MySQL:无法创建表(错误号:150)

时间:2010-10-31 00:24:06

标签: mysql sql phpmyadmin mysql-error-150

我正在尝试导入.sql文件,但是在创建表时失败了。

这是失败的查询:

CREATE TABLE `data` (
`id` int(10) unsigned NOT NULL,
`name` varchar(100) NOT NULL,
`value` varchar(15) NOT NULL,
UNIQUE KEY `id` (`id`,`name`),
CONSTRAINT `data_ibfk_1` FOREIGN KEY (`id`) REFERENCES `keywords` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1;    

我从同一个数据库导出.sql,我删除了所有表,现在我试图导入它,为什么它失败了?

  

MySQL:无法创建表'。/ dbname / data.frm'(错误号:150)

34 个答案:

答案 0 :(得分:160)

来自MySQL - FOREIGN KEY Constraints Documentation

  

如果重新创建已删除的表,则它必须具有符合引用它的外键约束的定义。它必须具有正确的列名和类型,并且必须在引用的键上具有索引,如前所述。 如果不满足这些,MySQL将返回错误1005并在错误消息中引用错误150,这意味着未正确形成外键约束。 同样,如果由于错误150,ALTER TABLE失败,这意味着对于更改的表,将错误地形成外键定义。

答案 1 :(得分:96)

错误150表示您的外键有问题。可能外表上的键不是完全相同的类型?

答案 2 :(得分:59)

您可以通过运行SHOW ENGINE INNODB STATUS;然后在输出中查找LATEST FOREIGN KEY ERROR来获取实际的错误消息。

来源:answer from another user in a similar question

答案 3 :(得分:28)

数据类型必须完全匹配。如果要处理varchar类型,则表必须使用相同的排序规则。

答案 4 :(得分:24)

我认为所有这些答案都是正确的,会误导这个问题。

如果要使用外键还原转储文件,则在开始还原之前,实际答案是:

SET FOREIGN_KEY_CHECKS=0;

因为在外表甚至存在之前,恢复自然会创建一些约束。

答案 5 :(得分:20)

在某些情况下,如果相关表之间存在不同的引擎,则可能会遇到此错误消息。例如,表可能正在使用InnoDB而另一个表使用MyISAM。两者都需要相同

答案 6 :(得分:11)

错误号码150表示外键约束失败。您可能在外键所依赖的表(表keywords)之前创建此表。首先创建该表,它应该工作正常。

如果没有,删除外键语句并在创建表后添加它 - 您将收到有关特定约束失败的更有意义的错误消息。

答案 7 :(得分:10)

有很多事情可以导致errno 150,所以对于搜索这个主题的人来说,这就是我认为接近详尽的列表(来源Causes of Errno 150):

对于errno 150或errno 121,只需键入SHOW ENGINE INNODB STATUS,就会出现一个名为“LATEST FOREIGN KEY ERROR”的部分。在此之下它会给你一个非常有用的错误信息,通常会立即告诉你什么是问题。您需要SUPER权限才能运行它,所以如果您没有,则只需测试以下方案。

1)数据类型不匹配:列的类型必须相同

2)没有索引的父列(或以错误的顺序索引)

3)列排序不匹配

4)在NOT NULL列上使用SET NULL

5)表格排序不匹配:即使列排序规则匹配,在某些MySQL版本上也可能存在问题。

6)父列在父表中实际上不存在。检查拼写(可能是列开头或结尾的空格)

7)其中一列的索引之一不完整,或者列对于完整索引而言太长。请注意,MySQL(除非您调整它)的最大单列密钥长度为767字节(这对应于varchar(255)UTF列)

如果你得到一个错误的121,这里有几个原因:

1)您选择的约束名称已被采用

2)在某些系统上,如果您的语句和表名称存在大小写差异。如果您从一台服务器转到另一台具有不同案例处理规则的服务器,这可能会让您感到厌烦。

答案 8 :(得分:8)

有时MySQL只是超级愚蠢 - 我可以理解外键的原因..但在我的情况下,我刚刚删除整个数据库,我仍然得到错误...为什么?我的意思是,没有数据库了......我正在使用的sql-user无法访问服务器上的任何其他数据库......我的意思是,服务器对于当前用户来说是“空的”而且我仍然得到这个错误?对不起,但我猜MySQL是骗我的...但我可以处理它:)只需在你的fucky声明中添加这两行SQL:

