106

我在 Internet 上搜索了此问题的解决方案并检查了 Stack Overflow 问题,但没有一个解决方案适用于我的情况。

我想创建一个从表 sira_no 到 metal_kod 的外键。

ALTER TABLE sira_no
    ADD CONSTRAINT METAL_KODU FOREIGN KEY(METAL_KODU)
    REFERENCES metal_kod(METAL_KODU)
    ON DELETE SET NULL
    ON UPDATE SET NULL ;

此脚本返回:

Error Code: 1005. Can't create table 'ebs.#sql-f48_1a3' (errno: 150)

我尝试向引用的表添加索引:

CREATE INDEX METAL_KODU_INDEX ON metal_kod (METAL_KODU);

我在两个表(字符集和排序规则)上检查了 METAL_KODU,但找不到解决此问题的方法。我该如何解决这个问题?

这是 metal_kod 表:

METAL_KODU    varchar(4)    NO    PRI
DURUM    bit(1)    NO
METAL_ISMI    varchar(30)    NO
AYAR_YOGUNLUK    smallint(6)    YES        100
4

13 回答 13

275

错误代码:1005 - 您的代码中存在错误的主键引用

通常是由于引用的外键字段不存在。可能是您有拼写错误,或者检查大小写应该相同,或者字段类型不匹配。外键链接字段必须与定义完全匹配。

一些已知的原因可能是:

  1. 两个关键字段类型和/或大小不完全匹配。例如,如果一个是INT(10)关键字段,则需要是INTas well 而不是BIGINTor SMALLINTor TINYINT。您还应该检查一个不是SIGNED,另一个是UNSIGNED。它们都需要完全相同。
  2. 您尝试引用的关键字段之一没有索引和/或不是主键。如果关系中的某个字段不是主键,则必须为该字段创建索引。
  3. 外键名称是已经存在的键的副本。检查您的外键名称在您的数据库中是唯一的。只需在密钥名称的末尾添加一些随机字符即可进行测试。
  4. 您的一张或两张桌子是一张MyISAM桌子。为了使用外键,表必须都是InnoDB. (实际上,如果两个表都是,MyISAM那么您将不会收到错误消息 - 它只是不会创建密钥。)在查询浏览器中,您可以指定表类型。
  5. 您已指定级联ON DELETE SET NULL,但相关键字段设置为NOT NULL。您可以通过更改级联或将字段设置为允许NULL值来解决此问题。
  6. 确保 Charset 和 Collat​​e 选项在表级别以及键列的单个字段级别都相同。
  7. 您的外键列上有一个默认值(即 default=0)
  8. 关系中的一个字段是组合(复合)键的一部分,并且没有自己的单独索引。即使该字段有一个索引作为复合键的一部分,您也必须仅为该键字段创建一个单独的索引才能在约束中使用它。
  9. 您的ALTER语句中有语法错误,或者您在关系中输入了错误的字段名称之一
  10. 您的外键名称超过了 64 个字符的最大长度。

更多详情请参考:MySQL Error Number 1005 Can't create table

于 2012-01-26T13:26:25.280 回答
11

将数据库从一台服务器导出到另一台服务器时也会发生这种情况,并且默认情况下这些表按字母顺序列出。
因此,您的第一个表可能具有另一个尚未创建的表的外键。在这种情况下,禁用 foreign_key_checks 并创建数据库。

只需将以下内容添加到您的脚本中:

SET FOREIGN_KEY_CHECKS=0;

它会起作用。

于 2015-05-07T13:27:38.423 回答
4

当外键和引用键的类型不同或长度不同时,通常会发生这种情况。

于 2014-08-25T12:29:10.350 回答
4

有时是由于主表被删除(可能是通过禁用foreign_key_checks),但外键CONSTRAINT仍然存在于其他表中。在我的情况下,我删除了表并尝试重新创建它,但它给我抛出了同样的错误。

因此,如果有任何表,请尝试从所有表中删除所有外键约束,然后更新或创建表。

于 2015-02-01T11:21:23.587 回答
2

