MySQL报错1005:无法创建`music`.`track`表(外键约束错误)已多次排查求因
music.track表时外键约束错误(errno:150)的常见根源 哈哈,这个errno:150的外键错误我简直见得太多了!别着急,我给你列几个最常见的问题根源,你挨个排查肯定能解决:
关联字段的数据类型必须完全一致:这是踩坑最多的点!比如你track表的外键
album_id是INT,但主表album的主键是INT UNSIGNED,哪怕都是整数,只要带不带unsigned、长度(比如INT(10)和INT(11))不一样,MySQL就会直接报错。如果是字符串类型,字符集、排序规则也得完全匹配,比如utf8和utf8mb4绝对不能混着来。主表的关联字段必须是主键或唯一索引:外键必须关联到主表的
PRIMARY KEY或者带有UNIQUE约束的字段上。如果主表的那个字段只是普通索引,没有唯一性保证,MySQL会拒绝创建外键——毕竟外键要确保关联的记录是唯一存在的。主表和子表的存储引擎要一致:MyISAM引擎根本不支持外键约束!如果你的主表用的是InnoDB,而track表不小心选了MyISAM,肯定会报错。现在基本都用InnoDB,确保两个表的引擎都是它就好。
别写错主表或字段名:有时候手滑打错了主表名(比如把
albums写成album)或者字段名(把album_id写成alb_id),MySQL找不到对应的关联对象,也会抛出这个错误。仔细核对一遍拼写!外键约束名称重复:虽然少见,但如果数据库里已经存在一个同名的外键约束了,创建也会失败。可以给外键指定一个唯一的名字,比如
FK_track_album_id,避免冲突。主表中存在不符合约束的现有数据:如果是先创建了track表,后来再加外键,但track表里已经有一些
album_id值在主表中不存在,这时候加外键会失败——因为违反了“外键必须对应主表存在的记录”的规则。这种情况要么清理track表中的无效数据,要么暂时关闭外键检查(执行SET FOREIGN_KEY_CHECKS=0;,操作完记得再开回来SET FOREIGN_KEY_CHECKS=1;)。
举个正确的示例参考,比如先创建主表album:
CREATE TABLE `music`.`album` ( `album_id` INT UNSIGNED NOT NULL AUTO_INCREMENT, `title` VARCHAR(255) NOT NULL, PRIMARY KEY (`album_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
再创建track表,确保所有外键条件都满足:
CREATE TABLE `music`.`track` ( `track_id` INT UNSIGNED NOT NULL AUTO_INCREMENT, `album_id` INT UNSIGNED NOT NULL, `title` VARCHAR(255) NOT NULL, PRIMARY KEY (`track_id`), CONSTRAINT `FK_track_album_id` FOREIGN KEY (`album_id`) REFERENCES `music`.`album` (`album_id`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
内容的提问来源于stack exchange,提问作者scoffieldisxu