SET FOREIGN_KEY_CHECKS = 0;
# some code that gives you errno: 150
SET FOREIGN_KEY_CHECKS = 1;

现在应该执行sql ...如果你确实遇到了外键问题,它会显示在你再次启用检查的行 - 这将失败然后..但我的服务器只是安静:)

答案 9 :(得分:4)

在完成上述答案并进行实验后,这是解决MySQL中外键错误的有效方法(1005 - 错误150)。

要正确创建外键,MySQL要求的是:

  • 所有引用的键必须具有PRIMARY或UNIQUE索引。
  • 再次引用列必须与Referenced列具有相同的数据类型。

满足这些要求,一切都会顺利。

答案 10 :(得分:4)

将Windows应用程序移植到Linux时遇到此错误。在Windows中,数据库表名称不区分大小写,在Linux中它们区分大小写,可能是因为文件系统不同。因此,在Windows上,表Table1table1相同,REFERENCES table1Table1都有效。在Linux上,当应用程序在创建数据库结构时使用table1而不是Table1时,我看到错误#150;当我在Table1引用中创建了正确的字符大小写时,它也开始在Linux上运行。因此,如果没有其他帮助,请确保在REFERENCES中使用Linux时在表名中使用正确的字符大小写。

答案 11 :(得分:3)

  通常,外键和外键之间的不匹配主键导致   错误:150

外键必须与主键具有相同的数据类型。此外,如果主键 未签名,则外键也必须无符号

答案 12 :(得分:3)

如果PK表是在一个 CHARSET 中创建的,那么你在另一个CHARSET中创建FK表..那么你也可能会收到这个错误...我也得到了这个错误但是在更改了charset之后到PK charset然后执行没有错误

create table users
(
------------
-------------
)DEFAULT CHARSET=latin1;


create table Emp
(
---------
---------
---------
FOREIGN KEY (userid) REFERENCES users(id) on update cascade on delete cascade)ENGINE=InnoDB, DEFAULT CHARSET=latin1;

答案 13 :(得分:3)

我有同样的问题。它与表的列归类字符集有关。 确保两个表上的两个列的字符集排序规则必须相同。如果要在其上设置外键。 示例-如果将外键放在引用用户表的userID列的userImage表的userID列上,则排序规则必须与 utf8_general_ci 和字符集 utf8 相同表。通常,在创建表时,mysql从服务器设置中采用这两种配置。

答案 14 :(得分:3)

如果两个表具有引用,则会发生此错误,例如,一个表是Student,另一个表是Education,并且我们希望Education表具有Student表的外键引用。在这种情况下,两个表的列数据类型应该相同,否则会产生错误。

答案 15 :(得分:3)

更改表的引擎,只有innoDB支持外键

答案 16 :(得分:3)

就我而言。我的引擎和字符集有问题因为我的托管服务器更改设置而我的新表是MyISAM但我的旧表是InnoDB。我改变了。

答案 17 :(得分:3)

在大多数情况下,问题是因为发动机差异。如果父项是由InnoDB创建的,那么引用的表应该由MyISAM& AM创建。反之亦然

答案 18 :(得分:2)

我遇到了类似的问题,但我的原因是因为我在现有的表中添加了一个新字段,而且新字段引用了父表中的另一个字段,并且定义了NOT NULL且没有任何DEFAULT值。 - 我发现事情不起作用的原因是因为

  1. 我的新字段需要在应用约束之前使用每个记录上的父表中的值自动填充空白字段。每次应用约束时,都需要保持表数据的完整性。实现约束(外键)但是有一些数据库记录没有来自父表的值意味着数据已损坏所以MySQL永远不会强制你的约束
  2. 重要的是要记住,在正常情况下,如果您提前计划好数据库,并在数据插入之前实施约束,则可避免此特定情况

    避免这种问题的简单方法是

    • 保存数据库表数据
    • 截断表数据(和表工件,即索引等)
    • 应用约束
    • 导入您的数据

    我希望这有助于某人

答案 19 :(得分:2)

我在从文本文件创建数据库时遇到了这种问题。

mysql -uroot -padmin < E:\important\sampdb\createdb.sql
mysql -uroot -padmin sampdb < E:\important\sampdb\create_student.sql
mysql -uroot -padmin sampdb < E:\important\sampdb\create_absence.sql

mysql -uroot -padmin sampdb < E:\important\sampdb\insert_student.sql
mysql -uroot -padmin sampdb < E:\important\sampdb\insert_absence.sql

