MySQL错误1215:不能添加外键约束

我试图转发我的新数据库到我的数据库服务器,但我不明白为什么我得到这个错误。 我试图在这里search答案,但是我发现的一切都说要将数据库引擎设置为Innodb或确保我试图用作外键的键是他们自己的表中的主键。 如果我没有弄错的话,我已经完成了这两件事情。 任何其他帮助你们可以提供?

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脚本执行完成:语句:7成功,1失败

这是父表的SQL。

 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 

我猜Clients.Case_Number和/或Staff.Emp_IDClients_has_Staff.Clients_Case_NumberClients_has_Staff.Staff_Emp_ID数据types不完全相同。

也许父表中的列是INT UNSIGNED

他们需要在两个表中完全相同的数据types。

您可能会收到外键约束错误的原因:

  1. 你并没有将InnoDB作为所有表的引擎。
  2. 您正试图在目标表上引用一个不存在的键。 确保它是另一张桌子上的钥匙 (可以是主钥匙或唯一钥匙)
  3. 列的types不相同(引用表上的列可以为空)。

更新:

  1. 其中一个原因可能是您正在使用ON DELETE SET NULL的列未定义为空。 所以请确保列设置为默认为空。

检查这些。

对于其他同样的错误可能并不总是由于列types不匹配,您可以通过发出命令find更多有关mysql foriegn密钥错误的信息

 SHOW ENGINE INNODB STATUS; 

您可能会在打印的信息的顶部附近发现一个错误

无法在引用表中find引用列作为第一列显示的索引,或者表中的列types和引用的表不匹配约束。

错误1215是一个恼人的。 爆炸药的答案涵盖了基本知识。 你想确保从那里开始。 但是,还有更多更微妙的情况需要注意:

例如,当您尝试链接不同表的PRIMARY KEY时,请确保提供适当的ON UPDATEON DELETE选项。 例如:

 ... PRIMARY KEY (`id`), FOREIGN KEY (`id`) REFERENCES `t` (`other_id`) ON DELETE SET NULL .... 

不会飞,因为PRIMARY KEY(如id )不能为NULL

我相信,在添加这些约束时,还有更多类似的细微问题,这就是为什么当遇到约束错误时,总是要确保约束及其影响在当前上下文中是有意义的。 祝你好运,你的错误1215!

在我的情况下,我已经使用SET FOREIGN_KEY_CHECKS=0删除了一个表,然后SET FOREIGN_KEY_CHECKS=1 。 当我去重新加载表,我得到error 1215 。 问题是在数据库中有另一个表有一个外键我已经删除,正在重新加载。 重新加载过程的一部分涉及改变其中一个字段的数据types,这使得另一个表中的外键无效,从而触发error 1215 。 我解决了这个问题,通过删除,然后重新加载其他表与所涉及的领域的新数据types。

尝试添加fk时遇到同样的错误。 在我的情况下,问题是由FK表的PK被标记为无符号引起的。

在使用Laravel 4时,特别是在JeffreyWay的Laravel 4 Generators中,遇到了一个“Error 1215:无法添加外键约束”的错误。

在Laravel 4中,您可以使用JeffreyWay的Generators生成迁移文件来逐个创build表,这意味着每个迁移文件都会生成一个表。 您必须意识到每个迁移文件都使用文件名中的时间戳生成,这会给文件一个命令。 生成顺序也是在您启动Artisan CLI命令“php artisan migrate”时迁移操作的顺序。 所以,如果一个文件要求一个外键约束引用一个将在后面的文件中生成但还没有生成的键,那么错误1215将被触发。 在这种情况下,您需要做的是调整迁移文件生成的顺序。 以适当的顺序生成新文件,复制内容,然后删除无序的旧文件。

我有同样的问题。 我主张这样做:

我在主键中创build了以下行:( id int(11)unsigned NOT NULL AUTO_INCREMENT)

我尝试在我的模式构build器中导入表后发现此解决scheme。 如果它适合你,让我知道!

祝你好运!

费利佩Tércio

我找不到这个错误

 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 ) 

我有同样的问题,我的解决scheme:

之前:

 CREATE TABLE EMPRES ( NoFilm smallint NOT NULL PRIMARY KEY (NoFilm) FOREIGN KEY (NoFilm) REFERENCES cassettes ); 

解:

 CREATE TABLE EMPRES (NoFilm smallint NOT NULL REFERENCES cassettes, PRIMARY KEY (NoFilm) ); 

我希望这是帮助;)

当列的types不一样时也会发生这种情况。

例如,如果您所指的列是UNSIGNED INT,而被引用的列是INT,则会出现此错误。

检查表格的兼容性。 例如,如果一个表是MyISAM ,另一个表是InnoDB ,则可能有这个问题。

