Table with FK refer to a table with two PK - mysql

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

Related

MySQL Foreign key not allowing insert

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.

SQL - CONSTRAINT to link two tables

I don't understand how to link two tables together. This is an example:
CREATE TABLE IF NOT EXISTS itemStatus (
id int(11) AUTO_INCREMENT PRIMARY KEY,
name varchar(64) NOT NULL UNIQUE KEY
);
CREATE TABLE IF NOT EXISTS itemData (
id int(11) AUTO_INCREMENT PRIMARY KEY,
title varchar(64) NOT NULL,
status_id int(11) DEFAULT NULL,
CONSTRAINT `fk_id` FOREIGN KEY (`id`) REFERENCES `itemStatus` (`id`),
);
I'm calling the row "status_id" but I don't reference this anywhere, so it can't link the two. For this example, should should my "CONSTRAINT" line read in order to be correct?
A FOREIGN KEY in one table points to a PRIMARY KEY in another table.
Take a look at:
http://www.w3schools.com/sql/sql_foreignkey.asp
So it should be:
CREATE TABLE IF NOT EXISTS itemStatus (
id int(11) AUTO_INCREMENT PRIMARY KEY,
name varchar(64) NOT NULL UNIQUE KEY
);
CREATE TABLE IF NOT EXISTS itemData (
id int(11) AUTO_INCREMENT PRIMARY KEY,
title varchar(64) NOT NULL,
status_id int(11) DEFAULT NULL,
CONSTRAINT `fk_id` FOREIGN KEY (`status_id`) REFERENCES `itemStatus` (`id`)
);
FOREIGN KEY (status_id) => Field in the table will REFERENCES itemStatus (id)
Constraint can't have "," when it's the last:
(...) REFERENCES itemStatus (id),
So the structure should be:
CONSTRAINT <<CONSTRAINT_NAME>> FOREIGN KEY (<<COLUMN_IN_THE_TABLE>>) REFERENCES `<<ANOTHER_TABLE>>` (`<<ANOTHER_TABLE_COLUMN_ID>>`)
Looks like you're very close. Try this instead:
CONSTRAINT `fk_id` FOREIGN KEY (`status_id`) REFERENCES `itemStatus` (`id`)
Your constraint is linking two primary keys (id of table 1 with id of table 2).
It should be something like this:
CREATE TABLE IF NOT EXISTS itemData (
id int(11) AUTO_INCREMENT PRIMARY KEY,
title varchar(64) NOT NULL,
status_id int(11) DEFAULT NULL,
CONSTRAINT `fk_id` FOREIGN KEY (`status_id`) REFERENCES `itemStatus` (`id`)
);

Trouble constraining one database table to another

I'm new to SQL and trying to learn how to reference on table to another. This is what I have:
CREATE TABLE IF NOT EXISTS itemData (
id int(11) AUTO_INCREMENT PRIMARY KEY,
title varchar(64) NOT NULL,
sector_id int(11) DEFAULT NULL,
status_id int(11) DEFAULT NULL,
locations_id int(11) DEFAULT NULL,
payments_id int(11) DEFAULT NULL,
type_id int(11) DEFAULT NULL,
CONSTRAINT `fk_sector_id` FOREIGN KEY (sector_id) REFERENCES `sector` (`sector_id`),
CONSTRAINT `fk_status_id` FOREIGN KEY (`status_id`) REFERENCES `status` (`status_id`),
CONSTRAINT `fk_locations_id` FOREIGN KEY (`locations_id`) REFERENCES `location` (`locations_id`),
CONSTRAINT `fk_payments_id` FOREIGN KEY (`payments_id`) REFERENCES `payments` (`payments_id`),
CONSTRAINT `fk_type_id` FOREIGN KEY (`type_id`) REFERENCES `type` (`type_id`)
);
Then I have my reference table for example:
CREATE TABLE IF NOT EXISTS itemStatus (
id int(11) AUTO_INCREMENT PRIMARY KEY,
name varchar(64) NOT NULL UNIQUE KEY
);
This doesn't seem to validate, can someone tell me where I have gone wrong please?
You probably need to change your table definition like this:
CREATE TABLE IF NOT EXISTS itemStatus (
status_id int(11) AUTO_INCREMENT PRIMARY KEY,
name varchar(64) NOT NULL UNIQUE KEY
);
as the constraint definition in your table is like this:
CONSTRAINT `fk_status_id` FOREIGN KEY (`status_id`) REFERENCES `itemstatus` (`status_id`),
You need to update the correct table in the constraint.
Also if you dont want to change the table definition then change the constraint like this:
CONSTRAINT `fk_id` FOREIGN KEY (`id`) REFERENCES `itemstatus` (`id`)
Here's your constraint:
CONSTRAINT `fk_status_id` FOREIGN KEY (`status_id`) REFERENCES `status` (`status_id`)
Here's the table definition:
CREATE TABLE IF NOT EXISTS itemStatus (
id int(11) AUTO_INCREMENT PRIMARY KEY,
name varchar(64) NOT NULL UNIQUE KEY
);
There's no column named status_id in that table.
Either rename the primary key column to status_id or change the constraint to point to id.

Errno:150 in MySQL Database

