触发器的介绍
触发器, 就是一种特殊的存储过程
触发器和存储过程一样是一个能够完成特定功能、存储在数据库上的 SQL 片段, 但是触发器无需调用, 当对数据表中的数据执行 DML 操作时自动触发这个 SQL 片段的执行, 无需手动调用
在 MySQL 中, 只有执行 insert\delete\update
操作才能触发触发器的执行
触发器的使用
案件说明
# 创建学生信息操作日志表
create table stulogs(
id int primary key auto_increment,
time TIMESTAMP,
log_text varchar(200)
);
# 当向 students 表中添加学生信息时, 同时要在 stulogs 表中添加一条操作日志
insert into students(stu_num, stu_name, stu_gender, stu_age)
values('1004', '夏利', '女', 20);
# 手动进行纪录日志
insert into stulogs(time, long_text)
values(now(), '添加1004学生信息');
创建触发器
案例: 当向学生信息表添加、删除、修改学生信息表时, 使用触发器自动进行日志纪录
语法
create trigger tri_name
<before|after> -- 定义触发时机
<insert|delete|update> -- 定义 DML 类型
ON < table_name>
for each row -- 声明为行级触发器 (只要操作一条纪录就出发触发器执行一次)
sql_statement -- 触发器操作
示例
# 当学生信息表发生添加操作时, 向日志记录表中纪录一条日志
create trigger tri_test1
after insert on students
for each row
insert into stulogs(time, log_text)
values(now(), concat('添加', NEW.stu_num, '学生信息'));
查看触发器
show triggers;
测试触发器
- 刚创建的触发器是在 students 表发生 insert 操作时触发, 所以只需执行学生信息的添加操作
# 测试 1: 添加一个学生信息, 触发器执行了一次
insert into students(stu_num,stu_name, stu_gender, stu_age)
values('1005', '小明', '男', 20);
# 测试 2: 一条 SQL 指令添加了 2 条学生信息, 触发器执行 2 次
insert into students(stu_num,stu_name,stu_gender,stu_age)
values('1006', '小刚', '男', 20), ('1007', '李磊', '男', 20);
删除触发器
drop trigger tri_test1;
NEW 与 OLD
触发器用于监听对数据表中的
insert\delete\update
操作, 在触发器中通常处理一些 DML 的关联操作; 可以使用NEW
和OLD
关键字在触发器中获取触发这个触发器的 DML 操作的数据
- NEW: 在触发器中用于获取
insert
操作添加的数据、update
操作修改后的数据- OLD: 在触发器中用于获取
delete
操作删除前的数据、update
操作修改前的数据
NEW
insert
操作中:NEW
表示添加的新纪录
create trigger tri_test1
after insert on students for each row
insert into stulogs(time, log_text)
values(now(), concat('添加', NEW.stu_num, '学生信息'));
update
操作中:NEW
表示修改后的数据
create trigger tri_test2
after update on students for each row
insert into stulogs(time, log_text)
values(now(), concat('修改学生信息为: ', NEW.stu_num, NEW.stu_name));
OLD
delete
操作中:OLD
表示删除的纪录
create trigger tri_test3
after delete on students for each row
insert into stulogs(time, log_text)
values(now(), concat('删除', OLD.stu_num, '学生信息'));
update
操作中:OLD
表示删除前的纪录
create trigger tri_test3
after update on students for each row
insert into stulogs(time, log_text)
values(now(), concat('将修改学生信息从【', OLD.stu_num, '】修改为【', NEW.stu_name, '】'));
触发器使用总结
优点
- 触发器是自动执行的, 当对触发器相关的表执行相应的 DML 操作时立即执行
- 触发器可以实现表中数据的级联操作 (关联操作), 有利于保证数据的完整性
- 触发器可以对 DML 操作的数据进行更为复杂的合法性校验
缺点
- 使用触发器实现的业务逻辑如果出现问题将难以定位, 后期维护困难
- 大量使用触发器容易导致代码结构杂乱, 增加程序的复杂性
- 当触发器操作的数据量比较大时, 执行的效率会大大降低
使用建议
- 在互联网项目中, 应避免使用触发器
- 对于并发量不大的项目可以使用存储过程, 但是在互联网引用中不提倡使用存储过程, 以为存储过程使将实现业务的逻辑交给数据库处理, 一则增减了数据库的负载, 二则不利于数据库的迁移