165

我正在尝试导入 .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' (errno: 150)

4

35 回答 35

173

来自MySQL - FOREIGN KEY Constraints 文档

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

于 2010-10-31T00:39:14.140 回答
101

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

于 2010-10-31T00:28:48.040 回答
68

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

资料来源:另一位用户在类似问题中的回答

于 2014-07-23T17:28:30.497 回答
31

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

于 2010-12-09T13:46:52.980 回答
28

我认为所有这些答案虽然正确,但会误导问题。

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

SET FOREIGN_KEY_CHECKS=0;

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

于 2013-04-25T12:14:24.430 回答
24

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

于 2011-08-03T11:53:40.470 回答
12

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

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

于 2010-10-31T00:29:51.807 回答
10

有很多事情会导致 errno 150,因此对于搜索此主题的人,我认为这是一个接近详尽的列表(Errno 150 的来源原因):

对于 errno 150 或 errno 121,只需输入 SHOW ENGINE INNODB STATUS,就会有一个名为“LATEST FOREIGN KEY ERROR”的部分。在此之下,它会给您一个非常有用的错误消息,通常会立即告诉您问题所在。你需要超级权限才能运行它,所以如果你没有,你只需要测试以下场景。

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

2) 父列未编入索引(或索引顺序错误)

3)列排序规则不匹配

4) 在 NOT NULL 列上使用 SET NULL

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

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

7) 其中一列的索引不完整,或者该列对于完整索引来说太长。请注意,MySQL(除非您对其进行调整)的最大单列键长度为 767 字节(这对应于 varchar(255) UTF 列)

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

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

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

于 2015-03-18T17:21:09.867 回答
9

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

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

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

于 2013-07-18T16:08:01.030 回答
5

我有同样的问题。它与表的列Collat​​ionCharacter Set相关。确保两个表上的两列的字符集排序规则必须相同。如果你想在上面设置一个外键。示例 - 如果您将外键放在 userImage 表的 userID 列上,引用用户表的 userID 列。那么排序规则必须与表的两个列的utf8_general_ci和字符集utf8相同。通常,当您创建表时,mysql 从服务器设置中获取这两个配置。

于 2018-07-10T09:08:11.040 回答
4

在浏览了上面的答案并进行了一些实验之后,这是解决 MySQL 中的外键错误(1005 - 错误 150)的有效方法。

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

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

满足这些要求,一切都会好起来的。

于 2013-07-03T14:50:00.167 回答
4

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

于 2014-04-23T14:34:58.393 回答
4

通常,外键和主键不匹配会导致错误:150。

必须与主键具有相同的数据类型。此外,如果主键无符号的,那么外键也必须是无符号的。

于 2017-11-24T12:04:04.600 回答
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;
于 2012-10-16T10:19:28.920 回答
3

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

于 2012-04-17T16:14:48.177 回答
3

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

于 2013-12-23T05:53:52.747 回答
3

在大多数情况下,问题是由于 ENGINE 差异造成的。如果父表是由 InnoDB 创建的,那么引用的表应该由 MyISAM 创建,反之亦然

于 2015-06-16T14:34:56.083 回答
3

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

于 2015-10-29T14:39:05.997 回答
2

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

于 2014-11-22T18:59:13.033 回答
2

一个真正的边缘案例是您使用 MySQL 工具(在我的案例中为 Sequel Pro)重命名数据库。然后创建了一个同名的数据库。

这使外键约束保持到相同的数据库名称,因此重命名的数据库(例如 my_db_renamed)在新创建的数据库(my_db)中具有外键约束

不确定这是否是 Sequel Pro 中的错误,或者某些用例是否需要这种行为,但它花费了我一大早:/

于 2014-11-06T12:45:21.220 回答
2

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

于 2015-01-06T12:51:09.717 回答
2

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

于 2013-09-19T05:43:50.300 回答
2

创建没有外键的表,然后单独设置外键。

于 2017-11-17T10:02:31.307 回答
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 文件中的执行顺序。我试图用主键和外键创建表。在运行时,它将搜索参考表,但表不存在。所以它会返回那种错误。

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

于 2016-01-14T13:09:26.890 回答
2

我有一个类似的问题,但我的问题是因为我正在向具有数据的现有表添加一个新字段,并且新字段正在引用父表中的另一个字段,并且还具有 NOT NULL 的定义并且没有任何默认值。- 我发现事情不工作的原因是因为

  1. 在应用约束之前,我的新字段需要使用每条记录的父表中的值自动填充空白字段。每次应用约束时,都需要保持表数据的完整性不变。实施约束(外键)但有一些数据库记录没有父表中的值将意味着数据已损坏,因此 MySQL 永远不会强制执行您的约束

重要的是要记住,在正常情况下,如果您提前计划好数据库,并在数据插入之前实施约束,则可以避免这种特殊情况

避免这个问题的更简单的方法是

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

我希望这可以帮助别人

于 2016-10-24T11:04:43.427 回答
1

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

于 2013-03-21T15:22:38.863 回答
1

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

于 2012-10-02T05:16:11.380 回答
1

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

解决方案:先创建父表,再创建具有外键的子表。

于 2017-10-25T05:03:27.367 回答
1

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

HTH 乌韦

于 2015-07-16T16:07:00.397 回答
1

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

例如,如果您有员工表和部门表,则在员工表中的 dept_no 上分配外部约束,然后确保已创建部门表并将主键约束分配给 dept_no。

这对我有用...

于 2017-11-28T11:51:20.817 回答
1

我通过使变量接受来纠正了这个问题null

ALTER TABLE `ajout_norme` 
CHANGE `type_norme_code` `type_norme_code` VARCHAR( 2 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL
于 2016-04-14T15:50:54.823 回答
0

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

于 2018-07-21T19:31:47.167 回答
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.
于 2019-09-06T11:43:24.247 回答
0

这是一个愚蠢的错误,但我得到了 'errno: 150' 因为我忘记定义被引用为主键的父属性。

只是分享以防其他人有同样的问题。

于 2022-01-20T12:55:38.447 回答
-7

尝试:

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;  

您需要在CONSTRAINT和之间放置一个“,” FOREIGN

于 2012-08-07T18:43:05.953 回答