SQL触发器是绑定在表或视图上的自动执行存储过程,用于保障数据一致性与嵌入业务逻辑;支持INSERT/UPDATE/DELETE事件及BEFORE/AFTER时机,分语句级与行级,适用于日志记录、统计同步、约束校验等场景,但受递归限制、事务耦合和性能开销约束,应审慎使用。

SQL触发器是数据库面试中常被考察的重点内容,既考概念理解,也考实际设计能力。掌握其核心机制、适用场景和关键限制,才能在面试中清晰表达、避免踩坑。
触发器是什么?为什么用它?
触发器(Trigger)是绑定在表或视图上的特殊存储过程,由数据操作(INSERT/UPDATE/DELETE)自动激活执行,无需手动调用。它的核心价值在于实现数据一致性保障和业务逻辑自动嵌入,比如:同步更新统计字段、记录操作日志、校验跨表约束等。
注意:它不是替代应用层逻辑的工具,而是对数据库层强一致性的补充。
常见触发器类型与执行时机
主流数据库(如MySQL、SQL Server、PostgreSQL)支持以下分类:
- 按触发事件分:INSERT触发器、UPDATE触发器、DELETE触发器,也可组合定义(如MySQL的BEFORE INSERT, AFTER UPDATE)
- 按触发时机分:BEFORE(可修改即将插入/更新的行,常用于数据清洗或默认值填充);AFTER(适合日志记录、级联更新、通知类操作)
- 按作用范围分:行级触发器(每影响一行就触发一次,最常用);语句级触发器(整个SQL语句执行完触发一次,Oracle/PG支持,MySQL不支持)
触发器的典型使用场景(附简例)
面试官常让现场写一个简单触发器,重点看语法熟稔度和逻辑合理性:
- 自动填充创建时间:BEFORE INSERT ON orders SET NEW.create_time = NOW();
- 订单金额变更时同步更新客户总消费额:AFTER UPDATE ON order_items,读取OLD.amount和NEW.amount差值,UPDATE customers SET total_spent = total_spent + diff WHERE id = NEW.customer_id
- 禁止周末删除用户:BEFORE DELETE ON users IF WEEKDAY(NOW()) IN (5,6) THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Not allowed to delete on weekends'; END IF;
必须知道的硬性限制与风险点
触发器看似强大,但滥用极易引发性能、维护和事务问题:
- 不能显式调用或传参:只响应DML,无法像存储过程那样灵活控制
- 禁止在触发器中修改触发它的同一张表(MySQL报错“Can't update table in stored function/trigger”),否则导致递归或死锁
- 事务内执行:触发器失败会导致整个原始DML回滚,务必保证逻辑健壮(例如避免未处理的NULL值或除零)
- 隐式开销大:高频写入表上加复杂触发器会显著拖慢性能,日志类建议异步化或改用应用层+消息队列
- 调试困难:错误不易定位,尤其多层触发器嵌套时,生产环境慎用嵌套逻辑
不复杂但容易忽略——真正决定触发器是否该用的,不是“能不能”,而是“该不该”。优先考虑约束(CHECK)、外键、应用层统一处理;仅当强一致性必须由数据库兜底时,才引入触发器。










