-- drop table p_table;
-- drop table c_table;
CREATE TABLE p_table ( -- 父表
id int(11) NOT NULL auto_increment,
p_name varchar(20) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB char set = utf8 ;
CREATE TABLE `c_table` ( -- 子表
`id` int(11) NOT NULL auto_increment,
`c_name` varchar(20) DEFAULT NULL,
`p_id` int(11) NOT NULL ,
PRIMARY KEY (`id`),
foreign key fkeyName(p_id) references p_table(id)
) ENGINE=InnoDB char set = utf8 ;
insert into p_table(p_name) values('张1');
insert into p_table(p_name) values('张2');
insert into p_table(p_name) values('张3');
select * from p_table ; -- 3条记录
1 张1
2 张2
3 张3
insert into c_table(c_name,p_id) values('子1',1); -- 成功
insert into c_table(c_name,p_id) values('子2',2); -- 成功
select * from c_table ;-- 2条记录
1 子1 1
2 子2 2
insert into c_table(c_name,p_id) values('子5',5); -- 失败,父表中id=5不存在
[Err] 1452 - Cannot add or update a child row: a foreign key constraint fails (`db_test`.`c_table`, CONSTRAINT `c_table_ibfk_1` FOREIGN KEY (`p_id`) REFERENCES `p_table` (`id`))
-- 删除或修改已存在外键约束的父表中的记录会失败
update p_table set id = 5 where id = 1; -- 失败,父表中id=1已存在外键约束
[Err] 1451 - Cannot delete or update a parent row: a foreign key constraint fails (`db_test`.`c_table`, CONSTRAINT `c_table_ibfk_1` FOREIGN KEY (`p_id`) REFERENCES `p_table` (`id`))
delete from p_table where id = 1;-- 失败,父表中id=1已存在外键约束
[Err] 1451 - Cannot delete or update a parent row: a foreign key constraint fails (`db_test`.`c_table`, CONSTRAINT `c_table_ibfk_1` FOREIGN KEY (`p_id`) REFERENCES `p_table` (`id`))
-- 先删除子表的记录,再删除对应外键的父表的记录就能成功
delete from c_table where id = 1;
select * from c_table ;-- 1条记录
2 子2 2
delete from p_table where id = 1;-- 成功
select * from p_table ; -- 2条记录
2 张2
3 张3
------------增加级联操作-------------
CREATE TABLE `c_table` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`c_name` varchar(20) DEFAULT NULL,
`p_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `fkeyName` (`p_id`),
CONSTRAINT `c_table_ibfk_1` FOREIGN KEY (`p_id`) REFERENCES `p_table` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
alter table c_table drop foreign key c_table_ibfk_1 ; -- 删除外键约束
CREATE TABLE `c_table` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`c_name` varchar(20) DEFAULT NULL,
`p_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `fkeyName` (`p_id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
alter table c_table -- 添加外键,带级联操作
add constraint id_check
foreign key(p_id)
references p_table(id)
on delete cascade
on update cascade;
CREATE TABLE `c_table` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`c_name` varchar(20) DEFAULT NULL,
`p_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `id_check` (`p_id`),
CONSTRAINT `id_check` FOREIGN KEY (`p_id`) REFERENCES `p_table` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;
delete from p_table ;
delete from c_table ;
insert into p_table(p_name) values('张1');
insert into p_table(p_name) values('张2');
insert into p_table(p_name) values('张3');
select * from p_table ; -- 3条记录
4 张1
5 张2
6 张3
insert into c_table(c_name,p_id) values('子1',1); -- 失败,父表中不存在id=1的记录
[Err] 1452 - Cannot add or update a child row: a foreign key constraint fails (`db_test`.`c_table`, CONSTRAINT `id_check` FOREIGN KEY (`p_id`) REFERENCES `p_table` (`id`) ON DELETE CASCADE ON UPDATE CASCADE)
insert into c_table(c_name,p_id) values('子1',4);
insert into c_table(c_name,p_id) values('子1',5);
select * from c_table
6 子1 4
7 子1 5
update p_table set id = 10 where id = 5; -- 父表中的id修改后,字表中的的父表id也会修改
select * from p_table ; -- 3条记录
4 张1
6 张3
10 张2
select * from c_table;
6 子1 4
7 子1 10
delete from p_table where id = 10;-- 父表中删除该id的记录后,字表中对应id的记录也会删除
select * from p_table ;
4 张1
6 张3
select * from c_table;
6 子1 4
以上为原创
一、基本概念
1、MySQL中“键”和“索引”的定义相同,所以外键和主键一样也是索引的一种。不同的是MySQL会自动为所有表的主键进行索引,但是外键字段必须由用户进行明确的索引。用于外键关系的字段必须在所有的参照表中进行明确地索引,InnoDB不能自动地创建索引。
2、外键可以是一对一的,一个表的记录只能与另一个表的一条记录连接,或者是一对多的,一个表的记录与另一个表的多条记录连接。
3、如果需要更好的性能,并且不需要完整性检查,可以选择使用MyISAM表类型,如果想要在MySQL中根据参照完整性来建立表并且希望在此基础上保持良好的性能,最好选择表结构为innoDB类型。
4、外键的使用条件
① 两个表必须是InnoDB表,MyISAM表暂时不支持外键
② 外键列必须建立了索引,MySQL 4.1.2以后的版本在建立外键时会自动创建索引,但如果在较早的版本则需要显式建立;
③ 外键关系的两个表的列必须是数据类型相似,也就是可以相互转换类型的列,比如int和tinyint可以,而int和char则不可以;
5、外键的好处:可以使得两张表关联,保证数据的一致性和实现一些级联操作。
二、使用方法
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(无动作,默认的)
转自:https://www.2cto.com/database/201501/367791.html
关键字
含义
CASCADE 删除包含与已删除键值有参照关系的所有记录
SET NULL 修改包含与已删除键值有参照关系的所有记录,使用NULL值替换(只能用于已标记为NOT NULL的字段)
RESTRICT 拒绝删除要求,直到使用删除键值的辅助表被手工删除,并且没有参照时(这是默认设置,也是最安全的设置)
NO ACTION 啥也不做