MySQL“ERROR 1005(HY000):无法创建表'foo。#sql-12c_4'(错误号:150)”

49

我正在创建数据库foo中的一些表格,但每次都会出现关于外键的错误编号150。首先,这是我创建表格的代码:

CREATE TABLE Clients
(
client_id                CHAR(10)  NOT NULL ,
client_name              CHAR(50)  NOT NULL ,
provisional_license_num  CHAR(50)  NOT NULL ,
client_address           CHAR(50)  NULL ,
client_city              CHAR(50)  NULL ,
client_county            CHAR(50)  NULL ,
client_zip               CHAR(10)  NULL ,
client_phone             INT       NULL ,
client_email             CHAR(255) NULL ,
client_dob               DATETIME  NULL ,
test_attempts            INT       NULL
);
CREATE TABLE Applications
(
application_id   CHAR(10) NOT NULL ,
office_id        INT      NOT NULL ,
client_id        CHAR(10) NOT NULL ,
instructor_id    CHAR(10) NOT NULL ,
car_id           CHAR(10) NOT NULL ,
application_date DATETIME NULL 
);
CREATE TABLE Instructors
(
instructor_id      CHAR(10)  NOT NULL ,
office_id          INT       NOT NULL ,
instructor_name    CHAR(50)  NOT NULL ,
instructor_address CHAR(50)  NULL ,
instructor_city    CHAR(50)  NULL ,
instructor_county  CHAR(50)  NULL ,
instructor_zip     CHAR(10)  NULL ,
instructor_phone   INT       NULL ,
instructor_email   CHAR(255) NULL ,
instructor_dob     DATETIME  NULL ,
lessons_given      INT       NULL 
);
CREATE TABLE Cars
(
car_id             CHAR(10) NOT NULL ,
office_id          INT      NOT NULL ,
engine_serial_num  CHAR(10) NULL ,
registration_num   CHAR(10) NULL ,
car_make           CHAR(50) NULL ,
car_model          CHAR(50) NULL 
);
CREATE TABLE Offices
(
office_id       INT       NOT NULL ,
office_address  CHAR(50)  NULL ,
office_city     CHAR(50)  NULL ,
office_County   CHAR(50)  NULL ,
office_zip      CHAR(10)  NULL ,
office_phone    INT       NULL ,
office_email    CHAR(255) NULL 
);
CREATE TABLE Lessons
(
lesson_num     INT            NOT NULL ,
client_id      CHAR(10)       NOT NULL ,
date           DATETIME       NOT NULL ,
time           DATETIME       NOT NULL ,
milegage_used  DECIMAL(5, 2)  NULL ,
progress       CHAR(50)       NULL 
);
CREATE TABLE DrivingTests
(
test_num     INT       NOT NULL ,
client_id    CHAR(10)  NOT NULL ,
test_date    DATETIME  NOT NULL ,
seat_num     INT       NOT NULL ,
score        INT       NULL ,
test_notes   CHAR(255) NULL 
);

ALTER TABLE Clients ADD PRIMARY KEY (client_id);
ALTER TABLE Applications ADD PRIMARY KEY (application_id);
ALTER TABLE Instructors ADD PRIMARY KEY (instructor_id);
ALTER TABLE Offices ADD PRIMARY KEY (office_id);
ALTER TABLE Lessons ADD PRIMARY KEY (lesson_num);
ALTER TABLE DrivingTests ADD PRIMARY KEY (test_num);
ALTER TABLE Applications ADD CONSTRAINT FK_Applications_Offices FOREIGN KEY (office_id) REFERENCES Offices (office_id);
ALTER TABLE Applications ADD CONSTRAINT FK_Applications_Clients FOREIGN KEY (client_id) REFERENCES Clients (client_id);
ALTER TABLE Applications ADD CONSTRAINT FK_Applications_Instructors FOREIGN KEY (instructor_id) REFERENCES Instructors (instructor_id);
ALTER TABLE Applications ADD CONSTRAINT FK_Applications_Cars FOREIGN KEY (car_id) REFERENCES Cars (car_id);
ALTER TABLE Lessons ADD CONSTRAINT FK_Lessons_Clients FOREIGN KEY (client_id) REFERENCES Clients (client_id);
ALTER TABLE Cars ADD CONSTRAINT FK_Cars_Offices FOREIGN KEY (office_id) REFERENCES Offices (office_id);
ALTER TABLE Clients ADD CONSTRAINT FK_DrivingTests_Clients FOREIGN KEY (client_id) REFERENCES Clients (client_id);

我遇到的错误如下:

mysql> ALTER TABLE Applications ADD CONSTRAINT FK_Applications_Cars FOREIGN KEY
(car_id) REFERENCES Cars (car_id);
ERROR 1005 (HY000): Can't create table 'foo.#sql-12c_4' (errno: 150)

我运行了SHOW ENGINE INNODB STATUS,它给出了更详细的错误描述:

------------------------
LATEST FOREIGN KEY ERROR
------------------------
100509 20:59:49 Error in foreign key constraint of table foo/#sql-12c_4:
 FOREIGN KEY (car_id) REFERENCES Cars (car_id):
