触发器的介绍

触发器, 就是一种特殊的存储过程

触发器和存储过程一样是一个能够完成特定功能、存储在数据库上的 SQL 片段, 但是触发器无需调用, 当对数据表中的数据执行 DML 操作时自动触发这个 SQL 片段的执行, 无需手动调用

在 MySQL 中, 只有执行 insert\delete\update 操作才能触发触发器的执行

触发器的使用

案件说明

  1. # 创建学生信息操作日志表
  2. create table stulogs(
  3. id int primary key auto_increment,
  4. time TIMESTAMP,
  5. log_text varchar(200)
  6. );
  7. # 当向 students 表中添加学生信息时, 同时要在 stulogs 表中添加一条操作日志
  8. insert into students(stu_num, stu_name, stu_gender, stu_age)
  9. values('1004', '夏利', '女', 20);
  10. # 手动进行纪录日志
  11. insert into stulogs(time, long_text)
  12. values(now(), '添加1004学生信息');

创建触发器

案例: 当向学生信息表添加、删除、修改学生信息表时, 使用触发器自动进行日志纪录

语法

  1. create trigger tri_name
  2. <before|after> -- 定义触发时机
  3. <insert|delete|update> -- 定义 DML 类型
  4. ON < table_name>
  5. for each row -- 声明为行级触发器 (只要操作一条纪录就出发触发器执行一次)
  6. sql_statement -- 触发器操作

示例

  1. # 当学生信息表发生添加操作时, 向日志记录表中纪录一条日志
  2. create trigger tri_test1
  3. after insert on students
  4. for each row
  5. insert into stulogs(time, log_text)
  6. values(now(), concat('添加', NEW.stu_num, '学生信息'));

查看触发器

  1. show triggers;

测试触发器

  • 刚创建的触发器是在 students 表发生 insert 操作时触发, 所以只需执行学生信息的添加操作
  1. # 测试 1: 添加一个学生信息, 触发器执行了一次
  2. insert into students(stu_num,stu_name, stu_gender, stu_age)
  3. values('1005', '小明', '男', 20);
  4. # 测试 2: 一条 SQL 指令添加了 2 条学生信息, 触发器执行 2 次
  5. insert into students(stu_num,stu_name,stu_gender,stu_age)
  6. values('1006', '小刚', '男', 20), ('1007', '李磊', '男', 20);

删除触发器

  1. drop trigger tri_test1;

NEW 与 OLD

触发器用于监听对数据表中的 insert\delete\update 操作, 在触发器中通常处理一些 DML 的关联操作; 可以使用 NEWOLD 关键字在触发器中获取触发这个触发器的 DML 操作的数据

  • NEW: 在触发器中用于获取 insert 操作添加的数据、 update 操作修改后的数据
  • OLD: 在触发器中用于获取 delete 操作删除前的数据、update 操作修改前的数据

NEW

  • insert 操作中: NEW 表示添加的新纪录
  1. create trigger tri_test1
  2. after insert on students for each row
  3. insert into stulogs(time, log_text)
  4. values(now(), concat('添加', NEW.stu_num, '学生信息'));
  • update 操作中: NEW 表示修改后的数据
  1. create trigger tri_test2
  2. after update on students for each row
  3. insert into stulogs(time, log_text)
  4. values(now(), concat('修改学生信息为: ', NEW.stu_num, NEW.stu_name));

OLD

  • delete 操作中: OLD 表示删除的纪录
  1. create trigger tri_test3
  2. after delete on students for each row
  3. insert into stulogs(time, log_text)
  4. values(now(), concat('删除', OLD.stu_num, '学生信息'));
  • update 操作中: OLD 表示删除前的纪录
  1. create trigger tri_test3
  2. after update on students for each row
  3. insert into stulogs(time, log_text)
  4. values(now(), concat('将修改学生信息从【', OLD.stu_num, '】修改为【', NEW.stu_name, '】'));

触发器使用总结

优点

  • 触发器是自动执行的, 当对触发器相关的表执行相应的 DML 操作时立即执行
  • 触发器可以实现表中数据的级联操作 (关联操作), 有利于保证数据的完整性
  • 触发器可以对 DML 操作的数据进行更为复杂的合法性校验

缺点

  • 使用触发器实现的业务逻辑如果出现问题将难以定位, 后期维护困难
  • 大量使用触发器容易导致代码结构杂乱, 增加程序的复杂性
  • 当触发器操作的数据量比较大时, 执行的效率会大大降低

使用建议

  • 在互联网项目中, 应避免使用触发器
  • 对于并发量不大的项目可以使用存储过程, 但是在互联网引用中不提倡使用存储过程, 以为存储过程使将实现业务的逻辑交给数据库处理, 一则增减了数据库的负载, 二则不利于数据库的迁移