Error 1215 while creating foreign key on varchar column [duplicate] - mysql

I am trying to forward engineer my new schema onto my database server, but I can't figure out why I am getting this error.
I've tried to search for the answer here, but everything I've found has said to either set the database engine to InnoDB or to make sure the keys I'm trying to use as a foreign key are primary keys in their own tables. I have done both of these things, if I'm not mistaken. What else can I do?
Executing SQL script in server
ERROR: Error 1215: Cannot add foreign key constraint
-- -----------------------------------------------------
-- Table `Alternative_Pathways`.`Clients_has_Staff`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `Alternative_Pathways`.`Clients_has_Staff` (
`Clients_Case_Number` INT NOT NULL ,
`Staff_Emp_ID` INT NOT NULL ,
PRIMARY KEY (`Clients_Case_Number`, `Staff_Emp_ID`) ,
INDEX `fk_Clients_has_Staff_Staff1_idx` (`Staff_Emp_ID` ASC) ,
INDEX `fk_Clients_has_Staff_Clients_idx` (`Clients_Case_Number` ASC) ,
CONSTRAINT `fk_Clients_has_Staff_Clients`
FOREIGN KEY (`Clients_Case_Number` )
REFERENCES `Alternative_Pathways`.`Clients` (`Case_Number` )
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_Clients_has_Staff_Staff1`
FOREIGN KEY (`Staff_Emp_ID` )
REFERENCES `Alternative_Pathways`.`Staff` (`Emp_ID` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB
SQL script execution finished: statements: 7 succeeded, 1 failed
Here is the SQL for the parent tables.
CREATE TABLE IF NOT EXISTS `Alternative_Pathways`.`Clients` (
`Case_Number` INT NOT NULL ,
`First_Name` CHAR(10) NULL ,
`Middle_Name` CHAR(10) NULL ,
`Last_Name` CHAR(10) NULL ,
`Address` CHAR(50) NULL ,
`Phone_Number` INT(10) NULL ,
PRIMARY KEY (`Case_Number`) )
ENGINE = InnoDB
CREATE TABLE IF NOT EXISTS `Alternative_Pathways`.`Staff` (
`Emp_ID` INT NOT NULL ,
`First_Name` CHAR(10) NULL ,
`Middle_Name` CHAR(10) NULL ,
`Last_Name` CHAR(10) NULL ,
PRIMARY KEY (`Emp_ID`) )
ENGINE = InnoDB

I'm guessing that Clients.Case_Number and/or Staff.Emp_ID are not exactly the same data type as Clients_has_Staff.Clients_Case_Number and Clients_has_Staff.Staff_Emp_ID.
Perhaps the columns in the parent tables are INT UNSIGNED?
They need to be exactly the same data type in both tables.

Reasons you may get a foreign key constraint error:
You are not using InnoDB as the engine on all tables.
You are trying to reference a nonexistent key on the target table. Make sure it is a key on the other table (it can be a primary or unique key, or just a key)
The types of the columns are not the same (an exception is the column on the referencing table can be nullable even if it is not nullable in the referenced table).
If the primary key or foreign key is a varchar, make sure the collation is the same for both.
One of the reasons may also be that the column you are using for ON DELETE SET NULL is not defined to be null. So make sure that the column is set default null.
Check these.

For others, the same error may not always be due to a column type mismatch. You can find out more information about a MySQL foreign key error by issuing the command
SHOW ENGINE INNODB STATUS;
You may find an error near the top of the printed message. Something like
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.

Error 1215 is an annoying one. Explosion Pill's answer covers the basics. You want to make sure to start from there. However, there are more, much more subtle cases to look out for:
For example, when you try to link up PRIMARY KEYs of different tables, make sure to provide proper ON UPDATE and ON DELETE options. E.g.:
...
PRIMARY KEY (`id`),
FOREIGN KEY (`id`) REFERENCES `t` (`other_id`) ON DELETE SET NULL
....
won't fly, because PRIMARY KEYs (such as id) can't be NULL.
I am sure, there are even more, similarly subtle issues when adding these sort of constraints, which is why when coming across constraint errors, always make sure that the constraints and their implications make sense in your current context. Good luck with your error 1215!

Check the collation of the table. Using SHOW TABLE STATUS, you can check information about the tables, including the collation.
Both tables have to have the same collation.
It's happened to me.

In my case, I had deleted a table using SET FOREIGN_KEY_CHECKS=0, then SET FOREIGN_KEY_CHECKS=1 after. When I went to reload the table, I got error 1215. The problem was there was another table in the database that had a foreign key to the table I had deleted and was reloading. Part of the reloading process involved changing a data type for one of the fields, which made the foreign key from the other table invalid, thus triggering error 1215. I resolved the problem by dropping and then reloading the other table with the new data type for the involved field.

There is a pitfall I have experienced with "Error 1215: Cannot add foreign key constraint" when using Laravel 4, especially with JeffreyWay's Laravel 4 Generators.
In Laravel 4, you can use JeffreyWay's Generators to generate migration files to create tables one-by-one, which means, each migration file generates one table.
You have to be aware of the fact that each migration file is generated with a timestamp in the filename, which gives the files an order. The order of generation is also the order of migration operation when you fire the Artisan CLI command php artisan migrate.
So, if a file asks for a foreign key constraint referring to a key which will be, but not yet, generated in a latter file, the Error 1215 is fired.
In such a case, you have to adjust the order of migration files generation. Generate new files in proper order, copy-in the content, and then delete the disordered old files.

For MySQL (InnoDB) ... get definitions for the columns you want to link:
SELECT * FROM information_schema.columns WHERE
TABLE_NAME IN (tb_name','referenced_table_name') AND
COLUMN_NAME IN ('col_name','referenced_col_name')\G
Compare and verify both column definitions have:
same COLUMN_TYPE(length), same COLATION
It could be necessary to disable/enable the foreign_key mechanism, but be aware if in a production context:
set foreign_key_checks=0;
ALTER TABLE tb_name ADD FOREIGN KEY(col_name) REFERENCES ref_table(ref_column) ON DELETE ...
set foreign_key_checks=1;

I got the same error while trying to add a foreign key. In my case, the problem was caused by the foreign key table's primary key which was marked as unsigned.

Check for table compatibility (engine) with SHOW TABLE STATUS WHERE Name = 'tableName'.
For example, if one table is MyISAM and the other one is InnoDB, you may have this issue.
You can change it thanks to this command:
ALTER TABLE myTable ENGINE = InnoDB;
From documentation.

In my case I had to disable FOREIGN KEY checks as the source tables did not exist.
SET FOREIGN_KEY_CHECKS=0;

I just wanted to add this case as well for VARCHAR foreign key relation. I spent the last week trying to figure this out in MySQL Workbench 8.0 and was finally able to fix the error.
Short Answer:
The character set and collation of the schema, the table, the column, the referencing table, the referencing column and any other tables that reference to the parent table have to match.
Long Answer:
I had an ENUM datatype in my table. I changed this to VARCHAR and I can get the values from a reference table so that I don't have to alter the parent table to add additional options. This foreign-key relationship seemed straightforward but I got 1215 error. arvind's answer and the following link suggested the use of
SHOW ENGINE INNODB STATUS;
On using this command I got the following verbose description for the error with no additional helpful information
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.
Please refer to http://dev.mysql.com/doc/refman/8.0/en/innodb-foreign-key-constraints.html for correct foreign key definition.
After which I used SET FOREIGN_KEY_CHECKS=0; as suggested by Arvind Bharadwaj and the link here:
This gave the following error message:
Error Code: 1822. Failed to add the foreign key constraint. Missing
index for constraint
At this point, I 'reverse engineer'-ed the schema and I was able to make the foreign-key relationship in the EER diagram. On 'forward engineer'-ing, I got the following error:
Error 1452: Cannot add or update a child row: a foreign key constraint
fails
When I 'forward engineer'-ed the EER diagram to a new schema, the SQL script ran without issues. On comparing the generated SQL from the attempts to forward engineer, I found that the difference was the character set and collation. The parent table, child table and the two columns had utf8mb4 character set and utf8mb4_0900_ai_ci collation, however, another column in the parent table was referenced using CHARACTER SET = utf8 , COLLATE = utf8_bin ; to a different child table.
For the entire schema, I changed the character set and collation for all the tables and all the columns to the following:
CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci;
This finally solved my problem with 1215 error.
Side Note:
The collation utf8mb4_general_ci works in MySQL Workbench 5.0 or later. Collation utf8mb4_0900_ai_ci works just for MySQL Workbench 8.0 or higher. I believe one of the reasons I had issues with character set and collation is due to MySQL Workbench upgrade to 8.0 in between. Here is a link that talks more about this collation.

I had the same problem.
I solved it doing this:
I created the following line in the
primary key: (id int(11) unsigned NOT NULL AUTO_INCREMENT)
I found out this solution after trying to import a table in my schema builder.

I had the same issue, and my solution is:
Before:
CREATE TABLE EMPRES
( NoFilm smallint NOT NULL
PRIMARY KEY (NoFilm)
FOREIGN KEY (NoFilm) REFERENCES cassettes
);
Solution:
CREATE TABLE EMPRES
(NoFilm smallint NOT NULL REFERENCES cassettes,
PRIMARY KEY (NoFilm)
);

This also happens when the type of the columns is not the same.
E.g., if the column you are referring to is an UNSIGNED INT and the column being referred to is INT then you get this error.

I can not find this error
CREATE TABLE RATING (
Riv_Id INT(5),
Mov_Id INT(10) DEFAULT 0,
Stars INT(5),
Rating_date DATE,
PRIMARY KEY (Riv_Id, Mov_Id),
FOREIGN KEY (Riv_Id) REFERENCES REVIEWER(Reviewer_ID)
ON DELETE SET NULL ON UPDATE CASCADE,
FOREIGN KEY (Mov_Id) REFERENCES MOVIE(Movie_ID)
ON DELETE SET DEFAULT ON UPDATE CASCADE
)

For me it was the column types. BigINT != INT.
But then it still didn't work.
So I checked the engines. Make sure Table1 = InnoDB and Table = InnoDB

Another reason: if you use ON DELETE SET NULL all columns that are used in the foreign key must allow null values. Someone else found this out in this question.
From my understanding it wouldn't be a problem regarding data integrity, but it seems that MySQL just doesn't support this feature (in 5.7).

So I tried all the fixes above and no luck. I may be missing the error in my tables -just could not find the cause and I kept getting error 1215. So I used this fix.
In my local environment in phpMyAdmin, I exported data from the table in question. I selected format CSV. While still in phpMyAdmin with the table selected, I selected "More->Options". Here I scrolled down to "Copy table to (database.table). Select "Structure only". Rename the table something, maybe just add the word "copy" next to the current table name. Click "Go" This will create a new table. Export the new table and import it to the new or other server. I am also using phpMyAdmin here also. Once imported change the name of the table back to its original name. Select the new table, select import. For format select CSV. Uncheck "enable foreign key checks". Select "Go". So far all is working good.
I posted my fix on my blog.

When trying to make a foreign key when using Laravel migration, like this example:
User table
public function up()
{
Schema::create('flights', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->TinyInteger('color_id')->unsigned();
$table->foreign('color_id')->references('id')->on('colors');
$table->timestamps();
});
}
Colors table
public function up()
{
Schema::create('flights', function (Blueprint $table) {
$table->increments('id');
$table->string('color');
$table->timestamps();
});
}
Sometimes properties didn't work:
[PDOException]
SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint
This error happened because the foreign key (type) in [user table] is different from the primary key (type) in the [colors table].
To solve this problem, you should change the primary key in the [colors table]:
$table->tinyIncrements('id');
When you use the primary key, $table->Increments('id');, you should use Integer as a foreign key:
$table->unsignedInteger('fk_id');
$table->foreign('fk_id')->references('id')->on('table_name');
When you use primary key $table->tinyIncrements('id'); you should use unsignedTinyInteger as a foreign key:
$table->unsignedTinyInteger('fk_id');
$table->foreign('fk_id')->references('id')->on('table_name');
When you use primary key $table->smallIncrements('id'); you should use unsignedSmallInteger as a foreign key:
$table->unsignedSmallInteger('fk_id');
$table->foreign('fk_id')->references('id')->on('table_name');
When you use primary key $table->mediumIncrements('id'); you should use unsignedMediumInteger as a foreign key:
$table->unsignedMediumInteger('fk_id');
$table->foreign('fk_id')->references('id')->on('table_name');

When this error occurs because the referenced table uses the MyISAM engine, this answer provides a quick way to convert your database so all Django model tables use InnoDB: Converting an existing MyISAM database to InnoDB with Django
It's a Django management command called convert_to_innodb.

Wooo, I just got it! It was a mix of a lot of already-posted answers (InnoDB, unsigned, etc.).
One thing I didn't see here though is: if your foreign key is pointing to a primary key, ensure the source column has a value that makes sense. For example, if the primary key is a mediumint(8), make sure the source column also contains a mediumint(8). That was part of the problem for me.

I experienced this error for a completely different reason. I used MySQL Workbench 6.3 for creating my data model (awesome tool). I noticed that when the column order defined in the foreign key constraint definition does not fit the table column sequence, this error is also generated.
It took me about four hours of trying everything else but checking that.
Now all is working well and I can get back to coding. :-)

This is a subtle version of what has already been said, but in my instance, I had 2 databases (foo and bar). I created foo first and I didn't realize it referenced a foreign key in bar.baz (which wasn't created yet). When I tried to create bar.baz (without any foreign keys), I kept getting this error. After looking around for a while I found the foreign key in foo.
So, long story short, If you get this error, you may have a pre-existing foreign key to the table being created.

As well as all of the previous advice for making sure that fields are identically defined, and table types also have the same collation, make sure that you don't make the rookie mistake of trying to link fields where data in the child field is not already in the parent field. If you have data that is in the child field that you have not already entered in to the parent field then that will cause this error. It's a shame that the error message is not a bit more helpful.
If you are unsure, then back up the table that has the foreign key, delete all the data and then try to create the foreign key. If successful then you know what to do!

Be aware of the use of backticks too. I had in a script the following statement
ALTER TABLE service ADD FOREIGN KEY (create_by) REFERENCES `system_user(id)`;
but the backticks at the end were false. It should have been:
ALTER TABLE service ADD FOREIGN KEY (create_by) REFERENCES `system_user`(`id`);
MySQL unfortunately does not give any details on this error...

Another source of this error is when you have two or more of the same table names which have the same foreign key names.
This sometimes happens to people who use modelling and design software, like MySQL Workbench, and later generate the script from the design.

For me, the 1215 error occurred when I was importing a dumpfile created by mysqldump, which creates the tables alphabetically, which in my case, caused foreign keys to reference tables created later in the file. (Props to this blog post for pointing it out: MySQL Error Code 1215: “Cannot add foreign key constraint”)
Since mysqldump orders tables alphabetically and I did not want to change the names of tables, I followed the instructions in the answer by JeremyWeir on this page, which states to put set FOREIGN_KEY_CHECKS = 0; at the top of the dump file and put SET FOREIGN_KEY_CHECKS = 1; at the bottom of the dump file.
That solution worked for me.

You may also check the Engine of both tables is set to InnoDB.

Related

SQL Cannot add foreign key restraint [duplicate]

I am trying to forward engineer my new schema onto my database server, but I can't figure out why I am getting this error.
I've tried to search for the answer here, but everything I've found has said to either set the database engine to InnoDB or to make sure the keys I'm trying to use as a foreign key are primary keys in their own tables. I have done both of these things, if I'm not mistaken. What else can I do?
Executing SQL script in server
ERROR: Error 1215: Cannot add foreign key constraint
-- -----------------------------------------------------
-- Table `Alternative_Pathways`.`Clients_has_Staff`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `Alternative_Pathways`.`Clients_has_Staff` (
`Clients_Case_Number` INT NOT NULL ,
`Staff_Emp_ID` INT NOT NULL ,
PRIMARY KEY (`Clients_Case_Number`, `Staff_Emp_ID`) ,
INDEX `fk_Clients_has_Staff_Staff1_idx` (`Staff_Emp_ID` ASC) ,
INDEX `fk_Clients_has_Staff_Clients_idx` (`Clients_Case_Number` ASC) ,
CONSTRAINT `fk_Clients_has_Staff_Clients`
FOREIGN KEY (`Clients_Case_Number` )
REFERENCES `Alternative_Pathways`.`Clients` (`Case_Number` )
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_Clients_has_Staff_Staff1`
FOREIGN KEY (`Staff_Emp_ID` )
REFERENCES `Alternative_Pathways`.`Staff` (`Emp_ID` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB
SQL script execution finished: statements: 7 succeeded, 1 failed
Here is the SQL for the parent tables.
CREATE TABLE IF NOT EXISTS `Alternative_Pathways`.`Clients` (
`Case_Number` INT NOT NULL ,
`First_Name` CHAR(10) NULL ,
`Middle_Name` CHAR(10) NULL ,
`Last_Name` CHAR(10) NULL ,
`Address` CHAR(50) NULL ,
`Phone_Number` INT(10) NULL ,
PRIMARY KEY (`Case_Number`) )
ENGINE = InnoDB
CREATE TABLE IF NOT EXISTS `Alternative_Pathways`.`Staff` (
`Emp_ID` INT NOT NULL ,
`First_Name` CHAR(10) NULL ,
`Middle_Name` CHAR(10) NULL ,
`Last_Name` CHAR(10) NULL ,
PRIMARY KEY (`Emp_ID`) )
ENGINE = InnoDB
I'm guessing that Clients.Case_Number and/or Staff.Emp_ID are not exactly the same data type as Clients_has_Staff.Clients_Case_Number and Clients_has_Staff.Staff_Emp_ID.
Perhaps the columns in the parent tables are INT UNSIGNED?
They need to be exactly the same data type in both tables.
Reasons you may get a foreign key constraint error:
You are not using InnoDB as the engine on all tables.
You are trying to reference a nonexistent key on the target table. Make sure it is a key on the other table (it can be a primary or unique key, or just a key)
The types of the columns are not the same (an exception is the column on the referencing table can be nullable even if it is not nullable in the referenced table).
If the primary key or foreign key is a varchar, make sure the collation is the same for both.
One of the reasons may also be that the column you are using for ON DELETE SET NULL is not defined to be null. So make sure that the column is set default null.
Check these.
For others, the same error may not always be due to a column type mismatch. You can find out more information about a MySQL foreign key error by issuing the command
SHOW ENGINE INNODB STATUS;
You may find an error near the top of the printed message. Something like
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.
Error 1215 is an annoying one. Explosion Pill's answer covers the basics. You want to make sure to start from there. However, there are more, much more subtle cases to look out for:
For example, when you try to link up PRIMARY KEYs of different tables, make sure to provide proper ON UPDATE and ON DELETE options. E.g.:
...
PRIMARY KEY (`id`),
FOREIGN KEY (`id`) REFERENCES `t` (`other_id`) ON DELETE SET NULL
....
won't fly, because PRIMARY KEYs (such as id) can't be NULL.
I am sure, there are even more, similarly subtle issues when adding these sort of constraints, which is why when coming across constraint errors, always make sure that the constraints and their implications make sense in your current context. Good luck with your error 1215!
Check the collation of the table. Using SHOW TABLE STATUS, you can check information about the tables, including the collation.
Both tables have to have the same collation.
It's happened to me.
In my case, I had deleted a table using SET FOREIGN_KEY_CHECKS=0, then SET FOREIGN_KEY_CHECKS=1 after. When I went to reload the table, I got error 1215. The problem was there was another table in the database that had a foreign key to the table I had deleted and was reloading. Part of the reloading process involved changing a data type for one of the fields, which made the foreign key from the other table invalid, thus triggering error 1215. I resolved the problem by dropping and then reloading the other table with the new data type for the involved field.
There is a pitfall I have experienced with "Error 1215: Cannot add foreign key constraint" when using Laravel 4, especially with JeffreyWay's Laravel 4 Generators.
In Laravel 4, you can use JeffreyWay's Generators to generate migration files to create tables one-by-one, which means, each migration file generates one table.
You have to be aware of the fact that each migration file is generated with a timestamp in the filename, which gives the files an order. The order of generation is also the order of migration operation when you fire the Artisan CLI command php artisan migrate.
So, if a file asks for a foreign key constraint referring to a key which will be, but not yet, generated in a latter file, the Error 1215 is fired.
In such a case, you have to adjust the order of migration files generation. Generate new files in proper order, copy-in the content, and then delete the disordered old files.
For MySQL (InnoDB) ... get definitions for the columns you want to link:
SELECT * FROM information_schema.columns WHERE
TABLE_NAME IN (tb_name','referenced_table_name') AND
COLUMN_NAME IN ('col_name','referenced_col_name')\G
Compare and verify both column definitions have:
same COLUMN_TYPE(length), same COLATION
It could be necessary to disable/enable the foreign_key mechanism, but be aware if in a production context:
set foreign_key_checks=0;
ALTER TABLE tb_name ADD FOREIGN KEY(col_name) REFERENCES ref_table(ref_column) ON DELETE ...
set foreign_key_checks=1;
I got the same error while trying to add a foreign key. In my case, the problem was caused by the foreign key table's primary key which was marked as unsigned.
Check for table compatibility (engine) with SHOW TABLE STATUS WHERE Name = 'tableName'.
For example, if one table is MyISAM and the other one is InnoDB, you may have this issue.
You can change it thanks to this command:
ALTER TABLE myTable ENGINE = InnoDB;
From documentation.
In my case I had to disable FOREIGN KEY checks as the source tables did not exist.
SET FOREIGN_KEY_CHECKS=0;
I just wanted to add this case as well for VARCHAR foreign key relation. I spent the last week trying to figure this out in MySQL Workbench 8.0 and was finally able to fix the error.
Short Answer:
The character set and collation of the schema, the table, the column, the referencing table, the referencing column and any other tables that reference to the parent table have to match.
Long Answer:
I had an ENUM datatype in my table. I changed this to VARCHAR and I can get the values from a reference table so that I don't have to alter the parent table to add additional options. This foreign-key relationship seemed straightforward but I got 1215 error. arvind's answer and the following link suggested the use of
SHOW ENGINE INNODB STATUS;
On using this command I got the following verbose description for the error with no additional helpful information
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.
Please refer to http://dev.mysql.com/doc/refman/8.0/en/innodb-foreign-key-constraints.html for correct foreign key definition.
After which I used SET FOREIGN_KEY_CHECKS=0; as suggested by Arvind Bharadwaj and the link here:
This gave the following error message:
Error Code: 1822. Failed to add the foreign key constraint. Missing
index for constraint
At this point, I 'reverse engineer'-ed the schema and I was able to make the foreign-key relationship in the EER diagram. On 'forward engineer'-ing, I got the following error:
Error 1452: Cannot add or update a child row: a foreign key constraint
fails
When I 'forward engineer'-ed the EER diagram to a new schema, the SQL script ran without issues. On comparing the generated SQL from the attempts to forward engineer, I found that the difference was the character set and collation. The parent table, child table and the two columns had utf8mb4 character set and utf8mb4_0900_ai_ci collation, however, another column in the parent table was referenced using CHARACTER SET = utf8 , COLLATE = utf8_bin ; to a different child table.
For the entire schema, I changed the character set and collation for all the tables and all the columns to the following:
CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci;
This finally solved my problem with 1215 error.
Side Note:
The collation utf8mb4_general_ci works in MySQL Workbench 5.0 or later. Collation utf8mb4_0900_ai_ci works just for MySQL Workbench 8.0 or higher. I believe one of the reasons I had issues with character set and collation is due to MySQL Workbench upgrade to 8.0 in between. Here is a link that talks more about this collation.
I had the same problem.
I solved it doing this:
I created the following line in the
primary key: (id int(11) unsigned NOT NULL AUTO_INCREMENT)
I found out this solution after trying to import a table in my schema builder.
I had the same issue, and my solution is:
Before:
CREATE TABLE EMPRES
( NoFilm smallint NOT NULL
PRIMARY KEY (NoFilm)
FOREIGN KEY (NoFilm) REFERENCES cassettes
);
Solution:
CREATE TABLE EMPRES
(NoFilm smallint NOT NULL REFERENCES cassettes,
PRIMARY KEY (NoFilm)
);
This also happens when the type of the columns is not the same.
E.g., if the column you are referring to is an UNSIGNED INT and the column being referred to is INT then you get this error.
I can not find this error
CREATE TABLE RATING (
Riv_Id INT(5),
Mov_Id INT(10) DEFAULT 0,
Stars INT(5),
Rating_date DATE,
PRIMARY KEY (Riv_Id, Mov_Id),
FOREIGN KEY (Riv_Id) REFERENCES REVIEWER(Reviewer_ID)
ON DELETE SET NULL ON UPDATE CASCADE,
FOREIGN KEY (Mov_Id) REFERENCES MOVIE(Movie_ID)
ON DELETE SET DEFAULT ON UPDATE CASCADE
)
For me it was the column types. BigINT != INT.
But then it still didn't work.
So I checked the engines. Make sure Table1 = InnoDB and Table = InnoDB
Another reason: if you use ON DELETE SET NULL all columns that are used in the foreign key must allow null values. Someone else found this out in this question.
From my understanding it wouldn't be a problem regarding data integrity, but it seems that MySQL just doesn't support this feature (in 5.7).
So I tried all the fixes above and no luck. I may be missing the error in my tables -just could not find the cause and I kept getting error 1215. So I used this fix.
In my local environment in phpMyAdmin, I exported data from the table in question. I selected format CSV. While still in phpMyAdmin with the table selected, I selected "More->Options". Here I scrolled down to "Copy table to (database.table). Select "Structure only". Rename the table something, maybe just add the word "copy" next to the current table name. Click "Go" This will create a new table. Export the new table and import it to the new or other server. I am also using phpMyAdmin here also. Once imported change the name of the table back to its original name. Select the new table, select import. For format select CSV. Uncheck "enable foreign key checks". Select "Go". So far all is working good.
I posted my fix on my blog.
When trying to make a foreign key when using Laravel migration, like this example:
User table
public function up()
{
Schema::create('flights', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->TinyInteger('color_id')->unsigned();
$table->foreign('color_id')->references('id')->on('colors');
$table->timestamps();
});
}
Colors table
public function up()
{
Schema::create('flights', function (Blueprint $table) {
$table->increments('id');
$table->string('color');
$table->timestamps();
});
}
Sometimes properties didn't work:
[PDOException]
SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint
This error happened because the foreign key (type) in [user table] is different from the primary key (type) in the [colors table].
To solve this problem, you should change the primary key in the [colors table]:
$table->tinyIncrements('id');
When you use the primary key, $table->Increments('id');, you should use Integer as a foreign key:
$table->unsignedInteger('fk_id');
$table->foreign('fk_id')->references('id')->on('table_name');
When you use primary key $table->tinyIncrements('id'); you should use unsignedTinyInteger as a foreign key:
$table->unsignedTinyInteger('fk_id');
$table->foreign('fk_id')->references('id')->on('table_name');
When you use primary key $table->smallIncrements('id'); you should use unsignedSmallInteger as a foreign key:
$table->unsignedSmallInteger('fk_id');
$table->foreign('fk_id')->references('id')->on('table_name');
When you use primary key $table->mediumIncrements('id'); you should use unsignedMediumInteger as a foreign key:
$table->unsignedMediumInteger('fk_id');
$table->foreign('fk_id')->references('id')->on('table_name');
When this error occurs because the referenced table uses the MyISAM engine, this answer provides a quick way to convert your database so all Django model tables use InnoDB: Converting an existing MyISAM database to InnoDB with Django
It's a Django management command called convert_to_innodb.
Wooo, I just got it! It was a mix of a lot of already-posted answers (InnoDB, unsigned, etc.).
One thing I didn't see here though is: if your foreign key is pointing to a primary key, ensure the source column has a value that makes sense. For example, if the primary key is a mediumint(8), make sure the source column also contains a mediumint(8). That was part of the problem for me.
I experienced this error for a completely different reason. I used MySQL Workbench 6.3 for creating my data model (awesome tool). I noticed that when the column order defined in the foreign key constraint definition does not fit the table column sequence, this error is also generated.
It took me about four hours of trying everything else but checking that.
Now all is working well and I can get back to coding. :-)
This is a subtle version of what has already been said, but in my instance, I had 2 databases (foo and bar). I created foo first and I didn't realize it referenced a foreign key in bar.baz (which wasn't created yet). When I tried to create bar.baz (without any foreign keys), I kept getting this error. After looking around for a while I found the foreign key in foo.
So, long story short, If you get this error, you may have a pre-existing foreign key to the table being created.
As well as all of the previous advice for making sure that fields are identically defined, and table types also have the same collation, make sure that you don't make the rookie mistake of trying to link fields where data in the child field is not already in the parent field. If you have data that is in the child field that you have not already entered in to the parent field then that will cause this error. It's a shame that the error message is not a bit more helpful.
If you are unsure, then back up the table that has the foreign key, delete all the data and then try to create the foreign key. If successful then you know what to do!
Be aware of the use of backticks too. I had in a script the following statement
ALTER TABLE service ADD FOREIGN KEY (create_by) REFERENCES `system_user(id)`;
but the backticks at the end were false. It should have been:
ALTER TABLE service ADD FOREIGN KEY (create_by) REFERENCES `system_user`(`id`);
MySQL unfortunately does not give any details on this error...
Another source of this error is when you have two or more of the same table names which have the same foreign key names.
This sometimes happens to people who use modelling and design software, like MySQL Workbench, and later generate the script from the design.
For me, the 1215 error occurred when I was importing a dumpfile created by mysqldump, which creates the tables alphabetically, which in my case, caused foreign keys to reference tables created later in the file. (Props to this blog post for pointing it out: MySQL Error Code 1215: “Cannot add foreign key constraint”)
Since mysqldump orders tables alphabetically and I did not want to change the names of tables, I followed the instructions in the answer by JeremyWeir on this page, which states to put set FOREIGN_KEY_CHECKS = 0; at the top of the dump file and put SET FOREIGN_KEY_CHECKS = 1; at the bottom of the dump file.
That solution worked for me.
You may also check the Engine of both tables is set to InnoDB.

