MySQL学习之触发器

文章目录


前言

阅读本文前请注意最后编辑时间,文章内容可能与目前最新的技术发展情况相去甚远。欢迎各位评论与私信,指出错误或是进行交流等。


什么是触发器(Trigger)?

触发器(Trigger)是数据库中的一种特殊存储程序,它绑定到某张表(或视图)上,并在特定的数据库操作(如 INSERT、UPDATE 或 DELETE)发生时自动执行预定义的操作。触发器无需手动调用,是一种事件驱动的机制。

触发器的特点

  1. 自动执行:一旦满足触发条件,触发器会在相关操作执行之前或之后自动运行。

  2. 绑定表:每个触发器都与特定的表绑定,只对该表的操作有效。

  3. 触发器类型包括:

    AFTER DELETE:在删除数据之后执行。

    BEFORE DELETE:在删除数据之前执行。

    AFTER UPDATE:在更新数据之后执行。

    BEFORE UPDATE:在更新数据之前执行。

    AFTER INSERT:在插入数据之后执行。

    BEFORE INSERT:在插入数据之前执行。

  4. 适用范围:

    触发器作用于每一行操作(FOR EACH ROW),或是整个语句的操作(FOR EACH STATEMENT,但在 MySQL 中不支持)。

MySQL中触发器的用法

创建

cpp 复制代码
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))

cpp 复制代码
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_record
    WHERE is_leave = 1
      AND 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 标志触发器主体,表示触发器的逻辑操作。

cpp 复制代码
 -- 检查新增小区楼栋数量是否 大于20栋 且 住户是否不低于150人
  IF NEW.term_count > 20 AND NEW.per_count >= 150 THEN
  • NEW.字段名:表示插入的新值。
  • 条件含义:
    检查新增小区楼栋数量是否 大于20栋 且 住户是否不低于150人。
    如果 NEW.term_count > 20 且 NEW.per_count >= 150,说明当前新增记录符合条件。
cpp 复制代码
DELETE FROM manual_record
WHERE is_leave = 1
  AND 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 早于一年前,则认为该记录已过期,删除之。

cpp 复制代码
 END IF; 结束条件语句。
 END $$ 标志触发器逻辑结束。
 DELIMITER $$ 重置分隔符

其他操作

cpp 复制代码
# 查看触发器
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

相关推荐
s_little_monster17 分钟前
【Linux开发】海思摄像头内部视频处理模块
linux·运维·经验分享·学习·音视频·嵌入式开发·海思
rufeike4 小时前
Redis学习笔记
redis·笔记·学习
重庆小透明6 小时前
【从零开始学习JVM | 第六篇】运行时数据区
java·jvm·后端·学习
Estar.Lee7 小时前
MySQL中外键约束详解 外键在表关系维护中的作用
运维·数据库·mysql·api·免费api
灯琰17 小时前
五款MySQL 可视化客户端软件
数据库·mysql
两袖清风9987 小时前
【MySQL】三大范式
数据库·mysql
晨曦backend8 小时前
Vim 替换命令完整学习笔记
笔记·学习·vim
liuyang___9 小时前
日期的数据格式转换
前端·后端·学习·node.js·node
蒙奇D索大9 小时前
【11408学习记录】[特殊字符] 速解命题核心!考研数学线性代数:4类行列式满分技巧(含秒杀公式)
笔记·学习·线性代数·考研·改行学it
哆啦A梦的口袋呀10 小时前
基于Python学习《Head First设计模式》第十章 状态模式
学习·设计模式