Cannot find an index in the referenced table where the
referenced columns appear as the first columns, or column types
in the table and the referenced table do not match for constraint.
Note that the internal storage type of ENUM and SET changed in
tables created with >= InnoDB-4.1.12, and such columns in old tables
cannot be referenced by such columns in new tables.
See http://dev.mysql.com/doc/refman/5.1/en/innodb-foreign-key-constraints.html
for correct foreign key definition.
------------

我在StackOverflow和其他网站上搜索了一下 - 在这里找到了一篇有用的博客文章,介绍了如何解决这个错误 - 但我无法弄清楚出了什么问题。任何帮助都将不胜感激!


请参见http://verysimple.com/2006/10/22/mysql-error-number-1005-cant-create-table-mydbsql-328_45frm-errno-150/。 - Benjamin Oakes
14个回答

41

你应该将 car_id 设为 cars 表的主键。


顺便提一下,如果你正在修改具有行的应用程序表并将car_id作为新的外键插入,则Applications.car_id应该可为空,否则您会遇到类似的错误。这就是我遇到的情况。 - cawecoy
在我的情况下,将参考键设为唯一的已足够,因为参考表中已经有一个主键。 - Spencer Williams

31

注意: 我曾经遇到相同的问题,原因是两个不同表中的引用字段有不同的排序规则(它们的类型完全一样)。

确保所有引用字段具有相同的类型和相同的排序规则!


2
+1 关于排序规则的信息。您知道为什么在数据类型相同时,排序规则会影响创建索引吗? - user325643
我认为这有点说得通,因为当我们使用不同的排序规则时,底层数据是不同的,而MySQL检查外键的一部分是确保数据完全相同...但我不知道官方原因 ;) - NickT
如果您的下一个问题是如何更改现有表的排序规则:https://dev59.com/p3RB5IYBdhLWcg3wCjcV - penfold

15

检查两个表是否具有相同的引擎(ENGINE)。例如,如果您有:

CREATE Table FOO ();

and:

->

并且:

CREATE Table BAR () ENGINE=INNODB;

如果您尝试从表BAR创建到表FOO的约束,它在某些MySQL版本上不起作用。

按照以下步骤解决问题:

CREATE Table FOO () ENGINE=INNODB;

使用InnoDB(https://jeremystein.com/journal/innodb-versus-myisam-no-comparison/) - Stack Underflow

12

虽然微不足道,但我因为忘记将一个 smallint 列声明为 unsigned 以匹配引用的现有表(它是“smallint unsigned”)而犯了错误。一个列为unsigned而另一个列不是unsigned会导致MySQL阻止在新表上创建外键。

id smallint(3) not null

为了外键的完整性,不匹配

id smallint(3) unsigned not null

这节省了我很多时间! - Anirudh Ramanathan

8

当我尝试以下操作时,遇到了这个毫无意义和信息量极低的错误:

ALTER TABLE `comments` ADD CONSTRAINT FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE SET NULL ON UPDATE CASCADE;

我的问题出在评论表中,user_id 被定义为:
`user_id` int(10) unsigned NOT NULL

所以……在我的情况下,问题出在 NOT NULL 和 ON DELETE SET NULL 之间的冲突上。

5
同时,这两个表需要具有相同的字符集。
例如:
CREATE TABLE1 (
  FIELD1 VARCHAR(100) NOT NULL PRIMARY KEY,
  FIELD2 VARCHAR(100) NOT NULL
)ENGINE=INNODB CHARACTER SET utf8 COLLATE utf8_bin;

to

CREATE TABLE2 (
  Field3 varchar(64) NOT NULL PRIMARY KEY,
  Field4 varchar(64) NOT NULL,
  CONSTRAINT FORIGEN KEY (Field3) REFERENCES TABLE1(FIELD1)
) ENGINE=InnoDB;

由于字符集不同,将失败。这是另一个微妙的失败,mysql 返回相同的错误。


同样的引擎也很重要。如果你从Linux导出一个带有MyISAM的转储文件,然后在Windows上导入它(保持MyISAM),那么在Windows上创建表可能会使用InnoDB,并且外键错误也会发生。 - Telmo Pimentel Mota

3

我使用Ubuntu Linux,在我的情况下,错误是由于不正确的语句语法引起的(我通过在终端键入perror 150找到了这一点,该命令会给出MySQL错误代码150:外键约束格式不正确)。

更改查询语句的语法后:

从原来的语法:

alter table scale add constraint foreign key (year_id) references year.id;

为了

alter table scale add constraint foreign key (year_id) references year(id);

已修复。


2

我也遇到了这个错误(对于几个表格),还有约束错误和MySQL在尝试导入整个数据库(~800 MB)时连接和断开连接。我的问题是由于 MySQL服务器 的最大允许数据包过低导致的。为了解决这个问题(在Mac上):

  • 打开 /private/etc/my.conf
  • # MySQL服务器 下,将 max_allowed_packet 从1M更改为4M(您可能需要尝试不同的值)
  • 重新启动MySQL

之后,数据库成功导入。

请注意,我正在运行 Mac OS X(x86 64位)的 MySQL 5.5.12。


2

所引用的字段必须是被引用表中的“关键字”,不一定是主键。因此,“car_id”应该是主键,或在“Cars”表中定义为NOT NULL和UNIQUE约束。

而且,两个字段必须是相同类型和排序规则。


1

已解决:

请确保主键和外键的数据类型完全匹配。 如果一个是有符号的,另一个是无符号的,将会失败。 良好的实践是确保两者都是无符号整数。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接