mysql -uroot -padmin sampdb < E:\important\sampdb\load_student.sql
mysql -uroot -padmin sampdb < E:\important\sampdb\load_absence.sql 

我刚刚在Create.bat中编写了上述行并运行了bat文件。

我的错误在于我的sql文件中执行的顺序。我试图用主键和外键创建表。在运行时,它将搜索引用表,但表不存在。 所以它会返回那种错误。

  

如果使用外键创建表,请检查引用   桌子是否存在。并检查参考的名称   表格和字段。

答案 20 :(得分:2)

一个真实的边缘案例是你使用MySQL工具(在我的例子中是Sequel Pro)来重命名数据库。然后创建了一个具有相同名称的数据库。

这将外键约束保留在同一个数据库名称中,因此重命名的数据库(例如my_db_renamed)在新创建的数据库中具有外键约束(my_db)

不确定这是否是Sequel Pro中的错误,或者某些用例是否需要此行为,但它在一个早上花费了我最好的部分:/

答案 21 :(得分:2)

我有同样的错误。在我的情况下,错误的原因是我在约束中有一个ON DELETE SET NULL语句,而我在其定义中放置约束的字段有一个NOT NULL语句。在字段中允许NULL可以解决问题。

答案 22 :(得分:2)

请确保您的主键列和引用列都具有相同的数据类型和属性(无符号,二进制,无符号zerofill等)。

答案 23 :(得分:1)

在使用单个表转储Django mysql数据库时遇到了类似的问题。我能够通过将数据库转储到文本文件,使用emacs将有问题的表移动到文件末尾并将修改后的sql转储文件导入新实例来解决问题。

HTH Uwe

答案 24 :(得分:1)

您从子表中引用的PARENT表的列必须是唯一的。如果不是,则导致错误150。

答案 25 :(得分:1)

我已通过使变量接受null

来纠正问题
ALTER TABLE `ajout_norme` 
CHANGE `type_norme_code` `type_norme_code` VARCHAR( 2 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL

答案 26 :(得分:1)

确保所有表都支持外键 - InnoDB引擎

答案 27 :(得分:1)

执行一系列MySQL命令时遇到了同样的问题。在将外键引用到尚未创建的其他表时,在创建表期间发生。在引用之前,它是表存在的顺序。

解决方案:在创建具有外键的子表之前,首先创建父表。

答案 28 :(得分:1)

创建没有外键的表,然后分别设置外键。

答案 29 :(得分:1)

也许this会有所帮助?主键列的定义应与外键列完全相同。

答案 30 :(得分:1)

我有同样的错误,然后我先创建了引用表,然后引用了表

  

例如,如果您有分配的员工和部门表   国外        对employee表中的dept_no进行约束,然后确保该部门        表已创建并已将主键约束分配给dept_no。

这对我有用......

答案 31 :(得分:0)

如果重新创建已删除的表,则该表必须具有符合引用该表的外键约束的定义。如前所述,它必须具有正确的列名和类型,并且必须在引用的键上具有索引。如果不满足这些条件,MySQL将返回 Error 1005 并在错误消息中引用 Error 150 ,这意味着未正确形成外键约束。同样,如果ALTER TABLE由于错误150而失败,这意味着将为更改后的表错误地形成外键定义。

答案 32 :(得分:0)

execute below line:
  SET FOREIGN_KEY_CHECKS = 0;


FOREIGN_KEY_CHECKS option specifies whether or not to check foreign key constraints for InnoDB tables. 

-- Specify to check foreign key constraints (this is the default)

    SET FOREIGN_KEY_CHECKS = 1;
 

-- Do not check foreign key constraints

   SET FOREIGN_KEY_CHECKS = 0;


When to Use :
Temporarily disabling referential constraints (set FOREIGN_KEY_CHECKS to 0) is useful when you need to re-create the tables and load data in any parent-child order.

答案 33 :(得分:-6)

尝试:

CREATE TABLE `data` (
  `id` int(10) unsigned NOT NULL,
  `name` varchar(100) NOT NULL,
  `value` varchar(15) NOT NULL,
UNIQUE KEY `id` (`id`,`name`),
CONSTRAINT `data_ibfk_1`,
FOREIGN KEY (`id`) REFERENCES `keywords` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1;  

您需要在CONSTRAINTFOREIGN之间添加“,”。