今天往MySQL的一张表里插记录时,出现一个错误提示:
ERROR 1452 : Cannot add or update a child row: a foreign key constraint fails。。。。
仔细观察后才发现该表中有一字段是外键,它参照了另外一张表的主键。
出现错误的原因是:插入外键的数据在另一张表的主键中不存在。
解决方法当然,很简单了,插入另一张表中主键存在的数据呗。。。。。
下面我们来一起探讨一下MySQL的外键吧。。。
一、参照完整性
1。参照完整性规则:
上面这就是参照完整性的定义,说明了一个表中的外键的取值只有两种可能,要么为空,要么只能是它参照的表的主键的值。
因为现实世界中的实体之间往往存在某种联系,在关系模型中实体及实体间的联系都是用关系来描述的。这样就自然存在着关系与关系间的引用啊。当数据库中的一个表与一个或多个表进行关联时都会涉及到参照完整性,这样可以保证数据的一致性和实现一些级联操作。
二、建立MySQL外键关系的前提条件
为了建立两个MySQL表之间的一个外键关系,必须满足以下三种情况:
三、外键的定义:
外键的定义语法:
[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(无动作,默认的)
举例:建表
新建一个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的外键,用来为删除外键定义用的,如下所示:
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;
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
就可以看到外键别名pc_ibfk_1 然后,就可以执行以下命令删除外键定义:
mysql> ALTER TABLE pc DROP FOREIGN KEY pc_ibfk_1;
Query OK, 1 row affected (0.66 sec)
Records: 1 Duplicates: 0 Warnings: 0