我正在努力在数据库中创建一些表
foo
,但每次我最终都会得到关于外键的 errno 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 和其他地方在线搜索 - 在这里发现了一篇有用的博客文章,其中包含有关如何解决此错误的指示 - 但我无法弄清楚出了什么问题。任何帮助将不胜感激!
您应该将
car_id
作为汽车的主钥匙。
注意:我遇到了同样的问题,这是因为引用的字段在两个不同的表中采用不同的排序规则(它们具有完全相同的类型)。
确保所有引用的字段具有相同的类型和相同的排序规则!
检查两个表是否具有相同的引擎。例如,如果您有:
CREATE Table FOO ();
和:
CREATE Table BAR () ENGINE=INNODB;
如果您尝试创建从表 BAR 到表 FOO 的约束,它在某些 MySQL 版本上将不起作用。
通过以下方式修复问题:
CREATE Table FOO () ENGINE=INNODB;
很微妙,但是这个错误让我困扰,因为我忘记将一个smallint列声明为无符号以匹配引用的现有表“smallint unsigned”。一个未签名和一个未签名会导致 MySQL 阻止在新表上创建外键。
id smallint(3) not null
不匹配,为了外键,
id smallint(3) unsigned not null
当我尝试执行以下操作时,我得到了这个完全毫无价值且无信息的错误:
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 之间的冲突。
两个表还需要具有相同的字符集。
例如
CREATE TABLE1 (
FIELD1 VARCHAR(100) NOT NULL PRIMARY KEY,
FIELD2 VARCHAR(100) NOT NULL
)ENGINE=INNODB CHARACTER SET utf8 COLLATE utf8_bin;
到
CREATE TABLE2 (
Field3 varchar(64) NOT NULL PRIMARY KEY,
Field4 varchar(64) NOT NULL,
CONSTRAINT FORIGEN KEY (Field3) REFERENCES TABLE1(FIELD1)
) ENGINE=InnoDB;
会失败,因为它们具有不同的字符集。这是另一个微妙的失败,mysql 返回相同的错误。
我使用 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);
修好了。
引用的字段必须是引用表中的“键”,不一定是主键。因此,“car_id”应该是主键,或者在“Cars”表中使用 NOT NULL 和 UNIQUE 约束进行定义。
此外,两个字段必须具有相同的类型和排序规则。
在尝试导入整个数据库(~800 MB)时,我还收到了此错误(针对多个表)以及约束错误和 MySQL 连接和断开连接。我的问题是由于MySQL 服务器允许的最大数据包数太低造成的。要解决此问题(在 Mac 上):
max_allowed_packet
从 1M 更改为 4M(您可能需要尝试使用此值。)数据库导入成功。
注意我正在运行适用于 Mac OS X(x86 64 位)的 MySQL 5.5.12。
检查使您引用的字段与外键完全匹配,在我的情况下,一个未签名,另一个已签名,所以我只是将它们更改为匹配,这有效
更改表客户信息 添加约束 fk_customer_information1 外键 (
user_id
)
参考文献 users
(id
)
删除级联时
关于更新级联
已解决:
检查确保Primary_Key和Foreign_Key与数据类型完全匹配。 如果一个已签名,另一个未签名,则失败。 好的做法是确保两者都是 unsigned int。
我使用了重复的外键名称。
重命名 FK 名称解决了我的问题。
澄清:
两个表都有一个名为 PK1、FK1 等的约束。重命名它们/使名称唯一解决了问题。
引用的列必须是单列索引或多列索引中的第一列,且类型相同、排序规则相同。
我的两个表有不同的排序规则。可以通过发出 show table status (如
table_name
) 来显示它,并且可以通过发出 alter table table_name
转换为字符集 utf8 来更改排序规则。
所有,我解决了一个问题并想分享它:
我遇到了这个错误<> 问题在于我的声明中:
更改表system_registro_de_modificacion添加外键 (usuariomodificador_id) 参考 Usuario(id) 删除限制;
我错误地编写了大小写:它在 Windows WAMP 中工作,但在 Linux MySQL 中,它对大小写更严格,因此编写“Usuario”而不是“usuario”(精确大小写),生成了错误,并且只需更改即可更正外壳。