新手不应直接学触发器和函数,因其隐式执行、易致死锁、覆盖字段、并发难控;函数还受限于确定性声明、禁止写操作等;应先掌握索引优化、upsert、事务链路。

不适合直接学,尤其不建议新手在还没写熟 JOIN、GROUP BY 和事务逻辑前碰触发器和函数。
为什么触发器对新手特别不友好
触发器执行是隐式的,你没调它,它自己就跑了——出问题时根本看不出哪条语句触发了哪段逻辑。常见错误包括:
-
AFTER INSERT里又去改同一张表,导致死锁或报错Can't update table 'xxx' in stored function/trigger - 误用
BEFORE UPDATE修改NEW字段,结果业务字段被悄悄覆盖,查半天发现不是应用层写的 - 在高并发插入场景下,多个触发器叠加执行顺序难预测,日志里只看到最终结果异常
真实场景中,90% 的触发器需求其实用应用层校验 + 显式 sql 更可控、更易测试。
函数比触发器稍好,但仍有硬门槛
mysql 函数(CREATE FUNCTION)要求你必须声明 DETERMINISTIC 或 READS SQL DATA,否则连创建都失败;而且函数里不能做 INSERT/UPDATE,也不能调用临时表——这些限制新手常忽略。
典型踩坑点:
- 写了个计算订单金额的函数,里面用了
select SUM(),但忘了加READS SQL DATA,建函数时报错this function has none of DETERMINISTIC... - 试图在函数里更新用户积分,结果报错
Not allowed to return a result set from a function(函数不能返回多行结果) - 把函数用在
WHERE条件里,比如WHERE get_user_level(user_id) = 3,导致全表扫描,性能骤降
真正该优先练的三件事
别急着进阶,先把基础链路跑通:
- 用
EXPLAIN看懂自己写的SELECT是不是走了索引,有没有回表 - 手写带
ON DUPLICATE KEY UPDATE的批量 upsert,比触发器更直观、更可测 - 在一个事务里串起
INSERT→UPDATE→SELECT,理解隔离级别怎么影响中间状态
等你能靠一条 EXPLAIN format=json 快速定位慢查询,再去看触发器和函数——那时你才真正知道它们适合填什么坑,而不是制造新坑。