触发器是MySQL中与表绑定的事件驱动机制,在INSERT、UPDATE或DELETE时自动执行;它不可显式调用、不支持事务控制语句,BEFORE可修改NEW值,AFTER适合日志记录,性能开销需谨慎评估。

触发器是什么:数据库层的自动响应机制
触发器是 MySQL 中一种特殊的存储程序,它在特定表上发生 INSERT、UPDATE 或 DELETE 操作时自动执行,无需应用层调用。它不是函数也不是存储过程,而是一段与表强绑定的、事件驱动的逻辑。
常见错误现象:执行 INSERT 后发现数据“莫名”被改了,或日志表没写入——大概率是触发器在后台生效但未被察觉。
- 触发器必须关联到具体表,且一个表同一事件(如
BEFORE INSERT)只能有一个同类型触发器 - 不能显式调用,也不能传参;它的输入来自当前操作的行(
NEW/OLD) - 不支持事务控制语句(如
START TRANSACTION),但会参与外层语句的事务
BEFORE 和 AFTER 触发器的关键区别
BEFORE 触发器在语句实际执行前运行,可修改 NEW 行值;AFTER 在语句成功提交后运行,适合记录日志或同步更新其他表。
典型误用:在 AFTER UPDATE 里试图修改本表数据,会报错 Can't update table 't' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
-
BEFORE INSERT:可用于设置默认值、校验字段(如把空邮箱转为'unknown@example.com') -
BEFORE UPDATE:适合自动更新updated_at字段,或阻止非法状态变更(如status从'done'改回'pending') -
AFTER DELETE:常用于归档删除记录到历史表,或清理关联缓存键
触发器中 NEW 和 OLD 的使用限制
NEW 代表新行数据(INSERT 和 UPDATE 可用),OLD 代表旧行数据(UPDATE 和 DELETE 可用)。它们是只读别名,不能赋值给变量再修改——必须直接赋值给 NEW.column_name。
DM建站系统汽车保养维修HTML5网站模板,DM企业建站系统。是由php+mysql开发的一套专门用于中小企业网站建设的开源cms。DM系统的理念就是组装,把模板和区块组装起来,产生不同的网站效果。可以用来快速建设一个响应式的企业网站( PC,手机,微信都可以访问)。后台操作简单,维护方便。DM企业建站系统安装步骤:第一步,先用phpmyadmin导入sql文件。 第二步:把文件放到你的本地服务器
容易踩的坑:在 BEFORE INSERT 中写 SET @tmp = NEW.id; 再 SET NEW.id = @tmp + 1; 是无效的;必须写成 SET NEW.id = NEW.id + 1;
-
INSERT:只有NEW,OLD为NULL -
DELETE:只有OLD,NEW为NULL -
UPDATE:NEW和OLD都存在,OLD是更新前值,NEW是待写入值
创建和查看触发器的实操要点
创建触发器需有 TRIGGER 权限,且不能跨库引用表(除非用 db_name.table_name 显式指定)。MySQL 8.0+ 支持多语句触发器,但必须用 BEGIN ... END 包裹,并临时修改分隔符。
DELIMITER $$ CREATE TRIGGER users_update_updated_at BEFORE UPDATE ON users FOR EACH ROW BEGIN SET NEW.updated_at = NOW(); END$$ DELIMITER ;
查看已建触发器:
- 查当前库所有触发器:
SHOW TRIGGERS; - 查某张表的触发器:
SHOW TRIGGERS LIKE 'users'; - 查定义语句:
SELECT TRIGGER_NAME, ACTION_TIMING, EVENT_MANIPULATION, ACTION_STATEMENT FROM information_schema.TRIGGERS WHERE EVENT_OBJECT_TABLE = 'users';
性能影响容易被低估:每个触发器都会增加 DML 延迟,尤其是涉及复杂查询或跨表更新时。高并发写入场景下,应优先考虑应用层处理或异步方案。









