您的位置:首页 > 数据库 > MySQL

mysql外键约束

2017-09-16 13:54 204 查看
-- 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(无动作,默认的)

转自:http://www.cnblogs.com/xiangxiaodong/archive/2013/05/05/3061049.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  mysql 外键 约束