MySQL外键约束_ON DELETE CASCADE/ON UPDATE CASCADE
MySQL通过外键约束实现数据库的参照完整性,外键约束条件可在创建外键时指定,table的存储引擎只能是InnoDB,因为只有这种存储模式才支持外键。
外键约束条件有以下4种:
(1)restrict方式:同no action,都是立即检查外键约束;
- - 限制,指的是如果子表引用父表的某个字段的值,那么不允许直接删除父表的该值。
(2)cascade方式:在父表上update/delete记录时,同步update/delete子表的匹配记录 ;
On delete cascade从mysql3.23.50开始可用,on update cascade从mysql4.0.8开始可用 ;
-- 级联,删除/更新父表的某条记录,子表中引用该值的记录会自动被删除/更新。
(3)No action方式:如果子表中有匹配的记录,则不允许对父表对应候选键进行update/delete操作 这个是ANSI SQL-92标准,从mysql4.0.8开始支持;
--无参照完整性关系,有了也不生效。
(4)set null方式:在父表上update/delete记录时,将子表上匹配记录的列设为null 要注意子表的外键列不能为not null
On delete set null从mysql3.23.50开始可用;,on update set null从mysql4.0.8开始可用 。
首先创建一个用户表,并插入两条记录:
mysql> create table t_group
-> (id int auto_increment primary key,
-> name varchar())
-> engine=InnoDB;
Query OK, rows affected (0.08 sec) mysql> insert into t_group values (,'Group_1'),(,'Group_2');
Query OK, rows affected (0.04 sec)
Records: Duplicates: Warnings: mysql> select * from t_group;
+----+---------+
| id | name |
+----+---------+
| | Group_1 |
| | Group_2 |
+----+---------+
rows in set (0.00 sec)
1.级联方式
创建级联子表:
mysql> create table t_user
-> (id int not null primary key,
-> name varchar(),groupid int,
-> foreign key(groupid) references t_group(id)
-> on delete cascade on update cascade)
-> engine=InnoDB;
Query OK, rows affected (0.08 sec)
完整性约束测试,以下例子都省略完整性测试:
mysql> insert into t_user values (1,'dayu',1),(2,'duoduo',2);
Query OK, 2 rows affected (0.08 sec)
Records: 2 Duplicates: 0 Warnings: 0 mysql> insert into t_user values (1,'huanhuan',1); //实体完整性测试,不能插入重复主键值
ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'
mysql> insert into t_user values (3,'maiqi',3); //参照完整性测试,不能插入在主表中不存在的外键值
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`test`.`t_user`, CONSTRAINT `t_user_ibfk_1` FOREIGN KEY (`groupid`) REFERENCES `t_group` (`id`) ON DELETE CASCADE ON UPDATE CASCADE)
级联测试:
mysql> select * from t_user;
+----+--------+---------+
| id | name | groupid |
+----+--------+---------+
| 1 | dayu | 1 |
| 2 | duoduo | 2 |
+----+--------+---------+
2 rows in set (0.00 sec) mysql> update t_group set id=3 where id=2; //从主表中更新一个记录
Query OK, 1 row affected (0.02 sec)
Rows matched: 1 Changed: 1 Warnings: 0 mysql> select * from t_user; /改变主表数据,从表数据随着更新
+----+--------+---------+
| id | name | groupid |
+----+--------+---------+
| 1 | dayu | 1 |
| 2 | duoduo | 3 |
+----+--------+---------+
2 rows in set (0.00 sec)
mysql> select * from t_user;
+----+--------+---------+
| id | name | groupid |
+----+--------+---------+
| 1 | dayu | 1 |
| 2 | duoduo | 3 |
+----+--------+---------+
2 rows in set (0.00 sec) mysql> delete from t_group where id=3; //从主表中删除一个记录
Query OK, 1 row affected (0.03 sec) mysql> select * from t_user; //子表中对应的记录自动被删除
+----+------+---------+
| id | name | groupid |
+----+------+---------+
| 1 | dayu | 1 |
+----+------+---------+
1 row in set (0.00 sec)
2.置空模式(set null,主表记录被删除,从表中对应的值设置为NULL)
首先创建一个子表:
mysql> select * from t_group;
+----+---------+
| id | name |
+----+---------+
| 1 | Group_1 |
| 2 | Group_2 |
+----+---------+
2 rows in set (0.00 sec)
mysql> create table t_user_1
-> (id int not null primary key,
-> name char(10),groupid int,
-> foreign key(groupid) references t_group(id)
-> on delete set null on update set null)
-> engine=InnoDB;
Query OK, 0 rows affected (0.11 sec) mysql> insert into t_user_1 values (1,'dayu',1),(2,'duoduo',2),(3,'huanhuan',2),(4,'maiqi',1);
Query OK, 4 rows affected (0.02 sec)
Records: 4 Duplicates: 0 Warnings: 0 mysql> select * from t_user_1;
+----+----------+---------+
| id | name | groupid |
+----+----------+---------+
| 1 | dayu | 1 |
| 2 | duoduo | 2 |
| 3 | huanhuan | 2 |
| 4 | maiqi | 1 |
+----+----------+---------+
4 rows in set (0.00 sec)
mysql> update t_group set id=3 where id=1;
Query OK, 1 row affected (0.03 sec)
Rows matched: 1 Changed: 1 Warnings: 0 mysql> select * from t_user_1;
+----+----------+---------+
| id | name | groupid |
+----+----------+---------+
| 1 | dayu | NULL |
| 2 | duoduo | 2 |
| 3 | huanhuan | 2 |
| 4 | maiqi | NULL |
+----+----------+---------+
4 rows in set (0.00 sec) mysql> delete from t_group where id=2; //从主表中删除一个记录
Query OK, 1 row affected (0.01 sec) mysql> select * from t_user_1; //子表中对应的属性值被自动设置为NULL
+----+----------+---------+
| id | name | groupid |
+----+----------+---------+
| 1 | dayu | NULL |
| 2 | duoduo | NULL |
| 3 | huanhuan | NULL |
| 4 | maiqi | NULL |
+----+----------+---------+
4 rows in set (0.00 sec)
3.禁止模式(no action/restrict),如果在子表中有引用,则不允许在主表中进行更新或删除
首先创建一个子表:
mysql> select * from t_group;
+----+---------+
| id | name |
+----+---------+
| 1 | Group_1 |
| 2 | Group_2 |
+----+---------+
2 rows in set (0.00 sec) mysql> create table t_user_2
-> (id int not null primary key,
-> name char(10),groupid int,
-> foreign key(groupid) references t_group(id)
-> on delete no action on update restrict)
-> engine=InnoDB;
Query OK, 0 rows affected (0.11 sec) mysql> insert into t_user_2 values (1,'dayu',1),(2,'duoduo',2),(3,'huanhuan',2),(4,'maiqi',1);
Query OK, 4 rows affected (0.02 sec)
Records: 4 Duplicates: 0 Warnings: 0 mysql> select * from t_user_2;
+----+----------+---------+
| id | name | groupid |
+----+----------+---------+
| 1 | dayu | 1 |
| 2 | duoduo | 2 |
| 3 | huanhuan | 2 |
| 4 | maiqi | 1 |
+----+----------+---------+
4 rows in set (0.00 sec)
mysql> update t_group set id= where id=;
ERROR (): Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t_user_2`, CONSTRAINT `t_user_2_ibfk_1` FOREIGN KEY (`groupid`) REFERENCES `t_group` (`id`) ON DELETE NO ACTION)
mysql> delete from t_group where id=;
ERROR (): Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t_user_2`, CONSTRAINT `t_user_2_ibfk_1` FOREIGN KEY (`groupid`) REFERENCES `t_group` (`id`) ON DELETE NO ACTION)
4.主从表的删除
删除从表没有限制,如下:
mysql> drop table t_user_2;
Query OK, rows affected (0.01 sec)
如果存在引用的从表,则主要不能随意删除:
mysql> drop table t_group;
ERROR (): Cannot delete or update a parent row: a foreign key constraint fails
经过以上测试,了解到MySQL通过外键约束实现了数据的完整性与一致性。
MySQL外键约束_ON DELETE CASCADE/ON UPDATE CASCADE的更多相关文章
- MySQL外键约束On Delete、On Update各取值的含义
主键.外键和索引的区别? 主键 外键 索引 定义: 唯一标识一条记录,不能有重复的,不允许为空 表的外键是另一表的主键, 外键可以有重复的, 可以是空值 主索引(由关键字PRIMARY定义的索引) ...
- MySQL外键约束On Delete和On Update的使用
On Delete和On Update都有Restrict,No Action, Cascade,Set Null属性.现在分别对他们的属性含义做个解释. ON DELETE restrict(约束) ...
- 【转】MySQL外键约束On Delete、On Update各取值的含义
转载地址:http://hi.baidu.com/jxqlovejava/item/3d2cc5b5d689917c244b0920 先看On Delete属性,可能取值如上图为:No Actio ...
- MySql 外键约束 之CASCADE、SET NULL、RESTRICT、NO ACTION分析和作用
MySQL有两种常用的引擎类型:MyISAM和InnoDB.目前只有InnoDB引擎类型支持外键约束.InnoDB中外键约束定义的语法如下: ALTER TABLE tbl_name ADD [CON ...
- 1、Mysql无法创建外键的原因 2、MySql 外键约束 之CASCADE、SET NULL、RESTRICT、NO ACTION分析和作用
在Mysql中创建外键时,经常会遇到问题而失败,这是因为Mysql中还有很多细节需要我们去留意,我自己总结并查阅资料后列出了以下几种常见原因. 1. 两个字段的类型或者大小不严格匹配.例如,如果一个 ...
- Mysql外键约束设置使用方法
如果表A的主关键字是表B中的字段,则该字段称为表B的外键,表A称为主表,表B称为从表.外键是用来实现参照完整性的,不同的外键约束方式将可以使两张表紧密的结合起来,特别是修改或者删除的级联操作将使得日常 ...
- mysql外键约束总结
总结三种MySQL外键约束方式 如果表A的主关键字是表B中的字段,则该字段称为表B的外键,表A称为主表,表B称为从表.外键是用来实现参照完整性的,不同的外键约束方式将可以使两张表紧密的结合起来,特别是 ...
- mysql 外键约束备注
梳理mysql外键约束的知识点. 1.mysql外键约束只对InnoDb引擎有效: 2.创建外键约束如下: DROP TABLE IF EXISTS t_demo_product; CREATE TA ...
- Mysql外键约束之CASCADE、SET NULL、RESTRICT、NO ACTION
Mysql中有目前只有InnoDB引擎支持外键约束,InnoDB中外键约束定义的语法如下: ALTER TABLE tbl_name ADD [CONSTRAINT [symbol]] FOREIGN ...
随机推荐
- Docker-堆栈stack(6)
堆栈(Stack)的概念: 堆栈是一组相互关联的服务,它们共享依赖关系,并且可以协调和缩放在一起.单个堆栈能够定义和协调整个应用程序的功能,但是非常复杂的应用程序可能希望使用多个堆栈. 下面我们就开始 ...
- 关于ping地址的几个意义
1.ping 127.0.0.1 判断电脑的tcp/ip协议栈有没有问题 2.ping 本机ip 判断电脑的网卡驱动有没有问题 3.ping 网关 判断数据是否可以到达路由 4.ping www.ba ...
- IDEA-各模块间引用出现问题的解决方法
1 点击项目右上角的Project Structure 2 选择Modules->父项目->点击右上角的加号->添加需要依赖的模块
- 【MyBatis学习06】_parameter:解决There is no getter for property named in class java.lang.String
我们知道在mybatis的映射中传参数,只能传入一个.通过#{参数名} 即可获取传入的值. Mapper接口文件: public int delete(int id) throws Exception ...
- 深度解剖session运行原理
已经大半年没有更新博客了,一方面有比博客更重要的事情要做,另外一方面也没有时间来整理知识,所以希望在接下来的日子里面能够多多的写博客来与大家交流 什么是session session的官方定义是:Se ...
- iowait
https://www.cnblogs.com/fuyuanming/articles/6497005.html
- Spring Boot Starter 的基本封装
1)spring-boot-starter这是Spring Boot的核心启动器,包含了自动配置.日志和YAML. 2)spring-boot-starter-amqp通过spring-rabbit来 ...
- nuxt跨域
根据nuxt官方文档提供的axios module 安装: npm install @nuxtjs/axios @nuxtjs/proxy --save nuxt.config.js modules: ...
- O - Muddy Fields
来源poj2226 Rain has pummeled the cows' field, a rectangular grid of R rows and C columns (1 <= R & ...
- linux的基本操作(文件压缩与打包)
文件的压缩与打包 在windows下我们接触最多的压缩文件就是.rar格式的了.但在linux下这样的格式是不能识别的,它有自己所特有的压缩工具.但有一种文件在windows和linux下都能使用那就 ...