mysql外键约束

MySQL中的外键用于建立表间的关系,它是一种索引,确保数据的参照完整性。外键可以是一对一或一对多,使用时需确保两个表为InnoDB类型并对外键列建立索引。外键的好处在于关联表和保证数据一致性。创建外键的语法包括定义外键、引用表和设置ON DELETE和ON UPDATE的触发行为。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

-- 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  啥也不做

转自:http://www.cnblogs.com/xiangxiaodong/archive/2013/05/05/3061049.html





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值