错误代码 1215 无法添加外键约束

当表没有足够的结构来处理开发人员强制要求的外键(FK)要求的快速查找验证时,会发生此错误。

CREATE TABLE `gtType` (
  `type` char(2) NOT NULL,
  `description` varchar(1000) NOT NULL,
  PRIMARY KEY (`type`)
) ENGINE=InnoDB;

CREATE TABLE `getTogethers` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `type` char(2) NOT NULL,
  `eventDT` datetime NOT NULL,
  `location` varchar(1000) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `fk_gt2type` (`type`), -- see Note1 below 
  CONSTRAINT `gettogethers_ibfk_1` FOREIGN KEY (`type`) REFERENCES `gtType` (`type`)
) ENGINE=InnoDB;

注 1:由于 FK 定义在其后面的行中,因此如果需要,将自动创建这样的 KEY。开发人员可以跳过它,如果需要,将添加 KEY(也称索引)。下面在 someOther 中显示了开发人员跳过它的一个例子。

到目前为止一直很好,直到下面的调用。

CREATE TABLE `someOther` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `someDT` datetime NOT NULL,
  PRIMARY KEY (`id`),
  CONSTRAINT `someOther_dt` FOREIGN KEY (`someDT`) REFERENCES `getTogethers` (`eventDT`)
) ENGINE=InnoDB;

错误代码:1215。无法添加外键约束

在这种情况下,由于缺少引用getTogethers 中的索引来处理 eventDT 的快速查找,它失败了。要在下一个声明中解决。

CREATE INDEX `gt_eventdt` ON getTogethers (`eventDT`);

getTogethers 已被修改,现在 someOther 的创建将成功。

来自 MySQL 手册页使用 FOREIGN KEY 约束

MySQL 需要外键和引用键上的索引,以便外键检查可以很快并且不需要表扫描。在引用表中,必须有一个索引,其中外键列以相同的顺序列为第一列。如果索引不存在,则会自动在引用表上创建此索引。

外键和引用键中的相应列必须具有相似的数据类型。整数类型的大小和符号必须相同。字符串类型的长度不必相同。对于非二进制(字符)字符串列,字符集和排序规则必须相同。

InnoDB 允许外键引用任何索引列或列组。但是,在引用的表中,必须有一个索引,其中引用的列被列为相同顺序的第一列。

请注意,最后一点是关于第一列(最左侧)列以及缺少主键要求(尽管强烈建议)。

成功创建引用 (子)表后,使用如下命令可以看到为你自动创建的所有键:

SHOW CREATE TABLE someOther;

遇到此错误的其他常见情况包括,如上文所述,但应突出显示:

  • 在签署的 INT 中看似微不足道的差异,指向 INT UNSIGNED

  • 开发人员无法理解多列(复合)KEYS 和第一(最左)订购要求。