????? 今天往MySQL的一张表里插记录时,出现一个错误提示:
ERROR?1452?:?Cannot?add?or?update?a?child?row:?a?foreign?key?constraint?fails。。。。?
????? 仔细观察后才发现该表中有一字段是外键,它参照了另外一张表的主键。 出现错误的原因是:插入外键的数据在另一张表的主键中不存在。 ????解决方法当然,很简单了,插入另一张表中主键存在的数据呗。。。。。 ? ??? 下面我们来一起探讨一下MySQL的外键吧。。。 ? 一、参照完整性 ?? 1。参照完整性规则: ?????????? ?
?
?
???? 因为现实世界中的实体之间往往存在某种联系,在关系模型中实体及实体间的联系都是用关系来描述的。这样就自然存在着关系与关系间的引用啊。当数据库中的一个表与一个或多个表进行关联时都会涉及到参照完整性,这样可以保证数据的一致性和实现一些级联操作。
?
二、建立MySQL外键关系的前提条件
???? 为了建立两个MySQL表之间的一个外键关系,必须满足以下三种情况:? ??
- ??*?两个表必须是InnoDB表类型。???
- ??*?使用在外键关系的域必须为索引型(Index)。????????
- ??*?使用在外键关系的域必须与数据类型相似。?
三、外键的定义:
外键的定义语法: ? 举例:建表 ? ????? 新建一个parts的表,cpu字段用来存放所有的cpu配件型号,再新建一个pc的表,其中的cpumodel字段用来存放pc机中的cpu型号,显然,cpumodel字段中的所有记录应该存在于parts表中。? ?? mysql>?create?table?parts(? ?? ????->?cpu?varchar(20)?not?null primary key,? ?? ????->?index(cpu)? ?? ????->?)engine=innodb;? ?? Query?OK,?0?rows?affected?(0.01?sec)? ?? ?? mysql>?create?table?pc(? ?? ????->?cpumodel?varchar(20)?not?null,? ?? ????->?index(cpumodel),? ?? ????->?constraint fk_pc? foreign?key(cpumodel)?references?parts(cpu)? ?? ????->?)engine=innodb;? ?? Query?OK,?0?rows?affected?(0.01?sec)? ?? ?? 注意:对于非InnoDB表,?FOREIGN?KEY?语句将被忽略。对parts表添加数据1,2,3,接着对pc表进行测试,满足条件的?1?可以顺利insert进去,而不符合条件的字符?5?在insert表的时候,出现外键约束性错误,这正是我们想要的结果? ?? ?? ?? mysql>?insert?into?parts?values('1'),('2'),('3');? ?? Query?OK,?3?rows?affected?(0.00?sec)? ?? Records:?3??Duplicates:?0??Warnings:?0? ?? ?? mysql>?insert?into?pc?values('1');? ?? Query?OK,?1?row?affected?(0.01?sec)? ?? ?? ?? mysql>?insert?into?pc?values('5');???? ? ERROR?1452?(23000):?Cannot?add?or?update?a?child?row:?a?foreign? ?? key?constraint?fails?(`Orange/pc`,?CONSTRAINT?`pc_ibfk_1`?FOREIGN?KEY? ?? (`cpumodel`)?REFERENCES?`parts`?(`cpu`))??? ? 四、外键的删除 ? 这个fk_pc就是表pc的外键,用来为删除外键定义用的,如下所示: ? CREATE TABLE `pc` ( ? 就可以看到外键别名pc_ibfk_1? 然后,就可以执行以下命令删除外键定义: ? ?
[CONSTRAINT symbol] FOREIGN KEY [id] (index_col_name, ...)
??? REFERENCES tbl_name (index_col_name, ...)
??? [ON DELETE {RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT}]
??? [ON UPDATE {RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT}]
????? 该语法可以在 CREATE TABLE 和 ALTER TABLE 时使用,如果不指定CONSTRAINT symbol,MYSQL会自动生成一个名字。
ON DELETE、ON UPDATE表示事件触发限制,可设参数:
RESTRICT(限制外表中的外键改动)
CASCADE(跟随外键改动)
SET NULL(设空值)
SET DEFAULT(设默认值)
NO ACTION(无动作,默认的)
mysql> ALTER TABLE?pc DROP FOREIGN KEY fk_pc;
Query OK, 1 row affected (0.25 sec)
Records: 1 Duplicates: 0 Warnings: 0
这样pc.cpumodel外键定义就被删除了,但是如果定义时没有指定CONSTRAINT fk_pc (即外键符号)时该怎么删除呢?别急,没有指定时,MySQL会自己创建一个,可以通过以下命令查看:
mysql> show create table pc;
? `cpumodel` varchar(20) NOT NULL,
? KEY `cpumodel` (`cpumodel`),
? CONSTRAINT `pc_ibfk_1` FOREIGN KEY (`cpumodel`) REFERENCES `parts` (`cpu`) ON DELETE CASCADE ON UPDATE CASCADE) ENGINE=InnoDB DEFAULT CHARSET=latin1
mysql> ALTER TABLE?? pc? DROP FOREIGN KEY pc_ibfk_1;
Query OK, 1 row affected (0.66 sec)
Records: 1 Duplicates: 0 Warnings: 0