级联数据库操作语句
级联查询前面已经介绍过了,因为查询是数据库操作中使用最多的操作,级联查询是比较复杂的,而且涉及到性能问题。这篇笔记记录如何实现级联更新和删除。
是否有级联插入呢?虽然不常见,实际上却可能有这样的需求,但级联插入建议使用触发器实现。有关触发器,将在具体数据库的相关章节介绍。至于级联更新和级联删除,实在是太常用了。复杂的级联更新,删除也可以使用触发器,但下面我们介绍一个更简单常用的方法,建表时指定外键的级联操作。
一个例子
我们这里以MySQL语法进行介绍,举一个最简单的使用场景例子。
我们有一个老师表t_teacher,学生表t_student,学生持有老师ID的外键,因此这是一个典型的一对多关系。
create table t_teacher(
teacher_id bigint primary key,
teacher_name varchar(20)
);
create table t_student(
student_id bigint primary key,
student_name varchar(20),
teacher_id bigint not null,
foreign key (teacher_id) references t_teacher (teacher_id)
);
我们插入几条测试数据:
insert into t_teacher values (1, "Tom");
insert into t_teacher values (2, "Bob");
insert into t_student values (1, "Kate", 1);
insert into t_student values (2, "Tim", 1);
insert into t_student values (3, "Lucy", 2);
级联删除
现在我们想实现,删除名字为“Tom”的老师,就把他关联的学生全部删除。
较差的实现方式:
- 查询
teacher_name="Tom"的老师,得到其teacher_id - 从
t_student中删除teacher_id为1的所有学生 - 从
t_teacher中删除teacher_id为1的老师
这种操作就比较麻烦了,如果是使用Java操作数据库,不仅要编写好几条SQL语句,还要多执行一次查询操作
较好的解决办法:
定义外键时这样写:
foreign key (teacher_id) references t_teacher (teacher_id) on delete cascade
on delete cascade代表t_teacher中某个数据项删除时,其关联的t_student表中的数据也会级联删除。如果你已经建好表了,也可以使用alter table语句修改外键。
现在我们试验一下,删除之前是这样的:

执行删除语句:
delete from t_teacher where teacher_name="Tom";
删除之后:

这确实是我们想要的结果。
级联更新
级联更新,举个例子就是修改t_teacher的主键,t_student的外键值也跟着更改。级联更新不太常用,因为我们通常不会随意修改主键。
如果想要使用级联更新,像下面这样定义外键就可以了。
foreign key (teacher_id) references t_teacher (teacher_id) on update cascade
我们还是使用前面插入的数据作为例子,执行更新语句:

我们修改了教师表中一条数据的主键,学生表的外键值也级联更新了。
同时设置级联删除和级联更新
两个级联操作全部指定给外键就行了。
foreign key (teacher_id) references t_teacher (teacher_id) on delete cascade on update cascade
除了cascade我们还有哪些选项
restrict默认行为(默认强制外键约束),无需手动指定,这种情况下直接删除或更新被外键关联的数据项是不允许的,SQL会报错cascade就是上面介绍的级联更新和删除no action删除或更新被外键关联的数据不会影响持有外键的数据set null删除或更新被外键关联的数据会把该外键值设为null,这个应用也很多,比如上面例子中,我们如果想要删除教师后保留学生信息,就可以使用这个选项
作者:Gacfox
版权声明:本网站为非盈利性质,文章如非特殊说明均为原创,版权遵循知识共享协议CC BY-NC-ND 4.0进行授权,转载必须署名,禁止用于商业目的或演绎修改后转载。