Foreign Key error in MySql [duplicate]

I am trying to forward engineer my new schema onto my database server, but I can't figure out why I am getting this error.
I've tried to search for the answer here, but everything I've found has said to either set the database engine to InnoDB or to make sure the keys I'm trying to use as a foreign key are primary keys in their own tables. I have done both of these things, if I'm not mistaken. What else can I do?
Executing SQL script in server
ERROR: Error 1215: Cannot add foreign key constraint
-- -----------------------------------------------------
-- Table `Alternative_Pathways`.`Clients_has_Staff`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `Alternative_Pathways`.`Clients_has_Staff` (
`Clients_Case_Number` INT NOT NULL ,
`Staff_Emp_ID` INT NOT NULL ,
PRIMARY KEY (`Clients_Case_Number`, `Staff_Emp_ID`) ,
INDEX `fk_Clients_has_Staff_Staff1_idx` (`Staff_Emp_ID` ASC) ,
INDEX `fk_Clients_has_Staff_Clients_idx` (`Clients_Case_Number` ASC) ,
CONSTRAINT `fk_Clients_has_Staff_Clients`
FOREIGN KEY (`Clients_Case_Number` )
REFERENCES `Alternative_Pathways`.`Clients` (`Case_Number` )
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_Clients_has_Staff_Staff1`
FOREIGN KEY (`Staff_Emp_ID` )
REFERENCES `Alternative_Pathways`.`Staff` (`Emp_ID` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB
SQL script execution finished: statements: 7 succeeded, 1 failed
Here is the SQL for the parent tables.
CREATE TABLE IF NOT EXISTS `Alternative_Pathways`.`Clients` (
`Case_Number` INT NOT NULL ,
`First_Name` CHAR(10) NULL ,
`Middle_Name` CHAR(10) NULL ,
`Last_Name` CHAR(10) NULL ,
`Address` CHAR(50) NULL ,
`Phone_Number` INT(10) NULL ,
PRIMARY KEY (`Case_Number`) )
ENGINE = InnoDB
CREATE TABLE IF NOT EXISTS `Alternative_Pathways`.`Staff` (
`Emp_ID` INT NOT NULL ,
`First_Name` CHAR(10) NULL ,
`Middle_Name` CHAR(10) NULL ,
`Last_Name` CHAR(10) NULL ,
PRIMARY KEY (`Emp_ID`) )
ENGINE = InnoDB
I'm guessing that Clients.Case_Number and/or Staff.Emp_ID are not exactly the same data type as Clients_has_Staff.Clients_Case_Number and Clients_has_Staff.Staff_Emp_ID.
Perhaps the columns in the parent tables are INT UNSIGNED?
They need to be exactly the same data type in both tables.
Reasons you may get a foreign key constraint error:
You are not using InnoDB as the engine on all tables.
You are trying to reference a nonexistent key on the target table. Make sure it is a key on the other table (it can be a primary or unique key, or just a key)
The types of the columns are not the same (an exception is the column on the referencing table can be nullable even if it is not nullable in the referenced table).
If the primary key or foreign key is a varchar, make sure the collation is the same for both.
One of the reasons may also be that the column you are using for ON DELETE SET NULL is not defined to be null. So make sure that the column is set default null.
Check these.
For others, the same error may not always be due to a column type mismatch. You can find out more information about a MySQL foreign key error by issuing the command
SHOW ENGINE INNODB STATUS;
You may find an error near the top of the printed message. Something like
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.
Error 1215 is an annoying one. Explosion Pill's answer covers the basics. You want to make sure to start from there. However, there are more, much more subtle cases to look out for:
For example, when you try to link up PRIMARY KEYs of different tables, make sure to provide proper ON UPDATE and ON DELETE options. E.g.:
...
PRIMARY KEY (`id`),
FOREIGN KEY (`id`) REFERENCES `t` (`other_id`) ON DELETE SET NULL
....
won't fly, because PRIMARY KEYs (such as id) can't be NULL.
I am sure, there are even more, similarly subtle issues when adding these sort of constraints, which is why when coming across constraint errors, always make sure that the constraints and their implications make sense in your current context. Good luck with your error 1215!
Check the collation of the table. Using SHOW TABLE STATUS, you can check information about the tables, including the collation.
Both tables have to have the same collation.
It's happened to me.
In my case, I had deleted a table using SET FOREIGN_KEY_CHECKS=0, then SET FOREIGN_KEY_CHECKS=1 after. When I went to reload the table, I got error 1215. The problem was there was another table in the database that had a foreign key to the table I had deleted and was reloading. Part of the reloading process involved changing a data type for one of the fields, which made the foreign key from the other table invalid, thus triggering error 1215. I resolved the problem by dropping and then reloading the other table with the new data type for the involved field.
There is a pitfall I have experienced with "Error 1215: Cannot add foreign key constraint" when using Laravel 4, especially with JeffreyWay's Laravel 4 Generators.
In Laravel 4, you can use JeffreyWay's Generators to generate migration files to create tables one-by-one, which means, each migration file generates one table.
You have to be aware of the fact that each migration file is generated with a timestamp in the filename, which gives the files an order. The order of generation is also the order of migration operation when you fire the Artisan CLI command php artisan migrate.
So, if a file asks for a foreign key constraint referring to a key which will be, but not yet, generated in a latter file, the Error 1215 is fired.
In such a case, you have to adjust the order of migration files generation. Generate new files in proper order, copy-in the content, and then delete the disordered old files.
For MySQL (InnoDB) ... get definitions for the columns you want to link:
SELECT * FROM information_schema.columns WHERE
TABLE_NAME IN (tb_name','referenced_table_name') AND
COLUMN_NAME IN ('col_name','referenced_col_name')\G
Compare and verify both column definitions have:
same COLUMN_TYPE(length), same COLATION
It could be necessary to disable/enable the foreign_key mechanism, but be aware if in a production context:
set foreign_key_checks=0;
ALTER TABLE tb_name ADD FOREIGN KEY(col_name) REFERENCES ref_table(ref_column) ON DELETE ...
set foreign_key_checks=1;
I got the same error while trying to add a foreign key. In my case, the problem was caused by the foreign key table's primary key which was marked as unsigned.
Check for table compatibility (engine) with SHOW TABLE STATUS WHERE Name = 'tableName'.
For example, if one table is MyISAM and the other one is InnoDB, you may have this issue.
You can change it thanks to this command:
ALTER TABLE myTable ENGINE = InnoDB;
From documentation.
In my case I had to disable FOREIGN KEY checks as the source tables did not exist.
SET FOREIGN_KEY_CHECKS=0;
I just wanted to add this case as well for VARCHAR foreign key relation. I spent the last week trying to figure this out in MySQL Workbench 8.0 and was finally able to fix the error.
Short Answer:
The character set and collation of the schema, the table, the column, the referencing table, the referencing column and any other tables that reference to the parent table have to match.
Long Answer:
I had an ENUM datatype in my table. I changed this to VARCHAR and I can get the values from a reference table so that I don't have to alter the parent table to add additional options. This foreign-key relationship seemed straightforward but I got 1215 error. arvind's answer and the following link suggested the use of
SHOW ENGINE INNODB STATUS;
On using this command I got the following verbose description for the error with no additional helpful information
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.
Please refer to http://dev.mysql.com/doc/refman/8.0/en/innodb-foreign-key-constraints.html for correct foreign key definition.
After which I used SET FOREIGN_KEY_CHECKS=0; as suggested by Arvind Bharadwaj and the link here:
This gave the following error message:
Error Code: 1822. Failed to add the foreign key constraint. Missing
index for constraint
At this point, I 'reverse engineer'-ed the schema and I was able to make the foreign-key relationship in the EER diagram. On 'forward engineer'-ing, I got the following error:
Error 1452: Cannot add or update a child row: a foreign key constraint
fails
When I 'forward engineer'-ed the EER diagram to a new schema, the SQL script ran without issues. On comparing the generated SQL from the attempts to forward engineer, I found that the difference was the character set and collation. The parent table, child table and the two columns had utf8mb4 character set and utf8mb4_0900_ai_ci collation, however, another column in the parent table was referenced using CHARACTER SET = utf8 , COLLATE = utf8_bin ; to a different child table.
For the entire schema, I changed the character set and collation for all the tables and all the columns to the following:
CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci;
This finally solved my problem with 1215 error.
Side Note:
The collation utf8mb4_general_ci works in MySQL Workbench 5.0 or later. Collation utf8mb4_0900_ai_ci works just for MySQL Workbench 8.0 or higher. I believe one of the reasons I had issues with character set and collation is due to MySQL Workbench upgrade to 8.0 in between. Here is a link that talks more about this collation.
I had the same problem.
I solved it doing this:
I created the following line in the
primary key: (id int(11) unsigned NOT NULL AUTO_INCREMENT)
I found out this solution after trying to import a table in my schema builder.
I had the same issue, and my solution is:
Before:
CREATE TABLE EMPRES
( NoFilm smallint NOT NULL
PRIMARY KEY (NoFilm)
FOREIGN KEY (NoFilm) REFERENCES cassettes
);
Solution:
CREATE TABLE EMPRES
(NoFilm smallint NOT NULL REFERENCES cassettes,
PRIMARY KEY (NoFilm)
);
This also happens when the type of the columns is not the same.
E.g., if the column you are referring to is an UNSIGNED INT and the column being referred to is INT then you get this error.
I can not find this error
CREATE TABLE RATING (
Riv_Id INT(5),
Mov_Id INT(10) DEFAULT 0,
Stars INT(5),
Rating_date DATE,
PRIMARY KEY (Riv_Id, Mov_Id),
FOREIGN KEY (Riv_Id) REFERENCES REVIEWER(Reviewer_ID)
ON DELETE SET NULL ON UPDATE CASCADE,
FOREIGN KEY (Mov_Id) REFERENCES MOVIE(Movie_ID)
ON DELETE SET DEFAULT ON UPDATE CASCADE
)
For me it was the column types. BigINT != INT.
But then it still didn't work.
So I checked the engines. Make sure Table1 = InnoDB and Table = InnoDB
Another reason: if you use ON DELETE SET NULL all columns that are used in the foreign key must allow null values. Someone else found this out in this question.
From my understanding it wouldn't be a problem regarding data integrity, but it seems that MySQL just doesn't support this feature (in 5.7).
So I tried all the fixes above and no luck. I may be missing the error in my tables -just could not find the cause and I kept getting error 1215. So I used this fix.
In my local environment in phpMyAdmin, I exported data from the table in question. I selected format CSV. While still in phpMyAdmin with the table selected, I selected "More->Options". Here I scrolled down to "Copy table to (database.table). Select "Structure only". Rename the table something, maybe just add the word "copy" next to the current table name. Click "Go" This will create a new table. Export the new table and import it to the new or other server. I am also using phpMyAdmin here also. Once imported change the name of the table back to its original name. Select the new table, select import. For format select CSV. Uncheck "enable foreign key checks". Select "Go". So far all is working good.
I posted my fix on my blog.
When trying to make a foreign key when using Laravel migration, like this example:
User table
public function up()
{
Schema::create('flights', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->TinyInteger('color_id')->unsigned();
$table->foreign('color_id')->references('id')->on('colors');
$table->timestamps();
});
}
Colors table
public function up()
{
Schema::create('flights', function (Blueprint $table) {
$table->increments('id');
$table->string('color');
$table->timestamps();
});
}
Sometimes properties didn't work:
[PDOException]
SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint
This error happened because the foreign key (type) in [user table] is different from the primary key (type) in the [colors table].
To solve this problem, you should change the primary key in the [colors table]:
$table->tinyIncrements('id');
When you use the primary key, $table->Increments('id');, you should use Integer as a foreign key:
$table->unsignedInteger('fk_id');
$table->foreign('fk_id')->references('id')->on('table_name');
When you use primary key $table->tinyIncrements('id'); you should use unsignedTinyInteger as a foreign key:
$table->unsignedTinyInteger('fk_id');
$table->foreign('fk_id')->references('id')->on('table_name');
When you use primary key $table->smallIncrements('id'); you should use unsignedSmallInteger as a foreign key:
$table->unsignedSmallInteger('fk_id');
$table->foreign('fk_id')->references('id')->on('table_name');
When you use primary key $table->mediumIncrements('id'); you should use unsignedMediumInteger as a foreign key:
$table->unsignedMediumInteger('fk_id');
$table->foreign('fk_id')->references('id')->on('table_name');
When this error occurs because the referenced table uses the MyISAM engine, this answer provides a quick way to convert your database so all Django model tables use InnoDB: Converting an existing MyISAM database to InnoDB with Django
It's a Django management command called convert_to_innodb.
Wooo, I just got it! It was a mix of a lot of already-posted answers (InnoDB, unsigned, etc.).
One thing I didn't see here though is: if your foreign key is pointing to a primary key, ensure the source column has a value that makes sense. For example, if the primary key is a mediumint(8), make sure the source column also contains a mediumint(8). That was part of the problem for me.
I experienced this error for a completely different reason. I used MySQL Workbench 6.3 for creating my data model (awesome tool). I noticed that when the column order defined in the foreign key constraint definition does not fit the table column sequence, this error is also generated.
It took me about four hours of trying everything else but checking that.
Now all is working well and I can get back to coding. :-)
This is a subtle version of what has already been said, but in my instance, I had 2 databases (foo and bar). I created foo first and I didn't realize it referenced a foreign key in bar.baz (which wasn't created yet). When I tried to create bar.baz (without any foreign keys), I kept getting this error. After looking around for a while I found the foreign key in foo.
So, long story short, If you get this error, you may have a pre-existing foreign key to the table being created.
As well as all of the previous advice for making sure that fields are identically defined, and table types also have the same collation, make sure that you don't make the rookie mistake of trying to link fields where data in the child field is not already in the parent field. If you have data that is in the child field that you have not already entered in to the parent field then that will cause this error. It's a shame that the error message is not a bit more helpful.
If you are unsure, then back up the table that has the foreign key, delete all the data and then try to create the foreign key. If successful then you know what to do!
Be aware of the use of backticks too. I had in a script the following statement
ALTER TABLE service ADD FOREIGN KEY (create_by) REFERENCES `system_user(id)`;
but the backticks at the end were false. It should have been:
ALTER TABLE service ADD FOREIGN KEY (create_by) REFERENCES `system_user`(`id`);
MySQL unfortunately does not give any details on this error...
Another source of this error is when you have two or more of the same table names which have the same foreign key names.
This sometimes happens to people who use modelling and design software, like MySQL Workbench, and later generate the script from the design.
For me, the 1215 error occurred when I was importing a dumpfile created by mysqldump, which creates the tables alphabetically, which in my case, caused foreign keys to reference tables created later in the file. (Props to this blog post for pointing it out: MySQL Error Code 1215: “Cannot add foreign key constraint”)
Since mysqldump orders tables alphabetically and I did not want to change the names of tables, I followed the instructions in the answer by JeremyWeir on this page, which states to put set FOREIGN_KEY_CHECKS = 0; at the top of the dump file and put SET FOREIGN_KEY_CHECKS = 1; at the bottom of the dump file.
That solution worked for me.
You may also check the Engine of both tables is set to InnoDB.

MySQL Error 1215: Cannot add foreign key constraint

I am trying to forward engineer my new schema onto my database server, but I can't figure out why I am getting this error.
I've tried to search for the answer here, but everything I've found has said to either set the database engine to InnoDB or to make sure the keys I'm trying to use as a foreign key are primary keys in their own tables. I have done both of these things, if I'm not mistaken. What else can I do?
Executing SQL script in server
ERROR: Error 1215: Cannot add foreign key constraint
-- -----------------------------------------------------
-- Table `Alternative_Pathways`.`Clients_has_Staff`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `Alternative_Pathways`.`Clients_has_Staff` (
`Clients_Case_Number` INT NOT NULL ,
`Staff_Emp_ID` INT NOT NULL ,
PRIMARY KEY (`Clients_Case_Number`, `Staff_Emp_ID`) ,
INDEX `fk_Clients_has_Staff_Staff1_idx` (`Staff_Emp_ID` ASC) ,
INDEX `fk_Clients_has_Staff_Clients_idx` (`Clients_Case_Number` ASC) ,
CONSTRAINT `fk_Clients_has_Staff_Clients`
FOREIGN KEY (`Clients_Case_Number` )
REFERENCES `Alternative_Pathways`.`Clients` (`Case_Number` )
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_Clients_has_Staff_Staff1`
FOREIGN KEY (`Staff_Emp_ID` )
REFERENCES `Alternative_Pathways`.`Staff` (`Emp_ID` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB
SQL script execution finished: statements: 7 succeeded, 1 failed
Here is the SQL for the parent tables.
CREATE TABLE IF NOT EXISTS `Alternative_Pathways`.`Clients` (
`Case_Number` INT NOT NULL ,
`First_Name` CHAR(10) NULL ,
`Middle_Name` CHAR(10) NULL ,
`Last_Name` CHAR(10) NULL ,
`Address` CHAR(50) NULL ,
`Phone_Number` INT(10) NULL ,
PRIMARY KEY (`Case_Number`) )
ENGINE = InnoDB
CREATE TABLE IF NOT EXISTS `Alternative_Pathways`.`Staff` (
`Emp_ID` INT NOT NULL ,
`First_Name` CHAR(10) NULL ,
`Middle_Name` CHAR(10) NULL ,
`Last_Name` CHAR(10) NULL ,
PRIMARY KEY (`Emp_ID`) )
ENGINE = InnoDB
I'm guessing that Clients.Case_Number and/or Staff.Emp_ID are not exactly the same data type as Clients_has_Staff.Clients_Case_Number and Clients_has_Staff.Staff_Emp_ID.
Perhaps the columns in the parent tables are INT UNSIGNED?
They need to be exactly the same data type in both tables.
Reasons you may get a foreign key constraint error:
You are not using InnoDB as the engine on all tables.
You are trying to reference a nonexistent key on the target table. Make sure it is a key on the other table (it can be a primary or unique key, or just a key)
The types of the columns are not the same (an exception is the column on the referencing table can be nullable even if it is not nullable in the referenced table).
If the primary key or foreign key is a varchar, make sure the collation is the same for both.
One of the reasons may also be that the column you are using for ON DELETE SET NULL is not defined to be null. So make sure that the column is set default null.
Check these.
For others, the same error may not always be due to a column type mismatch. You can find out more information about a MySQL foreign key error by issuing the command
SHOW ENGINE INNODB STATUS;
You may find an error near the top of the printed message. Something like
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.
Error 1215 is an annoying one. Explosion Pill's answer covers the basics. You want to make sure to start from there. However, there are more, much more subtle cases to look out for:
For example, when you try to link up PRIMARY KEYs of different tables, make sure to provide proper ON UPDATE and ON DELETE options. E.g.:
...
PRIMARY KEY (`id`),
FOREIGN KEY (`id`) REFERENCES `t` (`other_id`) ON DELETE SET NULL
....
won't fly, because PRIMARY KEYs (such as id) can't be NULL.
I am sure, there are even more, similarly subtle issues when adding these sort of constraints, which is why when coming across constraint errors, always make sure that the constraints and their implications make sense in your current context. Good luck with your error 1215!
Check the collation of the table. Using SHOW TABLE STATUS, you can check information about the tables, including the collation.
Both tables have to have the same collation.
It's happened to me.
In my case, I had deleted a table using SET FOREIGN_KEY_CHECKS=0, then SET FOREIGN_KEY_CHECKS=1 after. When I went to reload the table, I got error 1215. The problem was there was another table in the database that had a foreign key to the table I had deleted and was reloading. Part of the reloading process involved changing a data type for one of the fields, which made the foreign key from the other table invalid, thus triggering error 1215. I resolved the problem by dropping and then reloading the other table with the new data type for the involved field.
There is a pitfall I have experienced with "Error 1215: Cannot add foreign key constraint" when using Laravel 4, especially with JeffreyWay's Laravel 4 Generators.
In Laravel 4, you can use JeffreyWay's Generators to generate migration files to create tables one-by-one, which means, each migration file generates one table.
You have to be aware of the fact that each migration file is generated with a timestamp in the filename, which gives the files an order. The order of generation is also the order of migration operation when you fire the Artisan CLI command php artisan migrate.
So, if a file asks for a foreign key constraint referring to a key which will be, but not yet, generated in a latter file, the Error 1215 is fired.
In such a case, you have to adjust the order of migration files generation. Generate new files in proper order, copy-in the content, and then delete the disordered old files.
For MySQL (InnoDB) ... get definitions for the columns you want to link:
SELECT * FROM information_schema.columns WHERE
TABLE_NAME IN (tb_name','referenced_table_name') AND
COLUMN_NAME IN ('col_name','referenced_col_name')\G
Compare and verify both column definitions have:
same COLUMN_TYPE(length), same COLATION
It could be necessary to disable/enable the foreign_key mechanism, but be aware if in a production context:
set foreign_key_checks=0;
ALTER TABLE tb_name ADD FOREIGN KEY(col_name) REFERENCES ref_table(ref_column) ON DELETE ...
set foreign_key_checks=1;
I got the same error while trying to add a foreign key. In my case, the problem was caused by the foreign key table's primary key which was marked as unsigned.
Check for table compatibility (engine) with SHOW TABLE STATUS WHERE Name = 'tableName'.
For example, if one table is MyISAM and the other one is InnoDB, you may have this issue.
You can change it thanks to this command:
ALTER TABLE myTable ENGINE = InnoDB;
From documentation.
In my case I had to disable FOREIGN KEY checks as the source tables did not exist.
SET FOREIGN_KEY_CHECKS=0;
I just wanted to add this case as well for VARCHAR foreign key relation. I spent the last week trying to figure this out in MySQL Workbench 8.0 and was finally able to fix the error.
Short Answer:
The character set and collation of the schema, the table, the column, the referencing table, the referencing column and any other tables that reference to the parent table have to match.
Long Answer:
I had an ENUM datatype in my table. I changed this to VARCHAR and I can get the values from a reference table so that I don't have to alter the parent table to add additional options. This foreign-key relationship seemed straightforward but I got 1215 error. arvind's answer and the following link suggested the use of
SHOW ENGINE INNODB STATUS;
On using this command I got the following verbose description for the error with no additional helpful information
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.
Please refer to http://dev.mysql.com/doc/refman/8.0/en/innodb-foreign-key-constraints.html for correct foreign key definition.
After which I used SET FOREIGN_KEY_CHECKS=0; as suggested by Arvind Bharadwaj and the link here:
This gave the following error message:
Error Code: 1822. Failed to add the foreign key constraint. Missing
index for constraint
At this point, I 'reverse engineer'-ed the schema and I was able to make the foreign-key relationship in the EER diagram. On 'forward engineer'-ing, I got the following error:
Error 1452: Cannot add or update a child row: a foreign key constraint
fails
When I 'forward engineer'-ed the EER diagram to a new schema, the SQL script ran without issues. On comparing the generated SQL from the attempts to forward engineer, I found that the difference was the character set and collation. The parent table, child table and the two columns had utf8mb4 character set and utf8mb4_0900_ai_ci collation, however, another column in the parent table was referenced using CHARACTER SET = utf8 , COLLATE = utf8_bin ; to a different child table.
For the entire schema, I changed the character set and collation for all the tables and all the columns to the following:
CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci;
This finally solved my problem with 1215 error.
Side Note:
The collation utf8mb4_general_ci works in MySQL Workbench 5.0 or later. Collation utf8mb4_0900_ai_ci works just for MySQL Workbench 8.0 or higher. I believe one of the reasons I had issues with character set and collation is due to MySQL Workbench upgrade to 8.0 in between. Here is a link that talks more about this collation.
I had the same problem.
I solved it doing this:
I created the following line in the
primary key: (id int(11) unsigned NOT NULL AUTO_INCREMENT)
I found out this solution after trying to import a table in my schema builder.
I had the same issue, and my solution is:
Before:
CREATE TABLE EMPRES
( NoFilm smallint NOT NULL
PRIMARY KEY (NoFilm)
FOREIGN KEY (NoFilm) REFERENCES cassettes
);
Solution:
CREATE TABLE EMPRES
(NoFilm smallint NOT NULL REFERENCES cassettes,
PRIMARY KEY (NoFilm)
);
This also happens when the type of the columns is not the same.
E.g., if the column you are referring to is an UNSIGNED INT and the column being referred to is INT then you get this error.
I can not find this error
CREATE TABLE RATING (
Riv_Id INT(5),
Mov_Id INT(10) DEFAULT 0,
Stars INT(5),
Rating_date DATE,
PRIMARY KEY (Riv_Id, Mov_Id),
FOREIGN KEY (Riv_Id) REFERENCES REVIEWER(Reviewer_ID)
ON DELETE SET NULL ON UPDATE CASCADE,
FOREIGN KEY (Mov_Id) REFERENCES MOVIE(Movie_ID)
ON DELETE SET DEFAULT ON UPDATE CASCADE
)
For me it was the column types. BigINT != INT.
But then it still didn't work.
So I checked the engines. Make sure Table1 = InnoDB and Table = InnoDB
Another reason: if you use ON DELETE SET NULL all columns that are used in the foreign key must allow null values. Someone else found this out in this question.
From my understanding it wouldn't be a problem regarding data integrity, but it seems that MySQL just doesn't support this feature (in 5.7).
So I tried all the fixes above and no luck. I may be missing the error in my tables -just could not find the cause and I kept getting error 1215. So I used this fix.
In my local environment in phpMyAdmin, I exported data from the table in question. I selected format CSV. While still in phpMyAdmin with the table selected, I selected "More->Options". Here I scrolled down to "Copy table to (database.table). Select "Structure only". Rename the table something, maybe just add the word "copy" next to the current table name. Click "Go" This will create a new table. Export the new table and import it to the new or other server. I am also using phpMyAdmin here also. Once imported change the name of the table back to its original name. Select the new table, select import. For format select CSV. Uncheck "enable foreign key checks". Select "Go". So far all is working good.
I posted my fix on my blog.
When trying to make a foreign key when using Laravel migration, like this example:
User table
public function up()
{
Schema::create('flights', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->TinyInteger('color_id')->unsigned();
$table->foreign('color_id')->references('id')->on('colors');
$table->timestamps();
});
}
Colors table
public function up()
{
Schema::create('flights', function (Blueprint $table) {
$table->increments('id');
$table->string('color');
$table->timestamps();
});
}
Sometimes properties didn't work:
[PDOException]
SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint
This error happened because the foreign key (type) in [user table] is different from the primary key (type) in the [colors table].
To solve this problem, you should change the primary key in the [colors table]:
$table->tinyIncrements('id');
When you use the primary key, $table->Increments('id');, you should use Integer as a foreign key:
$table->unsignedInteger('fk_id');
$table->foreign('fk_id')->references('id')->on('table_name');
When you use primary key $table->tinyIncrements('id'); you should use unsignedTinyInteger as a foreign key:
$table->unsignedTinyInteger('fk_id');
$table->foreign('fk_id')->references('id')->on('table_name');
When you use primary key $table->smallIncrements('id'); you should use unsignedSmallInteger as a foreign key:
$table->unsignedSmallInteger('fk_id');
$table->foreign('fk_id')->references('id')->on('table_name');
When you use primary key $table->mediumIncrements('id'); you should use unsignedMediumInteger as a foreign key:
$table->unsignedMediumInteger('fk_id');
$table->foreign('fk_id')->references('id')->on('table_name');
When this error occurs because the referenced table uses the MyISAM engine, this answer provides a quick way to convert your database so all Django model tables use InnoDB: Converting an existing MyISAM database to InnoDB with Django
It's a Django management command called convert_to_innodb.
Wooo, I just got it! It was a mix of a lot of already-posted answers (InnoDB, unsigned, etc.).
One thing I didn't see here though is: if your foreign key is pointing to a primary key, ensure the source column has a value that makes sense. For example, if the primary key is a mediumint(8), make sure the source column also contains a mediumint(8). That was part of the problem for me.
I experienced this error for a completely different reason. I used MySQL Workbench 6.3 for creating my data model (awesome tool). I noticed that when the column order defined in the foreign key constraint definition does not fit the table column sequence, this error is also generated.
It took me about four hours of trying everything else but checking that.
Now all is working well and I can get back to coding. :-)
This is a subtle version of what has already been said, but in my instance, I had 2 databases (foo and bar). I created foo first and I didn't realize it referenced a foreign key in bar.baz (which wasn't created yet). When I tried to create bar.baz (without any foreign keys), I kept getting this error. After looking around for a while I found the foreign key in foo.
So, long story short, If you get this error, you may have a pre-existing foreign key to the table being created.
As well as all of the previous advice for making sure that fields are identically defined, and table types also have the same collation, make sure that you don't make the rookie mistake of trying to link fields where data in the child field is not already in the parent field. If you have data that is in the child field that you have not already entered in to the parent field then that will cause this error. It's a shame that the error message is not a bit more helpful.
If you are unsure, then back up the table that has the foreign key, delete all the data and then try to create the foreign key. If successful then you know what to do!
Be aware of the use of backticks too. I had in a script the following statement
ALTER TABLE service ADD FOREIGN KEY (create_by) REFERENCES `system_user(id)`;
but the backticks at the end were false. It should have been:
ALTER TABLE service ADD FOREIGN KEY (create_by) REFERENCES `system_user`(`id`);
MySQL unfortunately does not give any details on this error...
Another source of this error is when you have two or more of the same table names which have the same foreign key names.
This sometimes happens to people who use modelling and design software, like MySQL Workbench, and later generate the script from the design.
For me, the 1215 error occurred when I was importing a dumpfile created by mysqldump, which creates the tables alphabetically, which in my case, caused foreign keys to reference tables created later in the file. (Props to this blog post for pointing it out: MySQL Error Code 1215: “Cannot add foreign key constraint”)
Since mysqldump orders tables alphabetically and I did not want to change the names of tables, I followed the instructions in the answer by JeremyWeir on this page, which states to put set FOREIGN_KEY_CHECKS = 0; at the top of the dump file and put SET FOREIGN_KEY_CHECKS = 1; at the bottom of the dump file.
That solution worked for me.
You may also check the Engine of both tables is set to InnoDB.

