错误:无法添加外键约束

时间:2017-10-24 18:43:32

标签: mysql sql database mysql-5.6

问题

我有两张桌子。第一个是人口稠密的;第二个是空的。

我希望第二个拥有引用第一个列的外键。

我的理解是,它应该是可能的,只要:

  • 两个表都具有相同的引擎
  • 两列都具有相同的数据类型
  • 两列的长度
  • 相同
  • 两列都具有相同的整理
  • 两列都具有相同的字符集
  • 父列有唯一
  • 父列具有子列
  • 中每个值的匹配值

就我而言,所有这些条件都是正确的,但MySQL仍然不允许外键关系。

还需要满足哪些其他条件?

实施例

注意:此示例概述了情况,但不会重现错误。

架构:

CREATE TABLE `parents` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4

CREATE TABLE `kids` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `parent_id` int(10) unsigned NOT NULL,
  PRIMARY KEY (`id`),
  KEY `parent_id` (`parent_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4

parents已填充。 kids是空的。

kids.parent_id无法成为parents.id的外键:

ALTER TABLE `kids` ADD FOREIGN KEY (`parent_id`) REFERENCES `parents` (`id`);
-- Error : Cannot add foreign key constraint

失败的解决方案

MySQL没有提供错误的原因; SHOW ENGINE INNODB STATUS不返回任何内容:

SHOW ENGINE INNODB STATUS;
-- [Type]       [Name]      [Status]
-- InnoDb

我拥有所需的数据库权限。

我已经仔细检查过列(甚至表格)具有相同的排序规则(字符集不适用于INT列)

ALTER TABLE `parents` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_520_ci;
ALTER TABLE `parents` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_520_ci;
ALTER TABLE `parents` MODIFY `id` int(10) unsigned NOT NULL AUTO_INCREMENT COLLATE utf8mb4_unicode_520_ci;
ALTER TABLE `kids` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_520_ci;
ALTER TABLE `kids` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_520_ci;
ALTER TABLE `kids` MODIFY `parent_id` int(10) unsigned NOT NULL COLLATE utf8mb4_unicode_520_ci;

ALTER TABLE `kids` ADD FOREIGN KEY (`parent_id`) REFERENCES `parents` (`id`);
-- Error : Cannot add foreign key constraint

讨论

之前我已经设置了很多外键,但在这种情况下显然有些不同。

上面的示例不会重现错误,这意味着架构是正确的。因此,除了模式之外的东西必须导致错误。

parents表或数据中必须存在隐藏的设置或条件,这使得它与kids表不兼容。它可能是什么?

注释

以前曾提出类似的问题,但他们的答案并没有解决这个特殊情况下的问题。

1 个答案:

答案 0 :(得分:0)

您需要允许外国人使用NULL

CREATE TABLE `kids` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `parent_id` int(10) unsigned NULL, // <<== HERE 
  PRIMARY KEY (`id`),
  KEY `parent_id` (`parent_id`),
  CONSTRAINT parent_fk FOREIGN KEY (parent_id)
   REFERENCES parents(parent_id)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4