MySQL学习之触发器
文章目录
- 前言
- 什么是触发器(Trigger)?
- 触发器的特点
- MySQL中触发器的用法
- 创建
- NEW 与 OLD
- 举例
- 其他操作
- 注意事项
- 后续内容
- 参考目录
前言
阅读本文前请注意最后编辑时间,文章内容可能与目前最新的技术发展情况相去甚远。欢迎各位评论与私信,指出错误或是进行交流等。
什么是触发器(Trigger)?
触发器(Trigger)是数据库中的一种特殊存储程序,它绑定到某张表(或视图)上,并在特定的数据库操作(如 INSERT、UPDATE 或 DELETE)发生时自动执行预定义的操作。触发器无需手动调用,是一种事件驱动的机制。
触发器的特点
-
自动执行:一旦满足触发条件,触发器会在相关操作执行之前或之后自动运行。
-
绑定表:每个触发器都与特定的表绑定,只对该表的操作有效。
-
触发器类型包括:
AFTER DELETE:在删除数据之后执行。
BEFORE DELETE:在删除数据之前执行。
AFTER UPDATE:在更新数据之后执行。
BEFORE UPDATE:在更新数据之前执行。
AFTER INSERT:在插入数据之后执行。
BEFORE INSERT:在插入数据之前执行。 -
适用范围:
触发器作用于每一行操作(FOR EACH ROW),或是整个语句的操作(FOR EACH STATEMENT,但在 MySQL 中不支持)。
MySQL中触发器的用法
创建
DELIMITER $$CREATE TRIGGER trigger_name { BEFORE | AFTER } { INSERT | UPDATE | DELETE }
ON table_name FOR EACH ROW
BEGIN执行语句
END $$DELIMITER ;
NEW 与 OLD
MySQL中定义了NEW和OLD,用来表示触发器的所在表中,触发了触发器的那一行数据。引用触发器中发生变化的记录内容,具体地:
触发器类型 | 触发器类型NEW和OLD的使用 |
---|---|
INSERT型触发器 | NEW表示将要或者已经新增的数据 |
UPDATE型触发器 | OLD表示修改之前的数据,NEW表示将要或已经修改后的数据 |
DELETE 型触发器 | OLD表示将要或者已经删除的数据 |
使用方法:
NEW.columnName (columnName为相应数据表某一列名)
OLD.columnName
举例
下面是一个用于清理数据的触发器代码示例,为了使大家更好的理解触发器的使用,下面将为大家分析每句代码的作用以及使用方法。
(题目:在社区表community中,当新增新的小区后;触发事件为当前新增小区这个insert操作。当新增小区楼栋数量 大于20栋 且 住户不低于150人,则在访客记录表manual_record中 删除 离开时间(out_time)距现在是一年以前 且 所有已离开的访客记录 (is_leave=1))
DELIMITER $$
CREATE TRIGGER update_is_leave_cleanup
AFTER INSERT ON community
FOR EACH ROW
BEGIN-- 检查新增小区楼栋数量是否 大于20栋 且 住户是否不低于150人IF NEW.term_count > 20 AND NEW.per_count >= 150 THEN-- 删除所有离开时间超过一年的访客记录DELETE FROM manual_recordWHERE is_leave = 1AND out_time < DATE_SUB(NOW(), INTERVAL 1 YEAR);END IF;
END$$
DELIMITER ;
CREATE TRIGGER update_is_leave_cleanup:创建一个名为 update_is_leave_cleanup 的触发器。
AFTER INSERT:表示在 community表执行 INSERT操作后触发该触发器。
ON community:触发器绑定到 community表。
FOR EACH ROW:触发器对 insert 操作的每一行都生效(逐行触发)。
BEGIN 和 END 标志触发器主体,表示触发器的逻辑操作。
-- 检查新增小区楼栋数量是否 大于20栋 且 住户是否不低于150人IF NEW.term_count > 20 AND NEW.per_count >= 150 THEN
- NEW.字段名:表示插入的新值。
- 条件含义:
检查新增小区楼栋数量是否 大于20栋 且 住户是否不低于150人。
如果 NEW.term_count > 20 且 NEW.per_count >= 150,说明当前新增记录符合条件。
DELETE FROM manual_record
WHERE is_leave = 1AND out_time < DATE_SUB(NOW(), INTERVAL 1 YEAR);
-
条件 1:is_leave = 1:
仅删除已经离开的记录。 -
条件 2:out_time < DATE_SUB(NOW(), INTERVAL 1 YEAR):
out_time 是记录的离开时间。
DATE_SUB(NOW(), INTERVAL 1 YEAR) 计算当前时间减去 1 年的日期。
如果 out_time 早于一年前,则认为该记录已过期,删除之。
END IF; 结束条件语句。END $$ 标志触发器逻辑结束。DELIMITER $$ 重置分隔符
其他操作
# 查看触发器
show triggers;# 删除触发器
drop trigger if exists trigger_name;# 需要注意的是,MySQL 不支持直接禁用单个触发器,但可以通过禁用整个表的触发器来达到类似的效果。
# 禁用所有触发器(全局禁用)
SET GLOBAL DISABLE_TRIGGERS = 1;# 启用所有触发器(全局启用)
SET GLOBAL DISABLE_TRIGGERS = 0;
注意事项
-
触发器性能:如果表数据量大,使用触发器可能会影响性能。假设触发器每次执行花费1s, insert table 500条数据,那么就需要触发500次触发器,光是触发器执行的时间就花费了500s,而insert500条数据一共是1s,那么这个insert的效率就非常低了。
-
事务支持:如果 UPDATE 操作失败,触发器逻辑也不会执行。
-
调试触发器:可以通过启用 MySQL 日志或手动检查数据变化来调试触发器。
-
数据备份:删除记录操作是不可逆的,在执行触发器前确保数据已备份。
-
MYSQL中触发器中不能对本表进行insert,update,delete操作,以免递归循环触发
-
触发器是针对每一行的;在增删改非常频繁的表上使用触发器会非常消耗资源。
后续内容
关于MySQL已经是非常成熟的技术了,且优秀的博文和视频非常之多,所以就不打算做重复的工作。贴一些优秀的内容共同学习即可
MySQL索引:https://blog.csdn.net/justry_deng/article/details/81458470
https://blog.csdn.net/qq_35190492/article/details/109257302
https://blog.csdn.net/2401_85373732/article/details/145061201
MySQL事务:https://blog.csdn.net/weixin_58376680/article/details/136993032
https://blog.csdn.net/qq_56880706/article/details/122653735
MySQL锁:https://blog.csdn.net/qq_44700578/article/details/139912042
MySQL优化:https://blog.csdn.net/yuan2019035055/article/details/122310447(SQL优化、索引优化、锁机制、主从复制)
https://blog.csdn.net/xiaofeng10330111/article/details/105360974(索引优化)
参考目录
https://www.bilibili.com/video/BV1iF411z7Pu
https://blog.csdn.net/Future_yzx/article/details/144633142
https://blog.csdn.net/weixin_42571280/article/details/141650739