当这个错误发生,因为被引用的表使用MyISAM引擎,这个答案提供了一个快速的方式来转换你的数据库,所以所有的Django模型表使用InnoDB: https : //stackoverflow.com/a/15389961/2950621

这是一个名为convert_to_innodb的Djangopipe理命令。

对我来说,这是列types。 BigINT!= INT。

但是,它仍然没有工作。

所以我检查了引擎。 确保Table1 = InnoDB和Table = InnoDB

对于MySQL(INNODB)…获取要链接的列的定义

 SELECT * FROM information_schema.columns WHERE TABLE_NAME IN (tb_name','referenced_table_name') AND COLUMN_NAME IN ('col_name','referenced_col_name')\G 

比较和validation两个列的定义都有

相同的COLUMN_TYPE(长度),相同的COLATION

可以帮助玩像

 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; 

另一个原因:如果使用ON DELETE SET NULL ,那么在外键中使用的所有列必须允许空值。 其他人在这个问题中发现了这一点 。

根据我的理解,在数据完整性方面不会有问题,但似乎MySQL并不支持这个特性(5.7版本)。

即使我有同样的问题。 这个错误是在FK表PK中的“无符号”标记

Wooo我刚刚得到它! 这是很多已经发布的答案(innoDB,unsigned等)的组合。 有一件事我没有看到,虽然是:如果你的FK指向一个PK,确保源列有一个合理的价值。 例如,如果PK是一个mediumint(8),请确保source列也包含一个mediumint(8)。 这是我的一部分问题。

请注意反引号的使用。 我在脚本中有以下声明

 ALTER TABLE service ADD FOREIGN KEY (create_by) REFERENCES `system_user(id)`; 

但最后的引文是错误的。 应该是:

 ALTER TABLE service ADD FOREIGN KEY (create_by) REFERENCES `system_user`(`id`); 

MySQL给这个错误的不幸的细节…

我出于完全不同的原因经历了这个错误。 我使用MySQL Workbench 6.3创build我的数据模型(真棒工具)。 我注意到,当外键约束定义中定义的列顺序不适合表列顺序时,也会生成此错误。

我花了大约4个小时的时间去尝试所有其他的东西,但是检查。

现在一切正常,我可以回到编码。 🙂

此错误的另一个来源是,您有两个或更多具有相同的外键名称相同的表名称。 这种情况有时会发生在使用build模和devise软件(如Mysql Workbench)的人身上,后来从devise中生成脚本。

当尝试使用laravel迁移时创build外键

像这个例子一样:

用户表

  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(); }); } 

颜色表

  public function up() { Schema::create('flights', function (Blueprint $table) { $table->increments('id'); $table->string('color'); $table->timestamps(); }); } 

有时属性不起作用

 [PDOException] SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint 

发生此错误的原因是[用户表]中的外键(types)与[颜色表]中的主键(types)不同

要解决这个问题,应该在[颜色表]中更改主键

$table->tinyIncrements('id');


当你使用主键$table->Increments('id');

你应该使用Integer作为外键

  $table-> unsignedInteger('fk_id'); $table->foreign('fk_id')->references('id')->on('table_name'); 

当你使用主键$table->tinyIncrements('id');

你应该使用unsignedTinyInteger作为外键

  $table-> unsignedTinyInteger('fk_id'); $table->foreign('fk_id')->references('id')->on('table_name'); 

当你使用主键$table->smallIncrements('id');

你应该使用unsignedSmallInteger作为外键

  $table-> unsignedSmallInteger('fk_id'); $table->foreign('fk_id')->references('id')->on('table_name'); 

当你使用主键$table->mediumIncrements('id');

你应该使用unsignedMediumInteger作为外键

  $table-> unsignedMediumInteger('fk_id'); $table->foreign('fk_id')->references('id')->on('table_name'); 

我知道我很晚,但我想把它放在这里,以便它被列出。

以及所有上述build议,以确保字段是相同的定义,并且表types也具有相同的sorting规则,请确保您不尝试链接字段中的数据在CHILD字段不是菜鸟的错误已经在PARENT字段中。 如果您有尚未进入PARENT字段的CHILD字段中的数据,则会导致此错误。 这是一个耻辱,错误信息是没有多大帮助。

如果您不确定,请备份带有外键的表,删除所有数据,然后尝试创build外键。 如果成功,那么你该怎么做!

祝你好运。

这是已经说过的微妙的版本,但在我的例子中,我有2个数据库(foo和bar)。 我首先创build了foo,但是我没有意识到它在bar.baz中引用了一个外键(它还没有创build)。 当我试图创buildbar.baz(没有任何外键),我不断收到这个错误。 经过四处寻找,我find了外键。

所以,长话短说,如果你得到这个错误,你可能有一个预先存在的外键被创build的表。

我有一次相同的错误。 我只是简单地重新启动MySQL服务器,并解决了这个问题。