mysql触发器是什么_mysql触发器基础概念解析

2次阅读

mysql触发器是“自动响应表操作的SQL小管家”,在INSERT、UPDATE、delete事件发生时,无需调用即在同一事务中执行预设逻辑。

mysql触发器是什么_mysql触发器基础概念解析

mysql触发器到底是个啥?一句话说清

MySQL触发器就是一个“自动响应表操作的SQL小管家”:你往表里 INSERT 一条数据、改了某行 UPDATE、或者删掉记录 DELETE,它就立刻按你写好的逻辑偷偷执行一段SQL——不用调用、不靠应用层、也不需要手动跑,只要事件发生,它就在同一事务里跟着动。

什么时候非得用触发器?不是所有场景都适合

触发器真有用,但容易被滥用。它最适合解决那些“必须在数据库层强约束、且跨表联动”的问题:

  • 订单插入时自动生成带前缀+补零的单号(BEFORE INSERT + NEW.order_number赋值)
  • 用户余额更新后,自动往日志表写一条变更记录(AFTER UPDATE + INSERT INTO audit_log...
  • 删除商品前,检查是否还有未完成订单,有则报错回滚(BEFORE DELETE + if EXISTS ... THEN signal SQLSTATE '45000' ...
  • 库存扣减后,若低于阈值,自动更新 is_low_stock = 1 字段(AFTER UPDATE 跨字段联动)

⚠️ 别用它做耗时操作(比如发邮件、调外部API)、别嵌套调用存储过程、更别指望它替代应用层的业务校验——事务一崩,整个操作就撤回,连带你的“成功提示”都是假的。

创建触发器最容易栽的三个坑

写法看着简单,实操中翻车率极高,尤其新手常卡在这三点:

  • 没改分隔符就写多行:MySQL默认以 ; 结束语句,但触发器体里也有 ;,不先执行 DELIMITER $$,就会报错 Error 1064 —— 一定要在 CREATE TRIGGER 前改,结束后再改回来
  • 混淆 NEW 和 OLD:只有 INSERT 能用 NEW(新数据),DELETE 只能用 OLD(旧数据),UPDATE 两者都能用(NEW 是改后值,OLD 是改前值)。写成 OLD.idINSERT 里直接报错
  • 同一张表上重复建同类型触发器:一张表最多只能有一个 BEFORE INSERT、一个 AFTER UPDATE……共6个。想覆盖旧的?先 DROP TRIGGER IF EXISTS trigger_name

触发器执行时机选 BEFORE 还是 AFTER?看你要干啥

这决定你能不能改数据、能不能看到最终结果:

  • BEFORE:能修改即将插入/更新的行(通过 SET NEW.xxx = ...),适合做数据清洗、默认值填充、合法性拦截;但看不到其他行的最终状态(比如不能查本表当前最大ID再+1,可能并发冲突)
  • AFTER:不能改 NEWOLD 的字段,但能安全读写其他表、记录日志、触发级联更新——因为主操作已落地,事务还没提交,一切还在可控范围内

比如要实现“用户注册后自动创建默认配置”,必须用 AFTER INSERT;而“插入时强制转小写邮箱”,就得用 BEFORE INSERTNEW.email

触发器不是银弹,它是把双刃剑:用对了,数据一致性稳如磐石;用错了,排查链路变长、性能毛刺频出、甚至引发死锁。关键不在会不会写,而在清楚知道——这一行SQL,到底该由谁来负责保证正确。

text=ZqhQzanResources