I'm having some problems creating a foreign key to an existing table in a MySQL database.
I have the table exp:
+-------------+------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------+------------------+------+-----+---------+-------+
| EID | varchar(45) | NO | PRI | NULL | |
| Comment | text | YES | | NULL | |
| Initials | varchar(255) | NO | | NULL | |
| ExpDate | date | NO | | NULL | |
| InsertDate | date | NO | | NULL | |
| inserted_by | int(11) unsigned | YES | MUL | NULL | |
+-------------+------------------+------+-----+---------+-------+
and I wan't to create a new table called sample_df referencing this, using the following:
CREATE TABLE sample_df (
df_id mediumint(5) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
sample_type mediumint(5) UNSIGNED NOT NULL,
df_10 boolean NOT NULL,
df_100 boolean NOT NULL,
df_1000 boolean NOT NULL,
df_above_1000 boolean NOT NULL,
target int(11) UNSIGNED NOT NULL,
assay mediumint(5) UNSIGNED ZEROFILL NOT NULL,
insert_date timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
inserted_by int(11) UNSIGNED NOT NULL,
initials varchar(255),
experiment varchar(45),
CONSTRAINT FOREIGN KEY (inserted_by) REFERENCES user (iduser),
CONSTRAINT FOREIGN KEY (target) REFERENCES protein (PID),
CONSTRAINT FOREIGN KEY (sample_type) REFERENCES sample_type (ID),
CONSTRAINT FOREIGN KEY (assay) REFERENCES assays (AID),
CONSTRAINT FOREIGN KEY (experiment) REFERENCES exp (EID)
);
But I get the error:
ERROR 1215 (HY000): Cannot add foreign key constraint
To get some more information, I did:
SHOW ENGINE INNODB STATUS\G
From which I got:
FOREIGN KEY (experiment) REFERENCES exp (EID)
):
Cannot find an index in the referenced table where the
referenced columns appear as the first columns, or column types
in the table and the referenced table do not match for constraint.
To me, the column types seem to match, since they are both varchar(45). (I also tried setting the experiment column to not null, but this didn't fix it). So I guess the problem must be that
Cannot find an index in the referenced table where the referenced columns appear as the first columns.
But I'm not quite sure what this means, or how to check/fix it. Does anyone have any suggestions? And what is meant by first columns?
Just throwing this into the mix of possible causes, I ran into this when the referencing table column had the same "type" but did not have the same signing.
In my case, the referenced table colum was TINYINT UNSIGNED and my referencing table column was TINYINT SIGNED. Aligning both columns solved the issue.
This error can also occur, if the references table and the current table don't have the same character set.
According to http://dev.mysql.com/doc/refman/5.5/en/create-table-foreign-keys.html
MySQL requires indexes on foreign keys and referenced keys so that
foreign key checks can be fast and not require a table scan. In the
referencing table, there must be an index where the foreign key
columns are listed as the first columns in the same order.
InnoDB permits a foreign key to reference any index column or group of
columns. However, in the referenced table, there must be an index
where the referenced columns are listed as the first columns in the
same order.
So if the index in referenced table is exist and it is consists from several columns, and desired column is not first, the error shall be occurred.
The cause of our error was due to violation of following rule:
Corresponding columns in the foreign key and the referenced key must
have similar data types. The size and sign of integer types must be
the same. The length of string types need not be the same. For
nonbinary (character) string columns, the character set and collation
must be the same.
As mentioned #Anton, this could be because of the different data type.
In my case I had primary key BIGINT(20) and tried to set foreight key with INT(10)
Mine was a collation issue between the referenced table and the to be created table so I had to explicitly set the collation type of the key I was referencing.
First I ran a query at referenced table to get its collation type
show table STATUS like '<table_name_here>';
Then I copied the collation type and explicitly stated employee_id's collation type at the creation query. In my case it was utf8_general_ci
CREATE TABLE dbo.sample_db
(
id INT PRIMARY KEY AUTO_INCREMENT,
event_id INT SIGNED NOT NULL,
employee_id varchar(45) COLLATE utf8_general_ci NOT NULL,
event_date_time DATETIME,
CONSTRAINT sample_db_event_event_id_fk FOREIGN KEY (event_id) REFERENCES event (event_id),
CONSTRAINT sample_db_employee_employee_id_fk FOREIGN KEY (employee_id) REFERENCES employee (employee_id)
);
In my case, it turned out the referenced column wasn't declared primary or unique.
https://stackoverflow.com/a/18435114/1763217
For me it was just the charset and collation of the DB. I changed to utf8_unicode_ci and works
In my case, it was an incompatibility with ENGINE and COLLATE, once i added ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci it worked
CREATE TABLE `some_table` (
`id` varchar(36) NOT NULL,
`col_id` varchar(36) NOT NULL,
PRIMARY KEY (`id`),
CONSTRAINT `FK_some_table_cols_col_id` FOREIGN KEY (`col_id`) REFERENCES `ref_table` (`id`) ON DELETE CASCADE,
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
The exact order of the primary key also needs to match with no extra columns in between.
I had a primary key setup where the column order actually matches, but the problem was the primary key had an extra column in it that is not part of the foreign key of the referencing table
e.g.) table 2, column (a, b, c) -> table 1, column (a, b, d, c) -- THIS FAILS
I had to reorder the primary key columns so that not only they're ordered the same way, but have no extra columns in the middle:
e.g.) table 2, column (a, b, c) -> table 1, column (a, b, c, d) -- THIS SUCCEEDS
I had this error as well. None of the answers pertained to me. In my case, my GUI automatically creates a table with a primary unique identifier as "unassigned". This fails when I try and create a foreign key and gives me the exact same error. My primary key needs to be assigned.
If you write the SQL itself like so id int unique auto_increment then you don't have this issue but for some reason my GUI does this instead id int unassigned unique auto_increment.
Hope this helps someone else down the road.
In my case was created using integer for the id, and the referencing table was creating by default a foreign key using bigint.
This caused a big nightmare in my Rails app as the migration failed but the fields were actually created in DB, so they showed up in the DB but not in the schema of the Rails app.
Referencing the same column more than once in the same constraint also produces this Cannot find an index in the referenced table error, but can be difficult to spot on large tables. Split up the constraints and it will work as expected.
In some cases, I had to make the referenced field unique on top of defining it as the primary key.
But I found that not defining it as unique doesn't create a problem in every case. I have not been able to figure out the scenarios though. Probably something to do with nullable definition.
Just to throw another solution in the mix. I had on delete set to set null but the field that i was putting the foreign key on was NOT nullable so making it nullable allowed the foreign key to be created.
As others have said the following things can be an issue
Field Length - INT -> BIGINT, VARCHAR(20) -> VARCHAR(40)
Unsigned - UNSIGNED -> Signed
Mixed Collations
And just to add to this , I've had the same issue today
Both fields were int of same length etc, however, one was unsigned and this was enough to break it.
Both needed to be declared as unsigned
I had the same problem with writing this piece of code in the OnModelCreating method
My problem was completely solved and my tables and migrations were created without errors. Please try it
var cascadeFKs = modelBuilder.Model.GetEntityTypes()
.SelectMany(t => t.GetForeignKeys())
.Where(fk => !fk.IsOwnership && fk.DeleteBehavior == DeleteBehavior.Cascade);
foreach (var fk in cascadeFKs)
fk.DeleteBehavior = DeleteBehavior.Restrict;
It is mostly because the old table you are referring to does not have the suitable data type / collation / engine with the new table. The way to detect the difference is dumping that old table out and see how the database collect the information to have the dump script
mysqldump -uroot -p -h127.0.0.1 your_database your_old_table > dump_table.sql
It will give you enough information for you to compare
create table your_old_table
(
`id` varchar(32) not null,
) Engine = InnoDB DEFAULT CHARSET=utf8mb3;
This only works if you have the permission to dump your table scheme
I spent hours trying to get this to work. It turned out I had an older version of Heidi, 11.0.0.5919 which was not displaying the UNSIGNED attribute in the create table statement (Heidi bug), which I had used to copy from. Couldn't see it in the table design view either.
So the original table had an UNSIGNED attribute, but my foreign key didn't. The solution was upgrading Heidi, and adding the UNSIGNED attribute in the create table .
CREATE TABLE `extension` (
`ExtensionId` INT NOT NULL,
`AccountId` INT NOT NULL,
PRIMARY KEY (`ExtensionId`) USING BTREE,
INDEX `AccountId` (`AccountId`) USING BTREE,
CONSTRAINT `AccountId` FOREIGN KEY (`AccountId`) REFERENCES `accounts` (`AccountId`) ON UPDATE NO ACTION ON DELETE NO ACTION,
)
COLLATE='utf8mb4_0900_ai_ci'
ENGINE=InnoDB
;
Change to:
`AccountId` INT UNSIGNED NOT NULL,
If Data type is same, Probably error is due to different Charset and Collation, try altering column as referenced column's Character set and Collate with a query something like this,
ALTER TABLE table_name MODIFY COLUMN
column_name VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_general_ci;
and then run the query for foreign key..
(alter charset of a table and database didn't work for me on incompatible error, until I alter specific column like my above suggestion)
In my case I referred directly to a PRIMARY KEY and got the error shown above. After adding a "normal" index additionally to my primary key it worked:
ALTER TABLE `TableName` ADD INDEX `id` (`id`);
Now it looks like this:
When I try to drop the INDEX id again I get following error:
(1553): Cannot drop index 'id': needed in a foreign key constraint.
EDIT:
This is not a new question - I just want to show the way i solved this problem for me and what kind of problems may occur.
Related
I'm having some problems creating a foreign key to an existing table in a MySQL database.
I have the table exp:
+-------------+------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------+------------------+------+-----+---------+-------+
| EID | varchar(45) | NO | PRI | NULL | |
| Comment | text | YES | | NULL | |
| Initials | varchar(255) | NO | | NULL | |
| ExpDate | date | NO | | NULL | |
| InsertDate | date | NO | | NULL | |
| inserted_by | int(11) unsigned | YES | MUL | NULL | |
+-------------+------------------+------+-----+---------+-------+
and I wan't to create a new table called sample_df referencing this, using the following:
CREATE TABLE sample_df (
df_id mediumint(5) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
sample_type mediumint(5) UNSIGNED NOT NULL,
df_10 boolean NOT NULL,
df_100 boolean NOT NULL,
df_1000 boolean NOT NULL,
df_above_1000 boolean NOT NULL,
target int(11) UNSIGNED NOT NULL,
assay mediumint(5) UNSIGNED ZEROFILL NOT NULL,
insert_date timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
inserted_by int(11) UNSIGNED NOT NULL,
initials varchar(255),
experiment varchar(45),
CONSTRAINT FOREIGN KEY (inserted_by) REFERENCES user (iduser),
CONSTRAINT FOREIGN KEY (target) REFERENCES protein (PID),
CONSTRAINT FOREIGN KEY (sample_type) REFERENCES sample_type (ID),
CONSTRAINT FOREIGN KEY (assay) REFERENCES assays (AID),
CONSTRAINT FOREIGN KEY (experiment) REFERENCES exp (EID)
);
But I get the error:
ERROR 1215 (HY000): Cannot add foreign key constraint
To get some more information, I did:
SHOW ENGINE INNODB STATUS\G
From which I got:
FOREIGN KEY (experiment) REFERENCES exp (EID)
):
Cannot find an index in the referenced table where the
referenced columns appear as the first columns, or column types
in the table and the referenced table do not match for constraint.
To me, the column types seem to match, since they are both varchar(45). (I also tried setting the experiment column to not null, but this didn't fix it). So I guess the problem must be that
Cannot find an index in the referenced table where the referenced columns appear as the first columns.
But I'm not quite sure what this means, or how to check/fix it. Does anyone have any suggestions? And what is meant by first columns?
Just throwing this into the mix of possible causes, I ran into this when the referencing table column had the same "type" but did not have the same signing.
In my case, the referenced table colum was TINYINT UNSIGNED and my referencing table column was TINYINT SIGNED. Aligning both columns solved the issue.
This error can also occur, if the references table and the current table don't have the same character set.
According to http://dev.mysql.com/doc/refman/5.5/en/create-table-foreign-keys.html
MySQL requires indexes on foreign keys and referenced keys so that
foreign key checks can be fast and not require a table scan. In the
referencing table, there must be an index where the foreign key
columns are listed as the first columns in the same order.
InnoDB permits a foreign key to reference any index column or group of
columns. However, in the referenced table, there must be an index
where the referenced columns are listed as the first columns in the
same order.
So if the index in referenced table is exist and it is consists from several columns, and desired column is not first, the error shall be occurred.
The cause of our error was due to violation of following rule:
Corresponding columns in the foreign key and the referenced key must
have similar data types. The size and sign of integer types must be
the same. The length of string types need not be the same. For
nonbinary (character) string columns, the character set and collation
must be the same.
As mentioned #Anton, this could be because of the different data type.
In my case I had primary key BIGINT(20) and tried to set foreight key with INT(10)
Mine was a collation issue between the referenced table and the to be created table so I had to explicitly set the collation type of the key I was referencing.
First I ran a query at referenced table to get its collation type
show table STATUS like '<table_name_here>';
Then I copied the collation type and explicitly stated employee_id's collation type at the creation query. In my case it was utf8_general_ci
CREATE TABLE dbo.sample_db
(
id INT PRIMARY KEY AUTO_INCREMENT,
event_id INT SIGNED NOT NULL,
employee_id varchar(45) COLLATE utf8_general_ci NOT NULL,
event_date_time DATETIME,
CONSTRAINT sample_db_event_event_id_fk FOREIGN KEY (event_id) REFERENCES event (event_id),
CONSTRAINT sample_db_employee_employee_id_fk FOREIGN KEY (employee_id) REFERENCES employee (employee_id)
);
In my case, it turned out the referenced column wasn't declared primary or unique.
https://stackoverflow.com/a/18435114/1763217
For me it was just the charset and collation of the DB. I changed to utf8_unicode_ci and works
In my case, it was an incompatibility with ENGINE and COLLATE, once i added ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci it worked
CREATE TABLE `some_table` (
`id` varchar(36) NOT NULL,
`col_id` varchar(36) NOT NULL,
PRIMARY KEY (`id`),
CONSTRAINT `FK_some_table_cols_col_id` FOREIGN KEY (`col_id`) REFERENCES `ref_table` (`id`) ON DELETE CASCADE,
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
The exact order of the primary key also needs to match with no extra columns in between.
I had a primary key setup where the column order actually matches, but the problem was the primary key had an extra column in it that is not part of the foreign key of the referencing table
e.g.) table 2, column (a, b, c) -> table 1, column (a, b, d, c) -- THIS FAILS
I had to reorder the primary key columns so that not only they're ordered the same way, but have no extra columns in the middle:
e.g.) table 2, column (a, b, c) -> table 1, column (a, b, c, d) -- THIS SUCCEEDS
I had this error as well. None of the answers pertained to me. In my case, my GUI automatically creates a table with a primary unique identifier as "unassigned". This fails when I try and create a foreign key and gives me the exact same error. My primary key needs to be assigned.
If you write the SQL itself like so id int unique auto_increment then you don't have this issue but for some reason my GUI does this instead id int unassigned unique auto_increment.
Hope this helps someone else down the road.
In my case was created using integer for the id, and the referencing table was creating by default a foreign key using bigint.
This caused a big nightmare in my Rails app as the migration failed but the fields were actually created in DB, so they showed up in the DB but not in the schema of the Rails app.
Referencing the same column more than once in the same constraint also produces this Cannot find an index in the referenced table error, but can be difficult to spot on large tables. Split up the constraints and it will work as expected.
In some cases, I had to make the referenced field unique on top of defining it as the primary key.
But I found that not defining it as unique doesn't create a problem in every case. I have not been able to figure out the scenarios though. Probably something to do with nullable definition.
Just to throw another solution in the mix. I had on delete set to set null but the field that i was putting the foreign key on was NOT nullable so making it nullable allowed the foreign key to be created.
As others have said the following things can be an issue
Field Length - INT -> BIGINT, VARCHAR(20) -> VARCHAR(40)
Unsigned - UNSIGNED -> Signed
Mixed Collations
And just to add to this , I've had the same issue today
Both fields were int of same length etc, however, one was unsigned and this was enough to break it.
Both needed to be declared as unsigned
I had the same problem with writing this piece of code in the OnModelCreating method
My problem was completely solved and my tables and migrations were created without errors. Please try it
var cascadeFKs = modelBuilder.Model.GetEntityTypes()
.SelectMany(t => t.GetForeignKeys())
.Where(fk => !fk.IsOwnership && fk.DeleteBehavior == DeleteBehavior.Cascade);
foreach (var fk in cascadeFKs)
fk.DeleteBehavior = DeleteBehavior.Restrict;
It is mostly because the old table you are referring to does not have the suitable data type / collation / engine with the new table. The way to detect the difference is dumping that old table out and see how the database collect the information to have the dump script
mysqldump -uroot -p -h127.0.0.1 your_database your_old_table > dump_table.sql
It will give you enough information for you to compare
create table your_old_table
(
`id` varchar(32) not null,
) Engine = InnoDB DEFAULT CHARSET=utf8mb3;
This only works if you have the permission to dump your table scheme
I spent hours trying to get this to work. It turned out I had an older version of Heidi, 11.0.0.5919 which was not displaying the UNSIGNED attribute in the create table statement (Heidi bug), which I had used to copy from. Couldn't see it in the table design view either.
So the original table had an UNSIGNED attribute, but my foreign key didn't. The solution was upgrading Heidi, and adding the UNSIGNED attribute in the create table .
CREATE TABLE `extension` (
`ExtensionId` INT NOT NULL,
`AccountId` INT NOT NULL,
PRIMARY KEY (`ExtensionId`) USING BTREE,
INDEX `AccountId` (`AccountId`) USING BTREE,
CONSTRAINT `AccountId` FOREIGN KEY (`AccountId`) REFERENCES `accounts` (`AccountId`) ON UPDATE NO ACTION ON DELETE NO ACTION,
)
COLLATE='utf8mb4_0900_ai_ci'
ENGINE=InnoDB
;
Change to:
`AccountId` INT UNSIGNED NOT NULL,
If Data type is same, Probably error is due to different Charset and Collation, try altering column as referenced column's Character set and Collate with a query something like this,
ALTER TABLE table_name MODIFY COLUMN
column_name VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_general_ci;
and then run the query for foreign key..
(alter charset of a table and database didn't work for me on incompatible error, until I alter specific column like my above suggestion)
In my case I referred directly to a PRIMARY KEY and got the error shown above. After adding a "normal" index additionally to my primary key it worked:
ALTER TABLE `TableName` ADD INDEX `id` (`id`);
Now it looks like this:
When I try to drop the INDEX id again I get following error:
(1553): Cannot drop index 'id': needed in a foreign key constraint.
EDIT:
This is not a new question - I just want to show the way i solved this problem for me and what kind of problems may occur.
Been awhile since I've had to create/define a database, so ignore my lack of understanding. Basically, I have a table that has a few fields, one of which is a hash which references another table with the same hash, and the hash value. I believe the problem lies in the fact that I'm using the foreign key to references the non-primary key in the secondary table. So my question is this: how do I set up this relationship? Below is a minimum example to create my issue:
-- first table, imagine this as the hash value (should I remove the r_id,
-- and make the r_hash a unique & primary key?)
create table rx(
r_id int(10) auto_increment primary key,
r_hash varchar(175) default null,
r_val varchar(175) default null
);
create table cx(
c_id int(10) auto_increment primary key,
c_name varchar(175) default null,
querystr varchar(175) default null,
r_c_hash varchar(175) default null,
constraint r_fk foreign key(r_c_hash) references rx(r_hash)
);
And the classic error that I somehow still can't get around:
ERROR 1005 (HY000): Can't create table 'test2.cx' (errno: 150)
EDIT:
Just for clarification, an example row from rx will look like this:
1 | asdkjIOFJE93fijflskf | anexamplehashvalue
and an example row from cx may look like this:
1 | name_of_file | queryString=yes&1=3 | asdkjIOFJE93fijflskf
which as you can see, the hash values match which is all I need.. Do I recreate the rx table with the hash as the PK and make it unique? or can I keep the structure of the tables as it already is?
Why are you not referencing the primary key? That really is what primary keys are for.
If you really, really need to use a different key, then you should define a unique index on it:
create unique index unq_rx_r_hash on rx(r_hash);
I found some threads about the error. But all the solutions doesn't work for me.
I created 2 tables a user table and one for articles. Now I want to store the user that created the article and the one who is the last modifier.
CREATE TABLE IF NOT EXISTS `testDb`.`users` (
`id` INT NOT NULL AUTO_INCREMENT,
`nickname` VARCHAR(255) NULL,
`first_name` VARCHAR(255) NULL,
`last_name` VARCHAR(255) NULL,
`e_mail` VARCHAR(255) NOT NULL,
`activated` TINYINT(1) NOT NULL DEFAULT 0,
`birth_date` DATE NULL,
`locked` TINYINT(1) NOT NULL DEFAULT 0,
`locked_date_time` DATETIME NULL,
`street` VARCHAR(255) NULL,
`street_number` VARCHAR(255) NULL,
`city` VARCHAR(255) NULL,
`postal_code` VARCHAR(255) NULL,
`country` VARCHAR(255) NULL,
`phone` VARCHAR(255) NULL,
PRIMARY KEY (`id`),
UNIQUE INDEX `user_id_UNIQUE` (`id` ASC)
)
ENGINE = InnoDB
AUTO_INCREMENT = 1;
CREATE TABLE IF NOT EXISTS `testDb`.`articles` (
`id` INT NOT NULL AUTO_INCREMENT,
`name` VARCHAR(255) NULL,
`description` VARCHAR(255) NULL,
`create_user` INT ZEROFILL NOT NULL,
`create_date_time` DATETIME NULL,
`last_modifie_user` INT ZEROFILL NOT NULL,
`last_modifie_date_time` DATETIME NULL,
PRIMARY KEY (`id`),
UNIQUE INDEX `article_id_UNIQUE` (`id` ASC),
INDEX `fk_articles_users1_idx` (`create_user` ASC),
INDEX `fk_articles_users2_idx` (`last_modifie_user` ASC)
)
ENGINE = InnoDB
AUTO_INCREMENT = 1;
ALTER TABLE `testDb`.`articles`
ADD CONSTRAINT `fk_articles_users1`
FOREIGN KEY (`create_user`)
REFERENCES `testDb`.`users` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
ADD CONSTRAINT `fk_articles_users2`
FOREIGN KEY (`last_modifie_user`)
REFERENCES `testDb`.`users` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION;
I get the following error, but I didn't understand why I should have a index for that.
Error Code: 1822. Failed to add the foreign key constaint. Missing index for constraint 'fk_articles_users1' in the referenced table 'users'
I actived
SHOW ENGINE innodb STATUS;
but this doesn't shows any erros.
create_user INT UNSIGNED ZEROFILL cannot reference id INT, because these count as different data types for purposes of foreign key reference. Make them the same data type.
The only data type difference that is permitted between columns in a foreign key relationship is length of a varchar. For example, VARCHAR(10) can reference VARCHAR(20) or vice-versa.
Any other difference in data type, size, or character set is incompatible for referential integrity.
Even having ZEROFILL on one column but not the other makes the data types incompatible.
I came across this issue and my Data Type was correct so I was stumped for a little but then I just made everything the same.
When creating foreign keys be sure the columns you are using have the same:
Data Type
Collation
Zero Fill
Not Null
Unsigned
Binary
When you are referring one column of one table to another table using a foreign key
Make sure that the column you are referring to should either a primary key or it should be unique.
then use
ALTER TABLE table_name1
ADD CONSTRAINT constraint_name
FOREIGN KEY(column_name_in_table_name1)
REFERENCES table_name2(column_name_in_table_name2);
this will do for you.
You could use SHOW FULL COLUMNS FROM table_name which returns a column Collation, for example for a table accounts with a special collation on the column name
mysql> SHOW FULL COLUMNS FROM accounts;
+----------+--------------+-------------------+------+-----+---------+----------+
| Field | Type | Collation | Null | Key | Default | Extra |
+----------+--------------+-------------------+------+-----+---------+----------|
| id | int(11) | NULL | NO | PRI | NULL | auto_inc |
| name | varchar(255) | utf8_bin | YES | | NULL | |
| email | varchar(255) | latin1_swedish_ci | YES | | NULL | |
...
Both columns have to has the same collation.
To change the collation of column
ALTER TABLE t1 MODIFY
col1 VARCHAR(5)
CHARACTER SET latin1
COLLATE latin1_swedish_ci;
It's happened to me.
If anyone is coming to this stackoverflow question with MySQL error code 1822, and still getting the same error even after keeping the same data type in the parent and child table.
Then please make sure that the source table table1's column which is getting referred in table2 is indexed / declared as the primary key or unique.
There must be some subtle problem in the alter table statement. Changing the definition of articles fixes the problem:
CREATE TABLE IF NOT EXISTS `articles` (
`id` INT NOT NULL AUTO_INCREMENT,
`name` VARCHAR(255) NULL,
`description` VARCHAR(255) NULL,
`create_user` INT ZEROFILL NOT NULL REFERENCES users(id),
`create_date_time` DATETIME NULL,
`last_modifie_user` INT ZEROFILL NOT NULL REFERENCES users(id),
`last_modifie_date_time` DATETIME NULL,
PRIMARY KEY (`id`),
INDEX `fk_articles_users1_idx` (`create_user` ASC),
INDEX `fk_articles_users2_idx` (`last_modifie_user` ASC)
)
ENGINE = InnoDB
AUTO_INCREMENT = 1;
Here is the SQL Fiddle.
In my case, the error was that I didn't know that the name of the FKs have to be unique across the whole database. Renaming the FK fixed the issue.
I am also getting the same error while learning SQL. Later all the tried possible ways, I found that we must enable the primary key of referred table than it will enable the foreign key. Hope it will helpful.
-- Foreign key add and remove
SHOW DATABASES;
USE test;
DESCRIBE addresses;
DESCRIBE people;
ALTER TABLE people
ADD CONSTRAINT FK_PeopleAddress
FOREIGN KEY (address_id) REFERENCES addresses(id);
For me the issue was that my default collation was different in my database. Ensure that your default collation for your database matches the collation of the fields that your FK is trying to reference.
Ensure the parent table is not a child of another table.
For some reason, ->unsignedBigInteger() didn't work for me.
So I changed it slightly from this:
$table->unsignedBigInteger('owner_id');
To this:
$table->bigInteger('owner_id')->unsigned();
And now it works!
I received this error in mysql workbench during a forward engineer. After double checking the indexes and fk's were correct (Unique or PK vals), I was able to solve this by selecting "Skip creation of FOREIGN KEYS" and "Skip Creation of FK Indexes as well".
I was then getting a successful forward engineer with the options above selected. After a successful forward engineer, try running it a second time with those options deselected (default).
This did the trick for me.
For me, I don't have a primary key and I am applying foreign key constrained(), so make sure to check your primary exists.
Same issue! but solved. I was referring to the same table while creating a foreign key.
foreign key(id)references same_table(id),
That was the reason for the error.
I'm creating a few simple tables and I can't get passed this foreign key error and I'm not sure why. Here's the script below.
create TABLE Instructors (
ID varchar(10),
First_Name varchar(50) NOT NULL,
Last_Name varchar(50) NOT NULL,
PRIMARY KEY (ID)
);
create table Courses (
Course_Code varchar(10),
Title varchar(50) NOT NULL,
PRIMARY KEY (Course_Code)
);
create table Sections (
Index_No int,
Course_Code varchar(10),
Instructor_ID varchar(10),
PRIMARY KEY (Index_No),
FOREIGN KEY (Course_Code) REFERENCES Courses(Course_Code)
ON DELETE cascade
ON UPDATE cascade,
FOREIGN KEY (Instructor_ID) REFERENCES Instructors(ID)
ON DELETE set default
);
Error Code: 1005. Can't create table '336_project.sections' (errno: 150)
My data types seem identical and the syntax seems correct. Can anyone point out what I'm not seeing here?
I'm using MySQL Workbench 5.2
This error also occurs if you are relating columns of different types, eg. int in the source table and BigInt in the destination table.
If you're using the InnoDB engine, the ON DELETE SET DEFAULT is your problem. Here's an excerpt from the manual:
While SET DEFAULT is allowed by the MySQL Server, it is rejected as invalid by InnoDB. CREATE TABLE and ALTER TABLE statements using this clause are not allowed for InnoDB tables.
You can use ON DELETE CASCADE or ON DELETE SET NULL, but not ON DELETE SET DEFAULT. There's more information here.
You can run
SHOW ENGINE INNODB STATUS
to read the reason of the failure in a human readable format
e.g.
------------------------
LATEST FOREIGN KEY ERROR
------------------------
150331 15:51:01 Error in foreign key constraint of table foobar/#sql-413_81:
FOREIGN KEY (`user_id`) REFERENCES `foobar`.`users`(`id`) ON DELETE SET NULL ON UPDATE CASCADE:
You have defined a SET NULL condition though some of the columns are defined as NOT NULL.
In order to create a FOREIGN KEY with reference to another table, the keys from both tables should be PRIMARY KEY and with the same datatype.
In your table sections, PRIMARY KEY is of different datatype i.e INT but in another table, it's of type i.e VARCHAR.
It may also be the case if you are not specifying the ON DELETE at all but are trying to reference a MYISAM table from InnoDB table:
CREATE TABLE `table1`(
`id` INT UNSIGNED NOT NULL,
`name` VARCHAR(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MYISAM CHARACTER SET UTF8;
CREATE TABLE `table2`(
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`table1_id` INT UNSIGNED NOT NULL,
`some_value` VARCHAR(255) NOT NULL,
PRIMARY KEY (`id`),
KEY `fk_table1_id`(`table1_id`),
CONSTRAINT FOREIGN KEY (`table1_id`) REFERENCES `table1`(`id`)
) ENGINE=INNODB CHARACTER SET UTF8;
The above will throw errno 150. One need to change the first table to InnoDB too for this to work.
It is failing on the
ON DELETE set default
I have not come across that before and I am not seeing it in the manuals either ( but then it is late )
Update
just seen this in the manual
While SET DEFAULT is allowed by the MySQL Server, it is rejected as
invalid by InnoDB. CREATE TABLE and ALTER TABLE statements using this
clause are not allowed for InnoDB tables.
I guess you may be using InnoDB tables ?
For completeness sake - you will also get this error if you make a foreign reference to a table that isn't defined at the time;
Here Problem is in database engine ( table1 MYISAM and table2 ENGINE).
To set FOREIGN KEYs,
Both table must be in same ENGINE and same charset.
PK column in parent and FK column must be in same data type and same collation type.
Hope you got an idea.
Make sure that table type is InnoDB, MyISAM does not support foreign key, afaik.
I was working on creating some tables in database foo, but every time I end up with errno 150 regarding the foreign key. Firstly, here's my code for creating tables:
CREATE TABLE Clients
(
client_id CHAR(10) NOT NULL ,
client_name CHAR(50) NOT NULL ,
provisional_license_num CHAR(50) NOT NULL ,
client_address CHAR(50) NULL ,
client_city CHAR(50) NULL ,
client_county CHAR(50) NULL ,
client_zip CHAR(10) NULL ,
client_phone INT NULL ,
client_email CHAR(255) NULL ,
client_dob DATETIME NULL ,
test_attempts INT NULL
);
CREATE TABLE Applications
(
application_id CHAR(10) NOT NULL ,
office_id INT NOT NULL ,
client_id CHAR(10) NOT NULL ,
instructor_id CHAR(10) NOT NULL ,
car_id CHAR(10) NOT NULL ,
application_date DATETIME NULL
);
CREATE TABLE Instructors
(
instructor_id CHAR(10) NOT NULL ,
office_id INT NOT NULL ,
instructor_name CHAR(50) NOT NULL ,
instructor_address CHAR(50) NULL ,
instructor_city CHAR(50) NULL ,
instructor_county CHAR(50) NULL ,
instructor_zip CHAR(10) NULL ,
instructor_phone INT NULL ,
instructor_email CHAR(255) NULL ,
instructor_dob DATETIME NULL ,
lessons_given INT NULL
);
CREATE TABLE Cars
(
car_id CHAR(10) NOT NULL ,
office_id INT NOT NULL ,
engine_serial_num CHAR(10) NULL ,
registration_num CHAR(10) NULL ,
car_make CHAR(50) NULL ,
car_model CHAR(50) NULL
);
CREATE TABLE Offices
(
office_id INT NOT NULL ,
office_address CHAR(50) NULL ,
office_city CHAR(50) NULL ,
office_County CHAR(50) NULL ,
office_zip CHAR(10) NULL ,
office_phone INT NULL ,
office_email CHAR(255) NULL
);
CREATE TABLE Lessons
(
lesson_num INT NOT NULL ,
client_id CHAR(10) NOT NULL ,
date DATETIME NOT NULL ,
time DATETIME NOT NULL ,
milegage_used DECIMAL(5, 2) NULL ,
progress CHAR(50) NULL
);
CREATE TABLE DrivingTests
(
test_num INT NOT NULL ,
client_id CHAR(10) NOT NULL ,
test_date DATETIME NOT NULL ,
seat_num INT NOT NULL ,
score INT NULL ,
test_notes CHAR(255) NULL
);
ALTER TABLE Clients ADD PRIMARY KEY (client_id);
ALTER TABLE Applications ADD PRIMARY KEY (application_id);
ALTER TABLE Instructors ADD PRIMARY KEY (instructor_id);
ALTER TABLE Offices ADD PRIMARY KEY (office_id);
ALTER TABLE Lessons ADD PRIMARY KEY (lesson_num);
ALTER TABLE DrivingTests ADD PRIMARY KEY (test_num);
ALTER TABLE Applications ADD CONSTRAINT FK_Applications_Offices FOREIGN KEY (office_id) REFERENCES Offices (office_id);
ALTER TABLE Applications ADD CONSTRAINT FK_Applications_Clients FOREIGN KEY (client_id) REFERENCES Clients (client_id);
ALTER TABLE Applications ADD CONSTRAINT FK_Applications_Instructors FOREIGN KEY (instructor_id) REFERENCES Instructors (instructor_id);
ALTER TABLE Applications ADD CONSTRAINT FK_Applications_Cars FOREIGN KEY (car_id) REFERENCES Cars (car_id);
ALTER TABLE Lessons ADD CONSTRAINT FK_Lessons_Clients FOREIGN KEY (client_id) REFERENCES Clients (client_id);
ALTER TABLE Cars ADD CONSTRAINT FK_Cars_Offices FOREIGN KEY (office_id) REFERENCES Offices (office_id);
ALTER TABLE Clients ADD CONSTRAINT FK_DrivingTests_Clients FOREIGN KEY (client_id) REFERENCES Clients (client_id);
These are the errors that I get:
mysql> ALTER TABLE Applications ADD CONSTRAINT FK_Applications_Cars FOREIGN KEY
(car_id) REFERENCES Cars (car_id);
ERROR 1005 (HY000): Can't create table 'foo.#sql-12c_4' (errno: 150)
I ran SHOW ENGINE INNODB STATUS which gives a more detailed error description:
------------------------
LATEST FOREIGN KEY ERROR
------------------------
100509 20:59:49 Error in foreign key constraint of table foo/#sql-12c_4:
FOREIGN KEY (car_id) REFERENCES Cars (car_id):
Cannot find an index in the referenced table where the
referenced columns appear as the first columns, or column types
in the table and the referenced table do not match for constraint.
Note that the internal storage type of ENUM and SET changed in
tables created with >= InnoDB-4.1.12, and such columns in old tables
cannot be referenced by such columns in new tables.
See http://dev.mysql.com/doc/refman/5.1/en/innodb-foreign-key-constraints.html
for correct foreign key definition.
------------
I searched around on StackOverflow and elsewhere online - came across a helpful blog post here with pointers on how to resolve this error - but I can't figure out what's going wrong. Any help would be appreciated!
You should make car_id a primary key in cars.
Note: I had the same problem, and it was because the referenced field was in a different collation in the 2 different tables (they had exact same type).
Make sure all your referenced fields have the same type AND the same collation!
Check that BOTH tables have the same ENGINE. For example if you have:
CREATE Table FOO ();
and:
CREATE Table BAR () ENGINE=INNODB;
If you try to create a constraint from table BAR to table FOO, it will not work on certain MySQL versions.
Fix the issue by following:
CREATE Table FOO () ENGINE=INNODB;
Subtle, but this error got me because I forgot to declare a smallint column as unsigned to match the referenced, existing table which was "smallint unsigned." Having one unsigned and one not unsigned caused MySQL to prevent the foreign key from being created on the new table.
id smallint(3) not null
does not match, for the sake of foreign keys,
id smallint(3) unsigned not null
I got this completely worthless and uninformative error when I tried to:
ALTER TABLE `comments` ADD CONSTRAINT FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE SET NULL ON UPDATE CASCADE;
My problem was in my comments table, user_id was defined as:
`user_id` int(10) unsigned NOT NULL
So... in my case, the problem was with the conflict between NOT NULL, and ON DELETE SET NULL.
Also both the tables need to have same character set.
for e.g.
CREATE TABLE1 (
FIELD1 VARCHAR(100) NOT NULL PRIMARY KEY,
FIELD2 VARCHAR(100) NOT NULL
)ENGINE=INNODB CHARACTER SET utf8 COLLATE utf8_bin;
to
CREATE TABLE2 (
Field3 varchar(64) NOT NULL PRIMARY KEY,
Field4 varchar(64) NOT NULL,
CONSTRAINT FORIGEN KEY (Field3) REFERENCES TABLE1(FIELD1)
) ENGINE=InnoDB;
Will fail because they have different charsets. This is another subtle failure where mysql returns same error.
I use Ubuntu linux, and in my case the error was caused by incorrect statement syntax (which I found out by typing perror 150 at the terminal, which gives
MySQL error code 150: Foreign key constraint is incorrectly formed
Changing the syntax of the query from
alter table scale add constraint foreign key (year_id) references year.id;
to
alter table scale add constraint foreign key (year_id) references year(id);
fixed it.
The referenced field must be a "Key" in the referenced table, not necessarily a primary key. So the "car_id" should either be a primary key or be defined with NOT NULL and UNIQUE constraints in the "Cars" table.
And moreover, both fields must be of the same type and collation.
I also received this error (for several tables) along with constraint errors and MySQL connecting and disconnecting when attempting to import an entire database (~800 MB). My issue was the result of The MySQL server max allowed packets being too low. To resolve this (on a Mac):
Opened /private/etc/my.conf
Under # The MySQL server, changed max_allowed_packet from 1M to 4M (You may need to experiment with this value.)
Restarted MySQL
The database imported successfully after that.
Note I am running MySQL 5.5.12 for Mac OS X (x86 64 bit).
check to make the field you are referencing to is an exact match with foreign key, in my case one was unsigned and the other was signed so i just changed them to match and this worked
ALTER TABLE customer_information
ADD CONSTRAINT fk_customer_information1
FOREIGN KEY (user_id)
REFERENCES users(id)
ON DELETE CASCADE
ON UPDATE CASCADE
Solved:
Check to make sure Primary_Key and Foreign_Key are exact match with data types.
If one is signed another one unsigned, it will be failed.
Good practice is to make sure both are unsigned int.
I was using a duplicate Foreign Key Name.
Renaming the FK name solved my problem.
Clarification:
Both tables had a constraint called PK1, FK1, etc. Renaming them/making the names unique solved the problem.
The referenced column must be an index of a single column or the first column in multi column index, and the same type and the same collation.
My two tables have the different collations. It can be shown by issuing show table status like table_name and collation can be changed by issuing alter table table_name convert to character set utf8.
all, I solved a problem and wanted to share it:
I had this error <>
The issue was in that in my statement:
alter table system_registro_de_modificacion add foreign key
(usuariomodificador_id) REFERENCES Usuario(id) On delete restrict;
I had incorrectly written the CASING: it works in Windows WAMP, but in Linux MySQL it is more strict with the CASING, so writting "Usuario" instead of "usuario" (exact casing), generated the error, and was corrected simply changing the casing.