在Mysql中创建外键时,经常会遇到问题而失败,这是因为Mysql中还有很多细节需要我们去留意,我自己总结并查阅资料后列出了以下几种常见原因。
1. 两个字段的类型或者大小不严格匹配。例如,如果一个是int(10),那么外键也必须设置成int(10),而不是int(11),也不能是tinyint。另外,你还必须确定两个字段是否一个为 signed,而另一个又是unsigned(即:无符号),这两字段必须严格地一致匹配,更多关于signed和unsigned的信息,
2. 试图设置外键的字段没有建立起索引,或者不是一个primary key(主键)。如果其中一个不是primary key的话,你必须先为它创建一个索引。
3. 其中一个或者两个表是MyISAM引擎的表。若想要使用外键约束,表必须是InnoDB引擎(实际上,如果两个表都是MyISAM 引擎的,这个错误根本不会发生,但也不会产生外键,只会建立索引)你需要检查表的引擎类型。
4. 外键的名字不能重复。你应该检查你的数据库以确保外健名字是唯一的,或者你在键名后面加上几个随机的字符以测试是否是这个原因。
5. 你可能设置了ON DELETE SET NULL,但是相关的键的字段又设置成了NOTS NULL值。你可能通过修改cascade的属性值或者把字段属性设置成allow null来解决。
6. 请确定你的Charset和Collate选项在表级和字段级上的一致。
7. 你可能设置为外键设置了一个默认值,如default=0。
8. ALTER声明中有语法错误
9.给表添加外键依赖时要么表中都没有数据,要么数据要符合依赖。如果A表和B表中已经有了数据,现在在A表中添加一个字段bid,bid参照B表的主键id,添加外键时添加不了,因为向A表添加字段后,A表中的每条记录的这个字段的值不一定能在B表中找到相应的记录。如
mp_album中添加一个字段photoid后,每条记录的此字段的值全部变为0了,现在给表mp_album中添加外键photoid参照mp_photo表中的id,此时mp_photo表中已经有1条数据了,mp_photo中的id值是从1开始增加的,要添加外键成功必须将mp_album表中photoid字段的值设为1才可以,否则会报错Cannot add or update a child row。
--
-- 表的结构 `mp_album`
--
CREATE TABLE IF NOT EXISTS `mp_album` (
`albumid` int(11) unsigned NOT NULL COMMENT '编号',
`name` varchar(60) DEFAULT NULL COMMENT '相册名',
`des` varchar(512) DEFAULT NULL COMMENT '描述',
`location` varchar(120) DEFAULT NULL COMMENT '地点',
`music` varchar(600) DEFAULT NULL COMMENT '音乐插件',
`status` tinyint(5) NOT NULL DEFAULT '1' COMMENT '状态',
`userid` int(11) unsigned NOT NULL COMMENT '用户编号',
`photoid` int(11) unsigned DEFAULT NULL COMMENT '主图片id'
) ENGINE=InnoDB AUTO_INCREMENT=77 DEFAULT CHARSET=utf8 COMMENT='相册表';
--
-- 转存表中的数据 `mp_album`
--
INSERT INTO `mp_album` (`albumid`, `name`, `des`, `location`, `music`, `status`, `userid`, `photoid`) VALUES
(2, 'q', 'q', 'q', 'q', 1, 1, 0),
(3, 'q', 'q', 'q', 'q', 1, 1, 0),
(4, 'q', 'q', 'q', 'q', 1, 1, 0),
(5, 'q', 'q', 'q', 'q', 1, 1, 0)
--
-- 表的结构 `mp_photo`
--
CREATE TABLE IF NOT EXISTS `mp_photo` (
`photoid` int(11) unsigned NOT NULL COMMENT '照片编号',
`name` varchar(100) NOT NULL COMMENT '照片名字',
`addtime` date NOT NULL COMMENT '添加时间',
`des` varchar(600) DEFAULT NULL COMMENT '描述',
`albumid` int(11) unsigned NOT NULL COMMENT '相册编号',
`width` smallint(4) unsigned NOT NULL COMMENT '宽度',
`height` smallint(4) unsigned NOT NULL COMMENT '高度'
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
--
-- 转存表中的数据 `mp_photo`
--
INSERT INTO `mp_photo` (`photoid`, `name`, `addtime`, `des`, `albumid`, `width`, `height`) VALUES
(1, '1', '2015-05-17', 'aaaaaaaaaaaaaaaaaaaa', 2, 10, 30);
ALTER TABLE `mp_album` ADD CONSTRAINT `photoid` FOREIGN KEY (`photoid`) REFERENCES `mp_photo` (`photoid`) ON DELETE set null