MySQL Foreign key not allowing insert - mysql

I am having an issue with a MySQL database I'm working on. I have a table DAY_ITEM with two nullable columns, FOOD_ID and MEAL_ID, that are foreign keys to the ID column in FOOD_ITEM and MEAL_ITEM tables respectively.
When I try to insert a new record into the FOOD_ITEM table I get this error:
[HY000][1364] Field 'FOOD_ID' doesn't have a default value
But that column isn't in the FOOD_ITEM table, the FOOD_ITEM table only has the ID column which is the foreign key of the FOOD_ID column in the DAY_ITEM table.
Below are my SQL scripts that make the tables, what I am doing wrong in these scripts?
DAY_ITEM Script
CREATE TABLE DAY_ITEM
(
ID BIGINT NOT NULL,
EMAIL VARCHAR(50) NOT NULL,
NAME VARCHAR(100) NULL DEFAULT NULL,
MOD_ID SMALLINT NOT NULL, #MOD = Meal Of Day
MOD_NAME VARCHAR(50) NULL DEFAULT NULL,
DAYS_DATE DATE NOT NULL,
FOOD_ID BIGINT NULL DEFAULT NULL,
MEAL_ID BIGINT NULL DEFAULT NULL
);
ALTER TABLE DAY_ITEM
ADD CONSTRAINT DAY_ITEM_PK_ID
PRIMARY KEY (ID);
ALTER TABLE DAY_ITEM
MODIFY COLUMN ID BIGINT NOT NULL AUTO_INCREMENT;
ALTER TABLE DAY_ITEM
ADD CONSTRAINT DAY_ITEM_FK_EMAIL
FOREIGN KEY (EMAIL) REFERENCES USER_ACCOUNT (EMAIL);
ALTER TABLE DAY_ITEM
ADD CONSTRAINT DAY_ITEM_FK_FOOD_ID
FOREIGN KEY (FOOD_ID) REFERENCES FOOD_ITEM (ID);
ALTER TABLE DAY_ITEM
ADD CONSTRAINT DAY_ITEM_FK_MEAL_ID
FOREIGN KEY (MEAL_ID) REFERENCES MEAL_ITEM (ID);
ALTER TABLE DAY_ITEM
ADD CONSTRAINT MEAL_ITEM_UK_EMAIL_DAYSDATE_FOODID
UNIQUE (EMAIL, DAYS_DATE, MOD_ID, FOOD_ID);
ALTER TABLE DAY_ITEM
ADD CONSTRAINT MEAL_ITEM_UK_EMAIL_DAYSDATE_MEALID
UNIQUE (EMAIL, DAYS_DATE, MOD_ID, MEAL_ID);
FOOD_ITEM Script
CREATE TABLE FOOD_ITEM
(
ID BIGINT NOT NULL,
EMAIL VARCHAR(50) NOT NULL,
NAME VARCHAR(100) NULL DEFAULT NULL,
SERVING_AMOUNT DECIMAL(6, 2) NULL DEFAULT NULL,
SERVING_SIZE VARCHAR(50) NULL DEFAULT NULL,
SERVING_ID SMALLINT NOT NULL,
CALORIES SMALLINT NULL DEFAULT NULL,
PROTEIN SMALLINT NULL DEFAULT NULL,
CARBS SMALLINT NULL DEFAULT NULL,
SUGAR SMALLINT NULL DEFAULT NULL,
FIBER SMALLINT NULL DEFAULT NULL,
FAT SMALLINT NULL DEFAULT NULL,
SAT_FAT SMALLINT NULL DEFAULT NULL,
MONO_FAT SMALLINT NULL DEFAULT NULL,
POLY_FAT SMALLINT NULL DEFAULT NULL,
TRANS_FAT SMALLINT NULL DEFAULT NULL,
SODIUM BIGINT NULL DEFAULT NULL,
CHOLESTEROL BIGINT NULL DEFAULT NULL
);
ALTER TABLE FOOD_ITEM
ADD CONSTRAINT FOOD_ITEM_PK_ID
PRIMARY KEY (ID);
ALTER TABLE FOOD_ITEM
MODIFY COLUMN ID BIGINT NOT NULL AUTO_INCREMENT;
ALTER TABLE FOOD_ITEM
ADD CONSTRAINT FOOD_ITEM_FK_EMAIL
FOREIGN KEY (EMAIL) REFERENCES USER_ACCOUNT (EMAIL);
ALTER TABLE FOOD_ITEM
ADD CONSTRAINT FOOD_ITEM_UK_EMAIL_NAME_SERVING
UNIQUE (EMAIL, NAME, SERVING_AMOUNT, SERVING_SIZE, SERVING_ID);
EDIT
Here is the insert statement I'm using that throws the error:
INSERT INTO FOOD_ITEM (EMAIL, NAME, SERVING_AMOUNT, SERVING_SIZE, SERVING_ID, CALORIES, PROTEIN, CARBS, FAT)
VALUES ('userOne#gravytrack.com', 'Caviar 2', 1.00, 'serving', 0, 250, 12, 13, 14);
I don't see why it's looking at the FOOD_ID in DAY_ITEM at all. I'm not inserting into DAY_ITEM I'm inserting into FOOD_ITEM. Even though I don't include an ID here it should just auto-increment. That's the way it worked in the past before I added the DAY_ITEM table.

