在 MariaDB 中,触发器(Triggers) 和 事件调度(Event Scheduler) 是自动化数据库操作的重要工具,分别用于响应数据变更事件和定时执行任务。
一、触发器(Triggers)
1. 核心概念
- 定义:触发器是一段与表关联的存储代码,当指定的事件(INSERT/UPDATE/DELETE)在表上发生时自动执行。
- 触发时机:BEFORE:在事件发生前执行(如验证数据合法性)。AFTER:在事件发生后执行(如记录审计日志)。
- 行级触发:针对每一行数据变更触发(FOR EACH ROW)。
2. 创建触发器
语法:
CREATE TRIGGER trigger_name
[BEFORE|AFTER] [INSERT|UPDATE|DELETE] ON table_name
FOR EACH ROW
BEGIN
-- 触发器逻辑(可使用 NEW 和 OLD 访问数据)
END;
示例 1:在插入新用户时自动记录创建时间
CREATE TRIGGER set_user_created_at
BEFORE INSERT ON users
FOR EACH ROW
BEGIN
SET NEW.created_at = NOW();
END;
示例 2:删除用户后自动备份到归档表
CREATE TRIGGER backup_deleted_user
AFTER DELETE ON users
FOR EACH ROW
BEGIN
INSERT INTO users_archive (id, name, deleted_at)
VALUES (OLD.id, OLD.name, NOW());
END;
3. 管理触发器
- 查看所有触发器:
SHOW TRIGGERS;
-- 或查询信息模式
SELECT * FROM information_schema.TRIGGERS
WHERE TRIGGER_SCHEMA = 'your_database';
- 删除触发器:
DROP TRIGGER [IF EXISTS] trigger_name;
4. 适用场景
- 数据验证:在写入前检查字段合法性。
- 审计跟踪:记录数据变更历史。
- 数据同步:跨表自动更新或归档。
- 计算字段:自动填充或更新衍生字段(如总价=单价×数量)。
5. 注意事项
- 性能影响:高频触发复杂逻辑可能拖慢写入速度。
- 事务处理:触发器中的失败会导致主操作回滚。
- 递归触发:避免触发器链式调用(如 A 触发 B,B 又触发 A)。
二、事件调度(Event Scheduler)
1. 核心概念
- 定义:事件调度器允许按计划执行 SQL 任务(类似操作系统中的 cron 任务)。
- 执行频率:支持一次性或周期性任务(如每天、每周)。
- 依赖服务:需启用 event_scheduler 组件。
2. 启用事件调度器
-- 临时启用(重启后失效)
SET GLOBAL event_scheduler = ON;
-- 永久启用(修改配置文件)
[mysqld]
event_scheduler = ON
3. 创建事件
语法:
CREATE EVENT event_name
ON SCHEDULE schedule_expression
[ON COMPLETION PRESERVE] -- 执行后保留事件定义(默认删除)
DO
BEGIN
-- 执行的 SQL 语句
END;
示例 1:每天凌晨清理 30 天前的日志
CREATE EVENT cleanup_old_logs
ON SCHEDULE EVERY 1 DAY
STARTS '2024-01-01 02:00:00'
DO
DELETE FROM logs WHERE created_at < NOW() - INTERVAL 30 DAY;
示例 2:每小时统计活跃用户并写入汇总表
CREATE EVENT aggregate_active_users
ON SCHEDULE EVERY 1 HOUR
DO
BEGIN
INSERT INTO user_stats (hour, active_count)
SELECT DATE_FORMAT(NOW(), '%Y-%m-%d %H:00:00'), COUNT(*)
FROM users WHERE last_login > NOW() - INTERVAL 1 HOUR;
END;
4. 管理事件
- 查看所有事件:
SHOW EVENTS;
-- 或查询信息模式
SELECT * FROM information_schema.EVENTS;
- 修改事件:
ALTER EVENT event_name
[RENAME TO new_name]
[ON SCHEDULE new_schedule]
[ENABLE|DISABLE];
- 删除事件:
DROP EVENT [IF EXISTS] event_name;
5. 适用场景
- 数据维护:定期清理旧数据、优化表。
- 统计报表:定时生成汇总数据。
- 数据同步:周期性同步到其他系统。
6. 注意事项
- 权限要求:创建事件需 EVENT 权限。
- 执行时间:避免在高峰时段运行耗时任务。
- 错误处理:事件失败会记录到错误日志,但不会自动重试。
- 时区设置:确保事件调度器时区与系统一致(通过 SET GLOBAL time_zone 配置)。
三、最佳实践
1. 触发器的优化
- 精简逻辑:避免在触发器中执行复杂计算或远程调用。
- 索引优化:确保触发器内查询的字段有索引。
- 避免递归:禁止触发器间接调用自身。
2. 事件调度的优化
- 错峰执行:将资源密集型任务安排在低峰时段。
- 事务控制:对大任务分批次提交,避免长事务锁表。
- 监控日志:定期检查错误日志中的事件执行记录。
3. 调试与排查
- 模拟执行:手动调用触发器逻辑或事件 SQL,验证正确性。
- 日志分析: SHOW BINLOG EVENTS; -- 查看二进制日志(需启用 binlog)
- 性能工具:使用 EXPLAIN 分析事件中的查询效率。