MySQL: MySQL触发器与事件调度器
最后更新:2026-08-26
触发器是自动执行的存储过程——数据变化时自动触发。
本课讲解触发器和事件调度器。
graph TB
A[数据变更事件] --> B{触发时机}
B -->|BEFORE| C[操作前触发]
B -->|AFTER| D[操作后触发]
C --> E[BEFORE INSERT<br/>插入前校验/修改]
C --> F[BEFORE UPDATE<br/>更新前校验/修改]
C --> G[BEFORE DELETE<br/>删除前校验]
D --> H[AFTER INSERT<br/>插入后联动]
D --> I[AFTER UPDATE<br/>更新后记日志]
D --> J[AFTER DELETE<br/>删除后清理]
A --> K[事件调度器]
K --> K1[定时执行]
K --> K2[一次性事件]
1. 你将学到
- BEFORE/AFTER 触发器
- NEW/OLD 关键字
- 触发器管理
- CREATE EVENT 事件调度
2. 一个真实的故事
(1) 痛点:手动操作总是遗漏
电商系统上线后,运营天天抱怨:下单后库存没扣、修改价格后审计日志没记录、过期会话堆积导致查询变慢。开发每次都在业务代码里加逻辑,但总有人忘记——不同服务的代码各写各的,根本无法统一保障。
(2) 触发器+事件的解法
用触发器在数据库层面自动执行:下单后扣库存、修改后记日志;用事件调度器定时清理过期数据。
| 维度 | 应用层逻辑 | 数据库自动执行 |
|---|---|---|
| 遗漏风险 | 高(依赖开发者) | 零(自动触发) |
| 跨服务一致性 | 难保证 | 数据库层统一 |
| 运维负担 | 需部署定时任务 | 事件调度器内置 |
| 可靠性 | 中等 | 最高 |
3. 触发器基础
▶ 示例:AFTER INSERT 触发器
SQL
DELIMITER //
CREATE TRIGGER trg_after_insert_user
AFTER INSERT ON users
FOR EACH ROW
BEGIN
INSERT INTO user_logs (user_id, action, created_at)
VALUES (NEW.id, 'INSERT', NOW());
END //
DELIMITER ;
▶ 示例:BEFORE UPDATE 触发器
SQL
DELIMITER //
CREATE TRIGGER trg_before_update_user
BEFORE UPDATE ON users
FOR EACH ROW
BEGIN
SET NEW.updated_at = NOW();
IF NEW.email != OLD.email THEN
SET NEW.email_verified = FALSE;
END IF;
END //
DELIMITER ;
4. NEW 与 OLD 关键字
| 触发器 | NEW | OLD |
|---|---|---|
| INSERT | 新插入的行 | 不可用 |
| UPDATE | 修改后的值 | 修改前的值 |
| DELETE | 不可用 | 被删除的行 |
5. 触发器管理
SQL
-- 查看触发器
SHOW TRIGGERS;
-- 删除触发器
DROP TRIGGER IF EXISTS trg_after_insert_user;
6. 事件调度器
▶ 示例:定时任务
SQL
-- 开启事件调度器
SET GLOBAL event_scheduler = ON;
-- 创建每天执行的事件
CREATE EVENT evt_daily_cleanup
ON SCHEDULE EVERY 1 DAY
STARTS '2026-07-04 02:00:00'
DO
DELETE FROM temp_data WHERE created_at < DATE_SUB(NOW(), INTERVAL 30 DAY);
-- 创建一次性事件
CREATE EVENT evt_one_time
ON SCHEDULE AT '2026-07-10 00:00:00'
DO
UPDATE promotions SET status = 'expired' WHERE end_date < CURDATE();
❓ 常见问题
Q 触发器能修改其他表?
A 可以。触发器中可以执行 INSERT/UPDATE/DELETE 操作其他表。
Q 触发器影响性能?
A 每行操作都会触发,批量操作时影响明显。慎用。
Q 事件调度器默认开启?
A 默认关闭。需
SET GLOBAL event_scheduler = ON; 开启。Q 触发器能调用外部程序吗?
A 不能。触发器只能执行 SQL 语句,无法调用操作系统命令或外部 API。
Q 一张表最多几个触发器?
A 同一事件同一时机只能一个触发器。即每张表最多 6 个(BEFORE/AFTER × INSERT/UPDATE/DELETE)。
📖 小节
- 触发器在数据变化时自动执行
- BEFORE 在操作前触发,AFTER 在操作后触发
- NEW 是新值,OLD 是旧值
- 事件调度器实现定时任务
📝 作业
-
基础题(难度⭐):创建触发器,自动记录用户表的变更日志。
-
进阶题(难度⭐⭐):创建 BEFORE UPDATE 触发器,自动更新 updated_at 字段。
-
挑战题(难度⭐⭐⭐):创建事件调度器,每天凌晨清理 30 天前的日志数据。