Try with removing Default NULL value and pass NULL while insert record.
your script shows like...
CREATE TABLE DAY_ITEM
(
ID BIGINT NOT NULL,
EMAIL VARCHAR(50) NOT NULL,
NAME VARCHAR(100) NULL DEFAULT NULL,
MOD_ID SMALLINT NOT NULL, #MOD = Meal Of Day
MOD_NAME VARCHAR(50) NULL DEFAULT NULL,
DAYS_DATE DATE NOT NULL,
FOOD_ID BIGINT NULL,
MEAL_ID BIGINT NULL
);
ALTER TABLE DAY_ITEM
ADD CONSTRAINT DAY_ITEM_PK_ID
PRIMARY KEY (ID);
ALTER TABLE DAY_ITEM
MODIFY COLUMN ID BIGINT NOT NULL AUTO_INCREMENT;
ALTER TABLE DAY_ITEM
ADD CONSTRAINT DAY_ITEM_FK_EMAIL
FOREIGN KEY (EMAIL) REFERENCES USER_ACCOUNT (EMAIL);
ALTER TABLE DAY_ITEM
ADD CONSTRAINT DAY_ITEM_FK_FOOD_ID
FOREIGN KEY (FOOD_ID) REFERENCES FOOD_ITEM (ID);
ALTER TABLE DAY_ITEM
ADD CONSTRAINT DAY_ITEM_FK_MEAL_ID
FOREIGN KEY (MEAL_ID) REFERENCES MEAL_ITEM (ID);
ALTER TABLE DAY_ITEM
ADD CONSTRAINT MEAL_ITEM_UK_EMAIL_DAYSDATE_FOODID
UNIQUE (EMAIL, DAYS_DATE, MOD_ID, FOOD_ID);
ALTER TABLE DAY_ITEM
ADD CONSTRAINT MEAL_ITEM_UK_EMAIL_DAYSDATE_MEALID
UNIQUE (EMAIL, DAYS_DATE, MOD_ID, MEAL_ID);
No need to change in second table.

insert a row with value NULL in id column in your parent table, then you can insert NULL value in child table.
Better option is you should avoid NULL values...
Update:
As you can see in your insert statement that food_id and meal_id fields are not included in insert statement means you are inserting default NULL value in these fields while in your master tables you have set these fields as not null means you are trying to insert a value (NULL) which does not exist in parent table.

Related

MySql - Reorder/rearrenge primary key field with auto-increment

I have several table(s) in mysql as follows :
CREATE TABLE UserMst (
UserID mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
UserName varchar(20) NOT NULL,
CreatedOn timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (UserID)
) ENGINE=InnoDB;
CREATE TABLE UserDet (
ID mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
UserID mediumint(8) unsigned DEFAULT NULL,
PRIMARY KEY (ID),
KEY FK_UserDet_UserMst_UserID (UserID),
CONSTRAINT FK_UserDet_UserMst_UserID FOREIGN KEY (UserID) REFERENCES UserMst (UserID) ON DELETE NO ACTION ON UPDATE CASCADE,
) ENGINE=InnoDB;
"UserMst" table has "UserID" as a primary key with auto increment and forginekey relation with "UserDet" with update casecade.
UserMst table has about 200000+ records and UserDet has 20000000 records in it. So now I want to reorder "UserMst" table based on "CreatedOn" field. How Do I do this without dropping relation between both tables, any idea?
Thanks

Table with FK refer to a table with two PK

