Py学习  »  DATABASE

mysql-错误1215:无法添加外键约束[重复]

zeldafan • 5 年前 • 3165 次点击  

我正试图将我的新模式转发到我的数据库服务器上,但我不明白为什么会出现这个错误。我试图在这里搜索答案,但我所找到的一切都表明,要么将db引擎设置为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
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/39827
 
3165 次点击  
文章 [ 30 ]  |  最新文章 5 年前
b5bus
Reply   •   1 楼
b5bus    10 年前

我也犯过同样的错误。我只是重新启动了mysql服务器并解决了这个问题。

blueFroggy
Reply   •   2 楼
blueFroggy    11 年前

就连我也有同样的问题。错误是FK表pk中的“unsigned”标记

marcello miorelli RADU
Reply   •   3 楼
marcello miorelli RADU    6 年前

添加另一个原因到 @Explosion Pills answer above :

7-使用多列键时,外键创建的顺序 必须与表列顺序中的另一个匹配。

Arya
Reply   •   4 楼
Arya    6 年前

对我来说,在导入由 mysqldump ,这将按字母顺序创建表,在我的示例中,这将导致外键引用稍后在文件中创建的表。(提示此页的道具: https://www.percona.com/blog/2017/04/06/dealing-mysql-error-code-1215-cannot-add-foreign-key-constraint/ )

由于mysqldump按字母顺序排列表,并且我不想更改表的名称,所以我按照jeremyweir的回答中的说明进行了操作 on this page ,哪个州 set FOREIGN_KEY_CHECKS = 0; 在转储文件的顶部 SET FOREIGN_KEY_CHECKS = 1; 在转储文件的底部。

这个办法对我有效。

Arvind Bhardwaj
Reply   •   5 楼
Arvind Bhardwaj    6 年前

在我的情况下,我不得不使残疾 FOREIGN KEY 作为源表的检查不存在。

SET FOREIGN_KEY_CHECKS=0;

ajon
Reply   •   6 楼
ajon    7 年前

这是已经说过的话的一个微妙版本,但是在我的例子中,我有两个数据库(foo和bar)。我首先创建了foo,但我没有意识到它引用了bar.baz中的外键(它还没有创建)。当我试图创建bar.baz(没有任何外键)时,我一直收到这个错误。找了一会儿,我在foo找到了外键。

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

noowie
Reply   •   7 楼
noowie    8 年前

我知道我去晚会很晚了,但我想把它放在这里,这样它就列出来了。

除了以上所有确保字段定义一致以及表类型也具有相同排序规则的建议外,还请确保不要犯尝试链接子字段中的数据不在父字段中的字段的新手错误。如果子字段中有尚未输入父字段的数据,则会导致此错误。遗憾的是,错误信息没有多大帮助。

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

祝你好运。

MAHDI ABDULSAHIB
Reply   •   8 楼
MAHDI ABDULSAHIB    8 年前

当使用laravel迁移时尝试生成外键时

比如这个例子:

用户表

    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

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

若要解决此问题,应更改[颜色表]中的主键

$table->tinyIncrements('id');


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

你应该用 Integer 作为外键

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

使用主键时 $表->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');
Dima Dz
Reply   •   9 楼
Dima Dz    9 年前

此错误的另一个原因是,有两个或多个相同的表名具有相同的外键名。这种情况有时会发生在使用建模和设计软件(如mysql workbench)的人身上,然后再从设计中生成脚本。

Olivier Faucheux
Reply   •   10 楼
Olivier Faucheux    9 年前

也要注意反引号的使用。我在一个脚本中有以下声明

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没有提供有关此错误的详细信息…

CoderBapu
Reply   •   11 楼
CoderBapu    6 年前

我只想把这个案子 VARCHAR 外键关系。上周我在mysql workbench 8.0中试图解决这个问题,最终修复了这个错误。

简短回答: 架构、表、列、引用表、引用列和引用父表的任何其他表的字符集和排序规则必须匹配。

长答案: 我的表中有一个枚举数据类型。我把这个改成了 瓦查尔 我可以从引用表中获取值,这样就不必修改父表来添加其他选项。这段外键关系看起来很简单,但我犯了1215个错误。 arvind 的答案和以下内容 link 建议使用

SHOW ENGINE INNODB STATUS;

在使用这个命令时,我得到了错误的以下详细描述,没有其他有用的信息

在引用的表中找不到 引用列显示为第一列或列类型 在表中与引用的表不匹配。 注意,枚举和集合的内部存储类型在 使用>=innodb-4.1.12创建的表,以及旧表中的此类列 不能被新表中的此类列引用。 请参考 http://dev.mysql.com/doc/refman/8.0/en/innodb-foreign-key-constraints.html 正确的外键定义。

之后我用 SET FOREIGN_KEY_CHECKS=0; 由建议 Arvind Bharadwaj 以及链接 here :

这将显示以下错误消息:

错误代码:1822。未能添加外键约束。失踪 约束索引

在这一点上,我对模式进行了“逆向工程”,并且能够在eer图中建立外键关系。在“前进工程师”中,我得到了以下错误:

错误1452:无法添加或更新子行:外键约束 失败

当我将eer图“转发”到一个新模式时,sql脚本运行时没有问题。在比较转发工程师尝试生成的sql时,我发现不同之处在于字符集和排序规则。父表、子表和这两列 utf8mb4 字符集和 utf8mb4_0900_ai_ci 但是,排序规则使用 CHARACTER SET = utf8 , COLLATE = utf8_bin ; 换一张桌子。

对于整个架构,我将所有表和列的字符集和排序规则更改为以下内容:

CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci;

这最终以1215个错误解决了我的问题。

旁注: 校勘 utf8mb4_general_ci 在mysql workbench 5.0或更高版本中工作。校勘 utf8mb4_0900_艾_ci 仅适用于MySQL Workbench 8.0或更高版本。我认为字符集和排序规则有问题的原因之一是MySQL Workbench升级到8.0。这是一个 link 这更能说明这一整理。

Stephen Nortje
Reply   •   12 楼
Stephen Nortje    9 年前

我经历这个错误的原因完全不同。我使用mysql workbench 6.3来创建我的数据模型(很棒的工具)。我注意到,当外键约束定义中定义的列顺序与表列序列不匹配时,也会生成此错误。

我花了大约4个小时尝试其他的一切,但检查。

现在一切正常,我可以重新开始编码了。-)