Have an error in my SQL code, but could not understand, where it is. Please, help me to solve that. Here is my code:
CREATE TABLE IF NOT EXISTS Records (
record_id int(11) NOT NULL AUTO_INCREMENT,
record_year year(4) NOT NULL,
record_quarter int(1) NOT NULL,
profit_tax int(11) NOT NULL,
PRIMARY KEY (record_id, record_year, record_quarter),
UNIQUE(record_year, record_quarter)
);
CREATE TABLE IF NOT EXISTS ProductsList (
product_id int(11) NOT NULL AUTO_INCREMENT,
product_name varchar(24) NOT NULL,
PRIMARY KEY (product_id)
);
An error is in that table:
CREATE TABLE IF NOT EXISTS RecordsProducts (
recordproduct_id int(11) NOT NULL AUTO_INCREMENT,
...
PRIMARY KEY (recordproduct_id),
FOREIGN KEY (record_id) REFERENCES Records (record_id),
FOREIGN KEY (product_id) REFERENCES ProductsList (record_id)
);
referencing column should be INDEX
referencing column should have same data type of referenced column
both referencing, referenced table should be InnoDB
CREATE TABLE IF NOT EXISTS RecordsProducts (
...
...
record_id int NOT NULL, <=== check data type
product_id int NOT NULL,
INDEX(record_id), <===== check INDEXed or not
INDEX(product_id), <====
FOREIGN KEY (record_id) REFERENCES Records (record_id),
FOREIGN KEY (product_id) REFERENCES ProductsList (record_id)
) ENGINE = InnoDB; <=== add 'ENGINE=InnoDB' explicitly

MySQL creating a table (errno 150)

I would like to ask something that troubles me many many days...
Here is what I mean:
I create these two tables:
CREATE TABLE IF NOT EXISTS journal (
issn varchar(20) NOT NULL,
j_title varchar(100) NOT NULL,
j_publisher varchar(30) NOT NULL,
PRIMARY KEY (issn)
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS volume (
volume_no int(11) NOT NULL,
issn varchar(20) NOT NULL,
year int(11) NOT NULL,
PRIMARY KEY (issn,volume_no),
FOREIGN KEY (issn) REFERENCES journal(issn)
) ENGINE=InnoDB;
When I try to create this:
CREATE TABLE IF NOT EXISTS issue (
issue_no int(11) NOT NULL,
issue_pages varchar(10) NOT NULL,
issue_date varchar(10) NOT NULL,
issn varchar(20) NOT NULL,
volume_no int(11) NOT NULL,
PRIMARY KEY (issue_no,issn,volume_no),
FOREIGN KEY (issn) REFERENCES journal(issn),
FOREIGN KEY (volume_no) REFERENCES volume(volume_no)
) ENGINE=InnoDB;
it throws an error (errno 150)
The error is in the foreign key volume_no.
Without FOREIGN KEY (volume_no) REFERENCES volume(volume_no)
the table is created without a problem.... I can't explain what's going on... I have seen it many times again and again but nothing!! Does anybody know what's going on?
Thanks in advance!!
I could see that the foreign key doesnt include issn but which is actually included in primary key for volumn table.
CREATE TABLE IF NOT EXISTS issue ( issue_no int(11) NOT NULL,
issue_pages varchar(10) NOT NULL,
issue_date varchar(10) NOT NULL,
issn varchar(20) NOT NULL,
volume_no int(11) NOT NULL,
PRIMARY KEY (issue_no,issn,volume_no),
FOREIGN KEY (issn,volume_no) REFERENCES volume(issn,volume_no) ) ENGINE=InnoDB;
Look at the below sql fiddle.
http://sqlfiddle.com/#!2/55a63
maybe volume_no needs to be UNSIGNED
FOREIGN keys must reference a PRIMARY or a UNIQUE key in the parent table.
You need only one Foreign Key at table issue, not two. And it should reference the Primary Key of volume:
CREATE TABLE IF NOT EXISTS issue (
issue_no int(11) NOT NULL,
issue_pages varchar(10) NOT NULL,
issue_date varchar(10) NOT NULL,
issn varchar(20) NOT NULL,
volume_no int(11) NOT NULL,
PRIMARY KEY (issn, volume_no, issue_no),
FOREIGN KEY (issn, volume_no)
REFERENCES volume(issn, volume_no)
) ENGINE=InnoDB;
If the PK of the parent table is more than one field, the order of the fields in the FK must be the same as the order in the PK.
issue: FOREIGN KEY (issn, volume_no) REFERENCES volume(issn, volume_no)
These conditions must be satisfied to not get error 150:
The two tables must be ENGINE=InnoDB.
The two tables must have the same charset.
The PK column(s) in the parent table and the FK column(s) must be the same data type.
The PK column(s) in the parent table and the FK column(s), if they have a define collation type, must have the same collation type;
If there is data already in the foreign key table, the FK column value(s) must match values in the parent table PK columns.
source: MySQL Creating tables with Foreign Keys giving errno: 150
I had about the same issue with my database. It wasn't about the definition of the foreign key, actually it was the definition of the primary key field.
CREATE TABLE tblProcesses (
fldProcessesID SMALLINT(5) UNIQUE NOT NULL AUTO_INCREMENT ,
CREATE TABLE tblProcessesMessage (
fldProcesses TEXT NOT NULL,
fldProcessesID VARCHAR(15) NOT NULL DEFAULT ,
The primary key in tblProcesses (fldProcessesID) did not have the UNSIGNED keyword while the foreign key in tblProcessesMessage (fldProcessesID) had the UNSIGNED keyword. This keyword was causing the problem - inconsistent type of field. So i added the UNSIGNED keyword to fldProcessesID in tblPreocesses:
CREATE TABLE tblProcesses (
fldProcessesID SMALLINT(5) UNSIGNED UNIQUE NOT NULL AUTO_INCREMENT,
I hope that this will help you solve your problems.
Best regards,
Nicholas