I have table1 with id and name columns both as PK, table2 would have a FK that refer to table1 column: name, when I make the FK in MySQL workbench, I get this error:
ERROR 1215: Cannot add foreign key constraint
table1: level, id enum(), name varchar(20) BOTH PK.
table2: class, id bigint PK AutoIncrement, level_name varchar(20), number int.
level_name is the FK to the PK name
Adding foreign key you need to care somethings like in your case in table1 that is level you have made PRIMARY KEY (id,name) and in second table you are referencing level_name to be the foreign key which is wrong you need to refer the pair of columns from your class table in order to create a foreign key add level_id of same type of id column from table1 level and then reference this pair FOREIGN KEY (level_id, level_name) to table level see below sample schema for your tables
CREATE TABLE `level` (
`id` enum('1','2','3','4','5') NOT NULL,
`name` varchar(20) NOT NULL,
PRIMARY KEY (`id`,`name`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `class` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`level_name` varchar(20) NOT NULL,
`level_id` enum('1','2','3','4','5') DEFAULT NULL,
`number` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `fk_key` (`level_id`,`level_name`),
CONSTRAINT `fk_key` FOREIGN KEY (`level_id`, `level_name`)
REFERENCES `level` (`id`, `name`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Demo

Creating MySQL relationships with foreign keys and alter statements

I will try to be specific because I feel my understanding of the subject isn't quite precise as well. My problem is understanding how to create relations between tables with foreign keys which I add with alter statements. I have these tables.
CREATE TABLE article (
content TEXT NOT NULL,
published_on DATE NOT NULL,
created_on DATE NOT NULL,
);
CREATE TABLE category(
name VARCHAR(30) NOT NULL,
date_created DATE NOT NULL,
);
CREATE TABLE user(
income FLOAT(30, 30) NOT NULL,
password VARCHAR(30) NOT NULL,
picture_url TEXT NOT NULL,
);
CREATE TABLE tag(
description VARCHAR(30) NOT NULL,
second_priority FLOAT(30, 30) NOT NULL,
);
To which I have to make there relationships:
Tag has a one to one connection to Category
Category has a many to one connection to User
User has a one to many connection to Article
And to do that I use there statements:
ALTER TABLE tag ADD CONSTRAINT FOREIGN KEY (tag_id) REFERENCES category (category_id);
ALTER TABLE category ADD CONSTRAINT FOREIGN KEY (user_id) REFERENCES user (user_id);
ALTER TABLE user ADD CONSTRAINT FOREIGN KEY (user_id) REFERENCES article (user_id);
My problem is that the third one fails. When I switch the places of article and user the constraint passes. After a bit of digging and experimenting I found out that I can't constraint two keys from which one is either UNIQUE or PRIMARY KEY and the other one just NOT NULL. So far I don't know how to continue, can someone please enlighten me as to how to create a one to one, many to one, one to many and a many to many relationship between these tables because I am kinda lost and everything in my head is a mess.
FULL STUFF:
CREATE DATABASE exam_database;
USE exam_database;
CREATE TABLE article (
content TEXT NOT NULL,
published_on DATE NOT NULL,
created_on DATE NOT NULL,
user_id INT(30) NOT NULL
);
CREATE TABLE category(
name VARCHAR(30) NOT NULL,
date_created DATE NOT NULL,
category_id INT(30) NOT NULL PRIMARY KEY AUTO_INCREMENT UNIQUE,
user_id INT(30) NOT NULL
);
CREATE TABLE user(
income FLOAT(30, 30) NOT NULL,
password VARCHAR(30) NOT NULL,
picture_url TEXT NOT NULL,
user_id INT(30) NOT NULL PRIMARY KEY AUTO_INCREMENT UNIQUE
);
CREATE TABLE tag(
description VARCHAR(30) NOT NULL,
second_priority FLOAT(30, 30) NOT NULL,
tag_id INT(30) NOT NULL PRIMARY KEY AUTO_INCREMENT UNIQUE
);
ALTER TABLE tag ADD CONSTRAINT FOREIGN KEY (tag_id) REFERENCES category (category_id);
ALTER TABLE category ADD CONSTRAINT FOREIGN KEY (user_id) REFERENCES user (user_id);
ALTER TABLE user ADD CONSTRAINT FOREIGN KEY (user_id) REFERENCES article (user_id);
First Your structure has some errors:
Missing PK, Why using INT(30)? etc...
Your DB should looks like:
CREATE DATABASE exam_database;
USE exam_database;
CREATE TABLE article (
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT UNIQUE,
user_id INT NOT NULL,
content TEXT NOT NULL,
published_on DATE NOT NULL,
created_on DATE NOT NULL
);
CREATE TABLE category(
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT UNIQUE,
user_id INT NOT NULL,
name VARCHAR(30) NOT NULL,
date_created DATE NOT NULL
);
CREATE TABLE user (
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT UNIQUE ,
income FLOAT(30, 30) NOT NULL,
password VARCHAR(30) NOT NULL,
picture_url TEXT NOT NULL
);
CREATE TABLE tag (
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT UNIQUE,
category_id INT NOT NULL,
description VARCHAR(30) NOT NULL,
second_priority FLOAT(30, 30) NOT NULL
);
Second Your FKs should look like:
ALTER TABLE tag ADD CONSTRAINT FOREIGN KEY (category_id) REFERENCES category (id);
ALTER TABLE category ADD CONSTRAINT FOREIGN KEY (user_id) REFERENCES user (id);
ALTER TABLE article ADD CONSTRAINT FOREIGN KEY (user_id) REFERENCES user (id);

Foreign Key not working: Error code 1005, SQL state HY000: Can't create table

I have two tables I have created and I'm adding the foreign key constraint after the fact.
The two tables are defined as such:
CREATE TABLE `user` (
`user_id` int(11) NOT NULL auto_increment,
`user_ad_id` varchar(500) default NULL,
`user_name` varchar(100) NOT NULL,
`login_id` varchar(100) default NULL,
`email` varchar(256) NOT NULL,
`personal_config` int(10) NOT NULL,
PRIMARY KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
and
CREATE TABLE IF NOT EXISTS personal_config (
config_id INT(10) NOT NULL AUTO_INCREMENT,
last_updated TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
configuration TEXT(25600) NOT NULL,
PRIMARY KEY (config_id)
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE personal_config ADD CONSTRAINT personal_config_fk_user FOREIGN KEY
(config_id) REFERENCES user(personal_config);
And I keep getting the same error but can't figure it out. I've searched all the related threads to this.
Your FK config_id can't be an autoincrement field, that doesn't make much sense right? That field reflects a value in the foreign table, it cannot be set arbitrarily in the local table.
I think this is what you want:
ALTER TABLE user ADD CONSTRAINT personal_config_fk_user FOREIGN KEY (personal_config) REFERENCES personal_config(config_id);
Your ALTER TABLE statement is backward. Since personal_config.config_id is an auto_increment primary key, the foreign key should be defined in the users table against personal_config, not in personal_config against the users table.
ALTER TABLE users ADD CONSTRAINT user_fk_personal_config
FOREIGN KEY (personal_config)
REFERENCES personal_config(config_id);
if you set your user table field personal_config is primary key then it is possible to execute
CREATE TABLE IF NOT EXISTS personal_config (
config_id INT(10) NOT NULL AUTO_INCREMENT,
last_updated TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
configuration TEXT(25600) NOT NULL,
PRIMARY KEY (config_id), FOREIGN KEY
(config_id) REFERENCES user(personal_config)
)ENGINE=InnoDB DEFAULT CHARSET=utf8;

MYSQL, When defining a table does the UNIQUE constraint have to be used in conjunction with an INTEGER or can it be any datatype?

I am wanting to have a label column (VARCHAR) and I want it to be unique, but when I try to create the table it seems to be throwing an error. Can a unique constraint only be used in conjunction with an INTEGER or will it work with other datatypes as well. The error I am getting is (ERRNO 150)
CREATE TABLE IF NOT EXISTS `user`(
user_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL,
`password` VARCHAR(255) NOT NULL
);
CREATE TABLE IF NOT EXISTS `element`(
element_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
label VARCHAR(5) NOT NULL DEFAULT '',
parent_id INT NULL,
user_id INT NOT NULL,
created_on TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
edited_on TIMESTAMP NOT NULL,
UNIQUE(label),
KEY element_1 (label),
CONSTRAINT FK_element_1 FOREIGN KEY (user_id) REFERENCES `user` (user_id),
CONSTRAINT FK_element_2 FOREIGN KEY (parent_id) REFERENCES `element` (element_id)
);
The only way I can have this error, if the first table is created with MyISAM engine and the second (tried to be created) with InnoDB.
Check the definition of the created table user, using:
SHOW CREATE TABLE user ;
If that's the case, drop it and recreate it with:
CREATE TABLE IF NOT EXISTS `user`(
user_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL,
`password` VARCHAR(255) NOT NULL
)
ENGINE = InnoDB ;