MySQL: 无法创建表(errno: 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: 无法创建 table’./dbname/data.frm’(errno: 150)

362482 次浏览

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

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

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

来自 外键约束文档:

如果重新创建已删除的表,则该表必须具有符合引用它的外键约束的定义。它必须具有正确的列名和类型,并且必须在引用的键上具有索引,如前所述。类似地,如果 ALTERTABLE 由于错误150而失败,这意味着对于已更改的表,将错误地形成外键定义。

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

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

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

试试:

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之间放一个“ ,”。

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

如果在一个 病历中创建 PK 表,然后在另一个 CHARSET 中创建 FK 表。.然后你也可能会得到这个错误... 我也得到了这个错误,但后改变字符集 PK 字符集然后它得到执行没有错误

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;

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

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

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

SET FOREIGN_KEY_CHECKS=0;

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

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

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

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

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

有时候 MySQL 就是超级愚蠢-我能理解外键的原因。.但在我的情况下,我刚刚删除了整个数据库,我仍然得到错误... 为什么?我的意思是,已经没有数据库了... 我使用的 sql-user 不能访问服务器上的任何其他数据库... 我的意思是,服务器对于当前用户是“空的”,我仍然得到这个错误?对不起,我猜 MySQL 在对我撒谎... ... 但我可以处理它:)只需要在你的操蛋语句周围添加这两行 SQL 语句:

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

现在应该执行 sql 了... ... 如果您真的遇到了外键问题,它会通过您再次启用检查的行显示出来——这将失败。.但是我的服务器很安静:)

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

如果两个表有一个引用,例如,一个表是 Student,另一个表是 Education,我们希望 Education 表有一个 Student 表的外键引用,就会发生这个错误。在此实例中,两个表的列数据类型应该相同,否则将生成错误。

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

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

资料来源: 来自其他用户的类似问题的回答

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

这将外键约束保留到相同的数据库名称,因此重命名的数据库(例如 my _ db _ rename)在新创建的数据库(my _ db)中有外键约束

不确定这是否是 Sequel Pro 中的一个 bug,或者某些用例是否需要这种行为,但它花费了我一个早上最好的时间:/

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

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

有相当多的事情可能导致 errno 150,因此对于搜索这个主题的人来说,下面是我认为接近详尽的列表(来源 Errno 150的成因) :

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

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

2)父栏没有索引(或索引顺序错误)

3)列排序规则不匹配

4)在非空列上使用 SETNULL

5)表排序规则不匹配: 即使列排序规则匹配,在某些 MySQL 版本中也会出现问题。

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

7)其中一列的索引不完整,或者该列太长,无法构成完整的索引。注意,MySQL (除非进行调整)的最大单列密钥长度为767字节(这对应于 varchar (255) UTF 列)

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

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

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

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

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

胡伟

对我来说。我有引擎和字符集的问题,因为我的主机服务器改变设置,我的新表是 MyISAM,但我的旧表是 InnoDB。只是我变了。

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

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 文件中的执行顺序。我尝试用主键和外键创建表。当它运行时,它将搜索引用表,但表不在那里。 所以它会返回这类错误。

如果使用外键创建表,请检查引用 表是否存在。还要检查引用的名称 桌子和田野。

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

ALTER TABLE `ajout_norme`
CHANGE `type_norme_code` `type_norme_code` VARCHAR( 2 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL

我有一个类似的问题,但我的是因为我添加了一个新的字段到一个现有的表,有数据,和新的字段是引用另一个字段从父表,也有定义的 NOT NULL,没有任何 DEFAULT 值。我发现事情不顺利的原因是

  1. 在应用约束之前,我的新字段需要用来自每条记录上的父表的值自动填充空字段。每次应用约束时,都需要保持表数据的 Integrity 不变。实现 CONSTRAINT (外键)然而有些数据库记录没有父表中的值将意味着数据损坏,因此 MySQL 将永远不会强化您的 CONSTRAINT

一定要记住,在正常情况下,如果您提前计划好数据库,并在插入数据之前实现约束,就可以避免这种特殊场景

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

  • 保存数据库表数据
  • 截断表数据(以及表构件,如索引等)
  • 应用约束
  • 导入数据

我希望这能帮到别人

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

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

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

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

外键必须具有与 主键相同的 数据类型。另外,如果 主键没签名,那么 外键也必须是 没签名

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

例如,如果您有员工和部门表,您的分配 外国人 约束到 dept _ no,然后确保部门 表,并已将主键约束分配给 dept _ no。

这招对我很管用。

我也有同样的问题,它与表的 校对字符集列有关。 确保两个表上的两列的 字符集校对必须相同。如果你想设置一个外键。 示例-如果在 userImage 表的 userID 列上放置外键,引用 users 表的 userID 列。然后,排序规则必须与表的两列的 Utf8 _ general _ ci和字符集 Utf8相同。通常,当您创建一个表 mysql 从服务器设置中获取这两个配置。

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

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.

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

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