当前位置: 首页 > news >正文

MySQL 触发器(Trigger)讲解

MySQL 触发器(Trigger)是一种与表相关联的特殊存储过程,它会在指定的数据库事件(如 INSERTUPDATEDELETE)发生时自动执行。触发器常用于保证数据一致性、记录审计日志或实现复杂的业务逻辑。


一、触发器的核心概念

  1. ​触发事件​

    • INSERT:插入数据时触发(如 BEFORE INSERT 或 AFTER INSERT
    • UPDATE:更新数据时触发(如 BEFORE UPDATE 或 AFTER UPDATE
    • DELETE:删除数据时触发(如 BEFORE DELETE 或 AFTER DELETE
  2. ​触发时机​

    • BEFORE:在操作执行前触发(可修改即将写入的数据)
    • AFTER:在操作执行后触发(只能读取已提交的数据)
  3. ​触发器作用对象​

    • 每个触发器只能关联一个表。
    • 通过 NEW 和 OLD 关键字访问数据:
      • NEW.column_name:表示新插入或更新的数据(INSERT/UPDATE)。
      • OLD.column_name:表示被更新或删除前的数据(UPDATE/DELETE)。

二、创建触发器的语法

DELIMITER $$
CREATE TRIGGER trigger_name
[BEFORE|AFTER] [INSERT|UPDATE|DELETE] ON table_name
FOR EACH ROW  -- 行级触发器(逐行触发)
BEGIN-- 触发器逻辑(SQL语句)
END
$$
DELIMITER ;

三、示例详解

示例1:自动设置创建时间

​需求​​:在插入数据前自动设置记录的创建时间。

DELIMITER $$
CREATE TRIGGER set_created_time
BEFORE INSERT ON users
FOR EACH ROW
BEGINSET NEW.created_at = NOW();  -- 修改插入前的数据
END
$$
DELIMITER ;
示例2:审计日志

​需求​​:在删除数据后记录日志到另一张表。

DELIMITER $$
CREATE TRIGGER log_user_deletion
AFTER DELETE ON users
FOR EACH ROW
BEGININSERT INTO audit_log (action, user_id, deleted_time)VALUES ('DELETE', OLD.id, NOW());  -- OLD.id 是被删除行的原始值
END
$$
DELIMITER ;
示例3:数据校验

​需求​​:禁止插入负数金额。

DELIMITER $$
CREATE TRIGGER validate_salary
BEFORE INSERT ON employees
FOR EACH ROW
BEGINIF NEW.salary < 0 THENSIGNAL SQLSTATE '45000'  -- 抛出错误,阻止操作SET MESSAGE_TEXT = 'Salary cannot be negative';END IF;
END
$$
DELIMITER ;

四、触发器的管理

  1. ​查看触发器​

    SHOW TRIGGERS;  -- 显示所有触发器
    SHOW CREATE TRIGGER trigger_name;  -- 查看具体定义
  2. ​删除触发器​

    DROP TRIGGER [IF EXISTS] trigger_name;
  3. ​修改触发器​
    MySQL 不支持直接修改触发器,需先删除再重新创建。


五、触发器的优缺点

​优点​​:
  • 简化应用层逻辑,保证数据一致性。
  • 自动执行级联操作(如更新关联表)。
​缺点​​:
  • ​隐藏的业务逻辑​​:触发器可能使调试复杂化。
  • ​性能问题​​:频繁触发的复杂逻辑可能影响数据库性能。
  • ​循环触发风险​​:例如,表A的触发器修改表B,表B的触发器又修改表A。

六、注意事项

  1. ​权限要求​
    创建触发器需要 TRIGGER 权限。

  2. ​事务中的触发器​
    触发器与所在事务共享上下文。如果触发器失败,整个事务会回滚。

  3. ​避免递归触发​
    确保触发器不会导致无限循环(如更新同一张表)。

  4. ​不支持 DDL​
    触发器内部不能执行 CREATE TABLE 或 ALTER TABLE 等DDL操作。


七、适用场景

  1. ​数据校验​​:确保字段值符合业务规则。
  2. ​审计追踪​​:记录关键数据的变更历史。
  3. ​自动计算​​:如更新统计字段(订单总金额)。
  4. ​级联操作​​:删除主表数据时同步删除关联的子表数据。

八、高级用法:FOR EACH ROW 与变量

触发器逐行处理数据,可以在 BEGIN...END 块中使用变量:

DELIMITER $$
CREATE TRIGGER update_inventory
AFTER INSERT ON orders
FOR EACH ROW
BEGINDECLARE product_id INT;DECLARE quantity INT;SET product_id = NEW.product_id;SET quantity = NEW.quantity;UPDATE products SET stock = stock - quantity WHERE id = product_id;
END
$$
DELIMITER ;

通过合理使用触发器,可以实现数据库层面的自动化逻辑,但需谨慎权衡其维护成本和性能影响。

相关文章:

  • LeetCode 790 多米诺和托米诺平铺 题解
  • Latex排版问题:图片单独占据一页
  • 【网络原理】IP协议
  • vmware虚拟机克隆
  • 聊天助手提示词调优案例
  • 代码随想录算法训练营第九天 |【字符串】151.翻转字符串里的单词、卡码网55.右旋转字符串、28.实现strStr、459.重复的子字符串
  • 星纪魅族新品发布会定档5月13日,Note 16系列战神归来
  • 第七章,VLAN技术
  • 驱动开发系列57 - Linux Graphics QXL显卡驱动代码分析(四)显示区域更新
  • C#中从本地(两个路径文件夹)中实时拿图显示到窗口中并接收(两个tcp发送的信号)转为字符串显示在窗体中实现检测可视化
  • 【C语言】推箱子小游戏
  • C++ 构造函数
  • # YOLOv1:开启实时目标检测的新时代
  • tp8+swoole搭建
  • 如何提升丢包网络环境下的传输性能:从 TCP 到 QUIC,再到 wovenet 的实践
  • OpenGl实战笔记(2)基于qt5.15.2+mingw64+opengl实现纹理贴图
  • 【C++核心技术深度解析:从继承多态到STL容器 】
  • Nacos源码—4.Nacos集群高可用分析四
  • Python爬虫+代理IP+Header伪装:高效采集亚马逊数据
  • 【AI知识库云研发部署】RAGFlow + DeepSeek
  • 吴清:基金业绩差的必须少收管理费,督促基金公司从“重规模”向“重回报”转变
  • 吴清:创造条件支持优质中概股企业回归内地和香港股市
  • 何立峰将访问瑞士、法国并举行中美经贸高层会谈、第十次中法高级别经济财金对话
  • 六大车企一季报:比亚迪近92亿净利稳居第一,多家车企营收下滑
  • 新华每日电讯:上海“绿色大民生”撑起“春日大经济”
  • AI世界的年轻人|“热潮下要有定力”,她的目标是让机器人真正步入家庭