mysql Foreign key constraint is incorrectly formed error

I have two tables, table1 is the parent table with a column ID and table2 with a column IDFromTable1 (not the actual name) when I put a FK on IDFromTable1 to ID in table1 I get the error Foreign key constraint is incorrectly formed error. I would like to delete table 2 record if table1 record gets deleted. Thanks for any help
ALTER TABLE `table2`
ADD CONSTRAINT `FK1`
FOREIGN KEY (`IDFromTable1`) REFERENCES `table1` (`ID`)
ON UPDATE CASCADE
ON DELETE CASCADE;
Let me know if any other information is needed. I am new to mysql
I ran into this same problem with HeidiSQL. The error you receive is very cryptic. My problem ended up being that the foreign key column and the referencing column were not of the same type or length.
The foreign key column was SMALLINT(5) UNSIGNED and the referenced column was INT(10) UNSIGNED. Once I made them both the same exact type, the foreign key creation worked perfectly.
For anyone facing this problem, just run
SHOW ENGINE INNODB STATUS
and see the LATEST FOREIGN KEY ERROR section for details.
I had the same problem when the parent table was created using MyISAM engine. It's a silly mistake, which I fixed with:
ALTER TABLE parent_table ENGINE=InnoDB;
make sure columns are identical(of same type) and if reference column is not primary_key, make sure it is INDEXED.
Syntax for defining foreign keys is very forgiving, but for anyone else tripping up on this, the fact that foreign keys must be "of the same type" applies even to collation, not just data type and length and bit signing.
Not that you'd mix collation in your model (would you?) but if you do, be sure your primary and foreign key fields are of the same collation type in phpmyadmin or Heidi SQL or whatever you use.
Hope this saves you the four hours of trial and error it cost me.
I had same problem, but solved it.
Just make sure that column 'ID' in 'table1' has UNIQUE index!
And of course the type, length of columns 'ID' and 'IDFromTable1' in these two tables has to be same. But you already know about this.
mysql error texts doesn't help so much, in my case, the column had "not null" constraint, so the "on delete set null" was not allowed
Just for completion.
This error might be as well the case if you have a foreign key with VARCHAR(..) and the charset of the referenced table is different from the table referencing it.
e.g. VARCHAR(50) in a Latin1 Table is different than the VARCHAR(50) in a UTF8 Table.
One more probable cause for the display of this error. The order in which I was creating tables was wrong. I was trying to reference a key from a table that was not yet created.
I had the same issue, both columns were INT(11) NOT NULL but I wan't able to create the foreign key.
I had to disable foreign keys checks to run it successfully :
SET FOREIGN_KEY_CHECKS=OFF;
ALTER TABLE ... ADD CONSTRAINT ...
SET FOREIGN_KEY_CHECKS=ON;
Hope this helps someone.
if everything is ok, just add ->unsigned(); at the end of foregin key.
if it does not work, check the datatype of both fields. they must be the same.
(Last Resent) Even if the field name and data type is the same but the collation is not the same, it will also result to that problem.
For Example
TBL
NAME | DATA
TYPE |
COLLATION
ActivityID | INT |
latin1_general_ci
ActivityID | INT |
utf8_general_ci
Try Changing it into
TBL
NAME | DATA
TYPE |
COLLATION
ActivityID | INT |
latin1_general_ci
ActivityID | INT |
latin1_general_ci
....
This worked for me.
This problem also occur in Laravel when you have the foreign key table table1 migration after the migration in which you reference it table2.
You have to preserve the order of the migration in order to foreign key feature to work properly.
database/migrations/2020_01_01_00001_create_table2_table.php
database/migrations/2020_01_01_00002_create_table1_table.php
should be:
database/migrations/2020_01_01_00001_create_table1_table.php
database/migrations/2020_01_01_00002_create_table2_table.php
Check the tables engine, both tables have to be the same engine, that helped me so much.
Although the other answers are quite helpful, just wanted to share my experience as well.
I faced the issue when I had deleted a table whose id was already being referenced as foreign key in other tables (with data) and tried to recreate/import the table with some additional columns.
The query for recreation (generated in phpMyAdmin) looked like the following:
CREATE TABLE `the_table` (
`id` int(11) NOT NULL, /* No PRIMARY KEY index */
`name` varchar(255) NOT NULL,
`name_fa` varchar(255) NOT NULL,
`name_pa` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
... /* SOME DATA DUMP OPERATION */
ALTER TABLE `the_table`
ADD PRIMARY KEY (`id`), /* PRIMARY KEY INDEX */
ADD UNIQUE KEY `uk_acu_donor_name` (`name`);
As you may notice, the PRIMARY KEY index was set after the creation (and insertion of data) which was causing the problem.
Solution
The solution was to add the PRIMARY KEY index on table definition query for the id which was being referenced as foreign key, while also removing it from the ALTER TABLE part where indexes were being set:
CREATE TABLE `the_table` (
`id` int(11) NOT NULL PRIMARY KEY, /* <<== PRIMARY KEY INDEX ON CREATION */
`name` varchar(255) NOT NULL,
`name_fa` varchar(255) NOT NULL,
`name_pa` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Try running following:
show create table Parent
//and check if type for both tables are the same, like myISAM or innoDB, etc
//Other aspects to check with this error message: the columns used as foreign
keys must be indexed, they must be of the same type
(if i.e one is of type smallint(5) and the other of type smallint(6),
it won't work), and, if they are integers, they should be unsigned.
//or check for charsets
show variables like "character_set_database";
show variables like "collation_database";
//edited: try something like this
ALTER TABLE table2
ADD CONSTRAINT fk_IdTable2
FOREIGN KEY (Table1_Id)
REFERENCES Table1(Table1_Id)
ON UPDATE CASCADE
ON DELETE CASCADE;
I lost for hours for that!
PK in one table was utf8 in other was utf8_unicode_ci!
thanks S Doerin:
"Just for completion.
This error might be as well the case if you have a foreign key with VARCHAR(..) and the charset of the referenced table is different from the table referencing it.
e.g. VARCHAR(50) in a Latin1 Table is different than the VARCHAR(50) in a UTF8 Table."
i solved this problem, changing the type of characters of the table.
the creation have latin1 and the correct is utf8.
add the next line.
DEFAULT CHARACTER SET = utf8;
I had the same problems.
The issue is the reference column is not a primary key.
Make it a primary key and problem is solved.
My case was that I had a typo on the referred column:
MariaDB [blog]> alter table t_user add FOREIGN KEY ( country_code ) REFERENCES t_country ( coutry_code );
ERROR 1005 (HY000): Can't create table `blog`.`t_user` (errno: 150 "Foreign key constraint is incorrectly formed")
The error message is quite cryptic and I've tried everything - verifying the types of the columns, collations, engines, etc.
It took me awhile to note the typo and after fixing it all worked fine:
MariaDB [blog]> alter table t_user add FOREIGN KEY ( country_code ) REFERENCES t_country ( country_code );
Query OK, 2 rows affected (0.039 sec)
Records: 2 Duplicates: 0 Warnings: 0
I face this problem the error came when you put the primary key in different data type like:
table 1:
Schema::create('products', function (Blueprint $table) {
$table->increments('id');
$table->string('product_name');
});
table 2:
Schema::create('brands', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('brand_name');
});
the data type for id of the second table must be increments
For anyone struggling as I was with this issue, this was my problem:
I was trying to alter a table to change a field from VARCHAR(16) to VARCHAR(255) and this was referencing another table column where the datatype was still VARCHAR(16)...
I had the same issue with Symfony 2.8.
I didn't get it at first, because there were no similar problems with int length of foreign keys etc.
Finally I had to do the following in the project folder. (A server restart didn't help!)
app/console doctrine:cache:clear-metadata
app/console doctrine:cache:clear-query
app/console doctrine:cache:clear-result
I was using HeidiSQL and to solve this problem I had to create an index in the referenced table with all the columns being referenced.
I had issues using Alter table to add a foreign key between two tables and the thing that helped me was making sure each column that I was trying to add a foreign key relationship to was indexed. To do this in PHP myAdmin:
Go to the table and click on the structure tab.
Click the index option to index the desired column as shown in screenshot:
Once I indexed both columns I was trying to reference with my foreign keys, I was able to successfully use the alter table and create the foreign key relationship. You will see that the columns are indexed like in the below screenshot:
notice how zip_code shows up in both tables.
I ran into the same issue just now. In my case, all I had to do is to make sure that the table I am referencing in the foreign key must be created prior to the current table (earlier in the code). So if you are referencing a variable (x*5) the system should know what x is (x must be declared in earlier lines of code). This resolved my issue, hope it'll help someone else.
The problem is very simple to solve
e.g: you have two table with names users and posts and you want create foreign key in posts table and you use phpMyAdmin
1) in post table add new column
(name:use_id | type: like the id in user table | Length:like the id in user table | Default:NULL | Attributes:unsigned | index:INDEX )
2)on Structure tab go to relation view
(Constraint name: auto set by phpmyAdmin | column name:select user_id |table:users | key: id ,...)
It was simply solved
javad mosavi iran/urmia
I had the same error, and I discovered that on my own case, one table was MyISAM, and the other one INNO. Once I switched the MyISAM table to INNO. It solved the issue.
One more solution which I was missing here is, that each primary key of the referenced table should have an entry with a foreign key in the table where the constraint is created.
If U Table Is Myisum And New Table Is InoDb you Are Note Foreign
You Must Change MyIsum Table To InoDb

can't add foreign key in mysql?

I used MySQL workbench to add a foreign key in a table, but some strange error happened, this is the SQL statement:
ALTER TABLE `tansung`.`Declaration` ADD COLUMN `goodsId` INT(11) NOT NULL AFTER `declarationId` ,
ADD CONSTRAINT `goodsId`
FOREIGN KEY (`goodsId` )
REFERENCES `tansung`.`Goods` (`goodsId` )
ON DELETE NO ACTION
ON UPDATE NO ACTION
, ADD INDEX `goodsId` (`goodsId` ASC) ;
When i click apply, the surprise comes out!
ERROR 1005: Can't create table 'tansung.#sql-1b10_1' (errno: 150)
SQL Statement:
ALTER TABLE `tansung`.`Declaration` ADD COLUMN `goodsId` INT(11) NOT NULL AFTER `declarationId` ,
ADD CONSTRAINT `goodsId`
FOREIGN KEY (`goodsId` )
REFERENCES `tansung`.`Goods` (`goodsId` )
ON DELETE NO ACTION
ON UPDATE NO ACTION
, ADD INDEX `goodsId` (`goodsId` ASC)
ERROR: Error when running failback script. Details follow.
ERROR 1050: Table 'Declaration' already exists
SQL Statement:
CREATE TABLE `Declaration` (
`declarationId` int(11) NOT NULL,
PRIMARY KEY (`declarationId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
I can't find out any mistake in logic, even can't understand the error, please give me a help.
All foreign key names throughout the database must be unique. If you already have a foreign key named 'goodsId', even on another table, you will receive this error.
If the related columns do not have exactly the same type (e.g. INT) and constraints (UNIQUE and such), you will receive that error.
It can happen because of many reasons. Following are some of the common reasons. You can also say syntactical errors, because of which these kinds of error are thrown.
If the FK (Foreign Key) table Engine is using MyISAM and PK (Primary Key) table Engine is using InnoDB. MyISAM does not support foreign key constraints. So, you might want to converting your linking table to InnoDB.
All foreign key names throughout the database must be unique. If you already have a foreign key constraint with the same name, even on another table, you will receive this error.
If the related columns do not have exactly the same data typetype (e.g. INT) and constraints (UNIQUE and such), you will receive that error.
I'm getting this error when the table being linked to (in your case, Goods) is stored using MyISAM, and the table you're adding the index to (in your case, Declarations) is stored using InnoDB.
You can tell this from the files in the database directory. MyISAM tables will have files like:
table_name.frm
table_name.MYD
table_name.MYI
The InnoDB table will just have:
table_name.frm
MyISAM does not support foreign key constraints. I would suggest converting your Goods table to InnoDB (though, have a look at the documentation first and do some basic research):
ALTER TABLE Goods ENGINE=INNODB;
After making this change, my ADD INDEX operation completed successfully.
Like the others have said, first make sure the types of the two columns are the same and the database supports it. After that, make sure that the columns that hold the keys to the other tables are valid.
I had a problem where I was adding the constraint to an existing column with data in it, and that data didn't match any of the primary keys in the other table so the attempt to create the relationship would fail. Fixing it involved updating all the columns to make sure my column data matched up with the constraint I was trying to make.
I discovered that when trying to do this in phpMyAdmin that tables that had a hyphen in the name would only allow one FK and then give errors. I have no idea why but it was easy enough to work around I simply remade the
CREATE TABLE `something_new` LIKE `something-old`;
DROP TABLE `something-old`;
YMMV.
The type definitions of Goods.goodsId and Declarations.goodsId must be identical, or you will get the errno: 150.
Make sure they are both the same data type, which looks to be goodsId INT(11) NOT NULL in the Declarations table. What is the CREATE TABLE statement for Goods?
I had the same problem. It seems that there was some data in the child table that was not present in the parent table. You can do an outer join to see the differences and you can assign a valid id for non-matching rows or delete them:
DELETE FROM books
WHERE NOT EXISTS (
SELECT * FROM users
WHERE books.user_id = users.id
)
Errno 150 has a lot of causes. If you have SUPER privileges, you should try using
SHOW ENGINE INNODB STATUS
and that will tell you what the cause was. If you don't have SUPER privileges, you need to just go through all the possible causes. You can find how to use the SHOW INNODB STATUS and a list of all the causes here:
MySQL Foreign Key Errors and Errno 150
When I got that error it was becuase I was trying to update a table that already had data int it and the data didn't meet the FK restrictions.
A fourth possible problem (to the three proposed by abhijitcaps) is that you didn't make the column you are referencing to a primary key.