Chad
Reply   •   13 楼
Chad    9 年前

对我来说,是列类型。大个子!= INT。

但后来还是没用。

所以我检查了引擎。确保table1=innodb和table=innodb

Chris Neve
Reply   •   14 楼
Chris Neve    10 年前

喔,我刚拿到!它混合了很多已经发布的答案(innodb、unsigned等)。但我在这里没有看到的一件事是:如果fk指向一个pk,确保source列有一个有意义的值。例如,如果pk是mediumint(8),请确保源列也包含mediumint(8)。对我来说这是问题的一部分。

Community Oliver
Reply   •   15 楼
Community Oliver    8 年前

当由于引用的表使用myisam引擎而发生此错误时,此答案提供了一种快速转换数据库的方法,以便所有django模型表都使用innodb: https://stackoverflow.com/a/15389961/2950621

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

Community Oliver
Reply   •   16 楼
Community Oliver    8 年前

另一个原因:如果你使用 ON DELETE SET NULL 全部的 外键中使用的列必须允许空值。有人在里面发现了这个 this question

据我所知,数据完整性不会有问题,但MySQL似乎不支持这个特性(在5.7中)。

Dennis
Reply   •   17 楼
Dennis    8 年前

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

bortunac
Reply   •   18 楼
bortunac    8 年前

对于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

比较并验证两个列定义是否

相同的列类型(长度),相同的列

能帮你玩得像

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;
Mozaffar
Reply   •   19 楼
Mozaffar    9 年前

当列的类型不相同时,也会发生这种情况。

例如,如果您引用的列是无符号int,而被引用的列是int,则会出现此错误。

Seth gathila
Reply   •   20 楼
Seth gathila    10 年前

我找不到这个错误

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
)