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

来源:这里教程网 时间:2026-02-28 20:48:28 作者:

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.id
INSERT
里直接报错
同一张表上重复建同类型触发器:一张表最多只能有一个
BEFORE INSERT
、一个
AFTER UPDATE
……共6个。想覆盖旧的?先
DROP TRIGGER IF EXISTS trigger_name

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

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

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

比如要实现“用户注册后自动创建默认配置”,必须用

AFTER INSERT
;而“插入时强制转小写邮箱”,就得用
BEFORE INSERT
NEW.email

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

相关推荐