错误代码:1005。无法创建表“…”(错误号:150)


103

我在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

您可以显示metal_kod表的架构吗?外键应引用该表中的哪个字段?
Manse 2012年

Answers:


271

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

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

一些已知的原因可能是:

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

有关更多详细信息,请参阅:MySQL错误号1005无法创建表


4
问题是外键字符集不匹配。感谢你的回答。
lamostreta,2012年

4
SHOW ENGINE INNODB STATUS正如这个问题中提到的那样,帮助我诊断了我的特定问题(以PEBCAK为例)
Hobo

1
该死的,即使它是主键。您需要为该密钥创建单个索引。谢谢,这解决了我的问题。
RSB 2012年

3
#4是我的问题-其中一个表是MyISAM,脚本试图创建一个InnoDB表。当我尝试部署最初运行MySQL 5.0或类似版本的旧系统时遇到了这个问题,其中默认存储引擎为MyISAM,脚本运行正常。我当前的环境是5.5,默认存储是InnoDB。set names 'utf8', storage_engine=MYISAM;在脚本的开头添加内容为我解决了这个问题。感谢@ user319198和@Stefano的详尽回答!:o)
Boris Chervenkov

1
我的数据库缺少#1中提到的'unsigned'属性,谢谢!
Helvete

11

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

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

SET FOREIGN_KEY_CHECKS=0;

它会工作。


4

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


4

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

因此,请尝试从所有表中删除所有外键CONSTRAINT(如果有的话),然后更新或创建表。


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语句上意味着缺少一些代码。


2

外键必须具有与其引用的主键完全相同的类型。对于示例,其类型为“ INT UNSIGNED NOT NULL”,则前一个键也必须为“ INT UNSIGNED NOT NULL”

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';

对我来说,未签名是问题。谢谢!
加博

2

错误代码:1005

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

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

    我关闭了PhpStorm,只是为了检查是否发生了锁定(反之亦然)。这解决了我的问题。


2

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

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

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

我不知道为什么地球上MySQL无法分辨出这样的表不存在...


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 ;

1

就我而言,它发生在一个表是InnoB而另一个表是MyISAM时。通过MySQL Workbench更改一张表的引擎可以为我解决。


1

就我而言,这是因为在约束声明中引用的表名不正确(我忘记了表名中的大写字母):

ALTER TABLE `Window` ADD CONSTRAINT `Windows_ibfk_1` FOREIGN KEY (`WallId`) REFERENCES `Wall` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;


1

我的问题没有列出,这是如此愚蠢...具有FKas PK 的表PK是这样声明的组合:主键(CNPJCEP)我希望CEP字段FK位于另一个表中,卡在此错误中,故事的寓意只是颠倒了上面主键()的代码CEPCNPJ并且可以正常工作。给他们的朋友小费。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.