错误代码:1005

我有一个类似的问题,所以这里有一些我尝试过的事情(不是按任何顺序,除了解决方案:))

  1. 更改了外键名称(不起作用)
  2. 减少外键长度
  3. 验证数据类型(没有错)
  4. 检查索引
  5. 检查排序规则(一切正常,又该死)
  6. 截断表,没用
  7. 删除表并重新创建
  8. 试图查看是否正在创建任何循环引用——一切都很好
  9. 最后,我看到我打开了两个编辑器。一个在 PhpStorm (JetBrains) 和另一个 MySQL 工作台中。似乎 PhpStorm / MySQL Workbench 创建了某种编辑锁。

    我关闭了 PhpStorm 只是为了检查是否是这种情况(可能是相反的情况)。这解决了我的问题。

于 2016-05-07T03:18:22.097 回答
2

我有一个类似的错误。问题与子表和父表没有相同的字符集和排序规则有关。这可以通过附加 ENGINE = InnoDB DEFAULT CHARACTER SET = utf8; 来解决。

CREATE TABLE IF NOT EXISTS `country` (`id` INT(11) NOT NULL AUTO_INCREMENT,...) ENGINE = InnoDB DEFAULT CHARACTER SET = utf8;

... SQL 语句上的意思是缺少一些代码。

于 2016-07-14T08:34:40.633 回答
2

我有同样的错误信息。最后我发现我在命令中拼错了表的名称:

ALTER TABLE `users` ADD FOREIGN KEY (country_id) REFERENCES country (id);

相对

ALTER TABLE `users` ADD FOREIGN KEY (country_id) REFERENCES countries (id);

我想知道为什么 MySQL 不能告诉这样的表不存在......

于 2017-02-07T03:04:58.643 回答
2

外键必须与它引用的主键具有完全相同的类型。例如,类型为“INT UNSIGNED NOT NULL”的外键也必须为“INT UNSIGNED NOT NULL”</p>

CREATE TABLE employees(
id_empl INT UNSIGNED NOT NULL AUTO_INCREMENT,
PRIMARY KEY(id)
);
CREATE TABLE offices(
id_office INT UNSIGNED NOT NULL AUTO_INCREMENT,
id_empl INT UNSIGNED NOT NULL,
PRIMARY KEY(id),
CONSTRAINT `constraint1` FOREIGN KEY (`id_empl`) REFERENCES `employees` (`id_empl`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='my offices';
于 2017-02-15T13:10:47.940 回答
1

它发生在我的例子中,因为在约束声明中引用的表的名称不正确(我忘记了表名中的大写):

ALTER TABLE `Window` ADD CONSTRAINT `Windows_ibfk_1` FOREIGN KEY (`WallId`) REFERENCES `Wall` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
于 2015-03-10T15:45:05.597 回答
1

刚刚提到了 MyISAM。只需尝试添加ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;在语句的末尾,假设您的其他表是使用 MyISAM 创建的。

CREATE TABLE IF NOT EXISTS `tablename` (
  `key` bigint(20) NOT NULL AUTO_INCREMENT,
  FOREIGN KEY `key` (`key`) REFERENCES `othertable`(`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;
于 2016-01-20T23:29:35.967 回答
1

就我而言,它发生在一张桌子是 InnoB 而另一张桌子是 MyISAM 时。通过 MySQL Workbench 更改一张表的引擎为我解决了问题。

于 2016-03-28T02:01:48.400 回答
1

检查两个表是否具有相同的架构 InnoDB MyISAM。在我的情况下,我使它们都一样 InnoDB 并工作

于 2019-09-21T02:35:32.047 回答
1

我的问题没有列出,这太愚蠢了.....具有FKas PK 的表是这样声明的复合表PK:主键(CNPJCEP)我希望 CEP 字段FK位于另一个表中,我是卡在这个错误中,故事的寓意只是将上面的代码反转为主键(CEPCNPJ)并且它起作用了。给他们的朋友小费。

于 2020-06-08T04:49:08.540 回答