触发器(Trigger)是数据库的"自动守卫"------当表发生 INSERT / UPDATE / DELETE 时自动执行预定义逻辑,无需应用层介入;事件(Event)则是数据库内置的"定时闹钟",按计划自动执行任务。两者都是让数据库"自己动起来"的关键能力。
一、触发器:数据变更的自动响应
场景
订单表删除订单时,需要同步清理订单明细表;用户更新邮箱时,需要自动记录审计日志。这些"连带操作"如果靠应用代码维护,容易遗漏且难以保证一致性,触发器可以在数据库层面自动完成。
语法详解
sql
CREATE TRIGGER 触发器名
{BEFORE | AFTER} {INSERT | UPDATE | DELETE}
ON 表名
FOR EACH ROW
BEGIN
-- 触发逻辑
END;
BEFORE / AFTER:变更前 / 变更后触发FOR EACH ROW:每一行受影响都会触发(行级触发器)- 通过
NEW/OLD关键字访问新值 / 旧值:INSERT只有NEWDELETE只有OLDUPDATE两者都有
代码示例:自动审计日志
sql
-- 1. 创建审计日志表
CREATE TABLE user_audit (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT,
old_email VARCHAR(100),
new_email VARCHAR(100),
changed_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
-- 2. 创建触发器:邮箱变更时自动记录
CREATE TRIGGER trg_user_email_update
AFTER UPDATE ON users
FOR EACH ROW
BEGIN
IF OLD.email <> NEW.email THEN
INSERT INTO user_audit (user_id, old_email, new_email)
VALUES (OLD.id, OLD.email, NEW.email);
END IF;
END;
执行结果
sql
UPDATE users SET email = 'new@example.com' WHERE id = 1;
-- 无需手动 INSERT,审计表自动多了一条记录:
-- +----+---------+------------------+------------------+---------------------+
-- | id | user_id | old_email | new_email | changed_at |
-- +----+---------+------------------+------------------+---------------------+
-- | 1 | 1 | old@example.com | new@example.com | 2026-08-02 10:30:00 |
-- +----+---------+------------------+------------------+---------------------+
管理触发器
sql
SHOW TRIGGERS; -- 查看所有触发器
DROP TRIGGER trg_user_email_update; -- 删除触发器
二、事件:数据库内置定时任务
场景
每天凌晨自动清理 30 天前的过期日志、每周日自动汇总统计数据。无需依赖外部 cron,数据库自己就能按计划执行。
语法详解
sql
CREATE EVENT 事件名
ON SCHEDULE EVERY 1 DAY -- 执行周期
STARTS '2026-08-03 03:00:00' -- 开始时间
DO
-- 要执行的 SQL 语句
END;
代码示例:定时清理过期日志
sql
-- 开启事件调度器(默认可能关闭)
SET GLOBAL event_scheduler = ON;
-- 每天凌晨 3 点删除 30 天前的操作日志
CREATE EVENT evt_clean_old_logs
ON SCHEDULE EVERY 1 DAY
STARTS '2026-08-03 03:00:00'
DO
DELETE FROM operation_log
WHERE created_at < DATE_SUB(NOW(), INTERVAL 30 DAY);
管理事件
sql
SHOW EVENTS; -- 查看所有事件
ALTER EVENT evt_clean_old_logs DISABLE; -- 暂停
ALTER EVENT evt_clean_old_logs ENABLE; -- 恢复
DROP EVENT evt_clean_old_logs; -- 删除
三、注意事项
- 触发器不要做重活:触发器内避免复杂查询和长时间操作,否则会拖慢主事务,甚至引发锁等待。
- 小心递归触发:A 表触发器修改 B 表,B 表触发器又修改 A 表,可能形成无限循环(MySQL 默认会报错阻止)。
- 调试困难:触发器是隐式执行的,出问题时排查成本高,务必写好注释并配合审计表使用。
- 事件调度器开关 :MySQL 的
event_scheduler默认 OFF,需先开启;数据库重启后要确认配置持久化。 - 可移植性:触发器语法在不同数据库(Oracle / SQL Server / PostgreSQL)差异较大,迁移时要重写。
小结
- 触发器 = 数据变更时的自动回调,适合保证数据一致性、自动审计
- 事件 = 数据库内置定时任务,适合周期性维护操作
- 两者都能减少应用层代码,但要用在合适场景,避免"自动化反而带来灾难"