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

Posted

技术标签:

【中文标题】错误代码:1005。无法创建表“...”(错误号:150)【英文标题】:Error Code: 1005. Can't create table '...' (errno: 150) 【发布时间】:2012-02-19 13:46:26 【问题描述】:

我在 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 表的架构...该表中的哪个字段应该外键引用? 【参考方案1】:

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

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

一些已知的原因可能是:

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

更多详情请参考:mysql Error Number 1005 Can’t create table

【讨论】:

问题是外键字符集不匹配。感谢您的回答。 SHOW ENGINE INNODB STATUS this question 中提到的帮助我诊断了我的特定问题(PEBCAK,在我的情况下......) 该死的,即使它是主键。您需要为该键创建单独的索引。谢谢这解决了我的问题。 #4 是我的问题 - 其中一个表是 MyISAM,脚本试图创建一个 InnoDB 表。当我尝试部署最初运行 MySQL 5.0 或类似版本的旧系统时遇到了这个问题,其中默认存储引擎是 MyISAM 并且脚本运行正常。我目前的环境是5.5,默认存储是InnoDB。在脚本开头添加set names 'utf8', storage_engine=MYISAM; 为我解决了这个问题。谢谢@user319198 和@Stefano 的详尽回答! :o) 我的缺少 #1 中提到的“无符号”属性,谢谢!【参考方案2】:

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

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

SET FOREIGN_KEY_CHECKS=0;

它会起作用的。

【讨论】:

【参考方案3】:

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

【讨论】:

【参考方案4】:

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

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

【讨论】:

【参考方案5】:

我遇到了类似的错误。问题与子表和父表没有相同的字符集和排序规则有关。这可以通过附加 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】:

外键必须与它引用的主键具有完全相同的类型。例如,类型为“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';

【讨论】:

未签名对我来说是个问题。谢谢!【参考方案7】:

错误代码:1005

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

    更改了外键名称(不起作用) 减少了外键长度 验证数据类型(没有错) 检查索引 检查排序规则(一切正常,又该死) 截断了表格,没有用处 删除表并重新创建 尝试查看是否正在创建任何循环引用 --- 一切正常

    最后,我看到我打开了两个编辑器。一个在 PhpStorm (JetBrains) 和另一个 MySQL 工作台中。 PhpStorm / MySQL Workbench 似乎创建了某种编辑锁。

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

【讨论】:

【参考方案8】:

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

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

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

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

【讨论】:

【参考方案9】:

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

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 ;

【讨论】:

【参考方案10】:

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

【讨论】:

【参考方案11】:

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

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

【讨论】:

【参考方案12】:

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

【讨论】:

【参考方案13】:

我的问题没有列出来,太傻了..... 将 FK 作为 PK 的表是一个复合 PK,声明如下:主键 (CNPJ, CEP) 我希望 CEP 字段在另一个表中为 FK,但我陷入了这个错误,故事的寓意只是反转了上面的主键代码(CEPCNPJ)并且它起作用了。 给他们的朋友小费。

【讨论】:

以上是关于错误代码:1005。无法创建表“...”(错误号:150)的主要内容,如果未能解决你的问题,请参考以下文章

SQL - 错误代码 1005 和错误号 121

mysql 无法创建表 - 错误 1005

Laravel 一般错误:1005 无法创建表

一般错误:1005 无法创建表

如何解决 laravel 迁移错误“一般错误:1005 无法创建表”

Laravel 5.8:一般错误:1005 无法创建表