错误代码:1005。无法创建表'...'(错误号:150)

时间:2012-01-26 13:14:31

标签: mysql foreign-keys mysql-error-1005

我在互联网上搜索了这个问题的解决方案并检查了SO问题,但没有解决方案适用于我的情况。

我想从表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);

我在两个表(charset和collat​​ion)上检查了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 

13 个答案:

答案 0 :(得分:259)

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

通常是由于参考FK字段不存在。可能是你有错字错误,或检查案例应该是相同的,或者是字段类型不匹配。 FK链接的字段必须与定义完全匹配。

一些已知原因可能是:

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

答案 1 :(得分:11)

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

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

SET FOREIGN_KEY_CHECKS=0;

它会起作用。

答案 2 :(得分:4)

我知道这是一个迟到的答案,但我认为这对某人有帮助。

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

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

答案 3 :(得分:3)

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

答案 4 :(得分:2)

错误代码:1005

您好, 我正在回答这个问题,以便任何像我一样面临类似问题的人都可以从中受益。相信我,这可以被忽视) (这可能已经回答了,如果有,请原谅我)

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

  1. 更改了外键名称(不起作用)
  2. 减少外键长度
  3. 验证了数据类型(没有错误)
  4. 检查索引
  5. 检查整理(一切正常,再次尝试)
  6. 截断表格,没什么用处
  7. 放下桌子并重新创建
  8. 试图查看是否正在创建任何循环引用---一切正常
  9. <强> 9。最后,我看到我打开了两位编辑。一个在PHPStorm(jetbrains)和另一个MySQL工作台。似乎PHPStorm / SQL工作台创建了某种编辑锁。 我关闭PHPStorm只是为了检查锁定是否是这种情况(它可能是另一种方式)。这解决了我的问题。 希望这可以帮助有类似问题的人。

答案 5 :(得分: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语句中的

...意味着缺少一些代码。

答案 6 :(得分:1)

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

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

我希望有所帮助。

答案 7 :(得分:1)

我收到了同样的错误消息。最后我发现我拼错了命令中表格的名称:

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

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

我想知道为什么地球上的mysql不能说这样的表不存在...

答案 8 :(得分:1)

外键必须与它引用的主键具有完全相同的类型。对于示例具有“INT UNSIGNED NOT NULL”类型,foreing键也必须“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';

答案 9 :(得分:1)

我的问题没有列出,这太愚蠢了..... 以FK作为PK的表是一个复合PK,其声明如下:主键(CNPJCEP) 我希望CEP字段位于另一个表中,FK,但我陷入了这个错误,故事的寓意只是颠倒了上面主键(CEPCNPJ)的代码,有效。 给他们的朋友小费。

答案 10 :(得分:0)

刚刚提到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 ;

答案 11 :(得分:0)

就我而言,当一张桌子是InnoB而另一张桌子是MyISAM时,就发生了这种情况。通过MySQL Workbench改变一个表的引擎,为我解决了。

答案 12 :(得分:0)

检查两个表是否具有相同的架构InnoDB MyISAM。在我的InnoDB案例中,我都做了相同的工作