MySQL 5.7+ 支持单表同一事件类型(如 BEFORE INSERT)创建多个触发器,但需用 FOLLOWS/PRECEDES 显式声明执行顺序;而 5.6 及之前版本严格限制每种“时机+事件”组合仅允许一个触发器,报错 ERROR 1359。

MySQL 5.7 单表**并不限制**只能定义一个相同事件类型的触发器——这个说法本身是错的,实际是旧版本(5.6 及之前)才这样。如果你遇到 ERROR 1359 或“Trigger already exists”报错,大概率是环境版本低于 5.7,或误用了历史文档。
ERROR 1359 报错说明你还在用 MySQL 5.6 或更早版本
该错误码在 5.6 及之前代表「同一张表上已存在同类型触发器」,属于硬性限制,不是配置问题:
- BEFORE INSERT、AFTER UPDATE 等每个「时机 + 事件」组合只允许一个触发器,系统内部只预留一个 slot
- 即使 DROP 后重建,也不能绕过;试图 CREATE 第二个会直接失败
- 常见 workaround 是把所有逻辑塞进一个触发器里,用 IF 分支判断,但可读性和调试成本高
MySQL 5.7+ 支持多个同类触发器,但需显式控制顺序
5.7 引入事务安全的 data dictionary,触发器元数据统一存入 mysql.triggers 表,支持主键唯一性(TRIGGER_SCHEMA, TRIGGER_NAME),从而解除单触发器限制:
- 你可以创建多个
BEFORE INSERT,只要名字不同,比如t1_before_ins_log和t1_before_ins_sync - 执行顺序默认按创建时间追加,但不可靠(如导入 dump 时顺序丢失)
- 必须用
FOLLOWS或PRECEDES显式声明依赖:CREATE TRIGGER t2 BEFORE INSERT ON t1 FOLLOWS t1_trigger - 若引用的触发器名不存在,语句直接报错
ERROR 3814 (HY000): Unknown trigger 'xxx',不会静默忽略
真正限制单表触发器总数的是事件类型组合,不是版本
无论 5.7 还是 8.0,MySQL 单表最多支持 6 个触发器,这是由「事件 × 时机」的正交组合决定的:
-
BEFORE INSERT、AFTER INSERT -
BEFORE UPDATE、AFTER UPDATE -
BEFORE DELETE、AFTER DELETE - 超过这 6 种组合再建,会报
ERROR 1235 (42000): This version of MySQL doesn't yet support 'multiple triggers with the same action time and event for one table'(注意:该错误在 5.7+ 已不用于同类多触发器场景,而是指逻辑越界)
容易被忽略的关键点:FOLLOWS/PRECEDES 不是可选项,而是生产必需
虽然 5.7 允许多个同类触发器,但如果你没写 FOLLOWS 或 PRECEDES,MySQL 会按字典当前状态计算“末尾”,而这个状态可能因导入、重建、升级而改变。特别是从 5.7 升级到 8.0 时,data dictionary 校验更严格,隐式顺序可能导致升级中断。所以哪怕环境仍是 5.7,所有新增触发器都应显式声明顺序关系。


















