MySQL 中的存储过程、触发器与事件调度器面试要点

在 MySQL 面试中,除了增删改查和索引优化,存储过程、触发器与事件调度器这“三件套”经常被用来考察候选人对数据库编程能力、自动化机制以及底层原理的理解。本文从面试高频问题出发,梳理核心要点,帮助你系统掌握。

一、存储过程

1. 什么是存储过程?它和函数有什么区别?

存储过程是一组预编译的 SQL 语句集合,存储在数据库中,可通过 CALL 调用。它支持输入输出参数、流程控制、事务控制,适合封装复杂业务逻辑。

与函数的区别:

  • 存储过程用 CALL 调用,函数用 SELECT 调用;
  • 存储过程可以有多个返回值(通过 OUT 参数),函数只能返回一个值;
  • 存储过程可以执行 DML/DDL 和事务,函数通常只做计算,且不能执行事务;
  • 函数可以嵌入 SQL 中使用,存储过程不能。

2. 存储过程的优缺点

优点:

  • 减少网络传输,一次调用执行多条 SQL;
  • 预编译,性能较好;
  • 代码复用,集中管理业务逻辑;
  • 权限控制更细,可只授予 EXECUTE 权限。

缺点:

  • 调试困难,可移植性差;
  • 业务逻辑分散在数据库层,不利于版本管理和微服务拆分;
  • 过度使用会增加数据库 CPU 负担。

3. 面试常问:如何查看和删除存储过程?

SHOW PROCEDURE STATUS WHERE Db = 'test';
SHOW CREATE PROCEDURE proc_name;
DROP PROCEDURE IF EXISTS proc_name;

4. 存储过程中的异常处理

使用 DECLARE ... HANDLER

DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
  ROLLBACK;
  SELECT 'error occurred';
END;

常见考点:CONTINUEEXIT 的区别,以及如何配合事务使用。

二、触发器

1. 触发器的基本概念

触发器是与表关联的、在 INSERTUPDATEDELETE 操作前后自动执行的 SQL 代码块。MySQL 只支持行级触发器,不支持语句级触发器。

语法要点:

CREATE TRIGGER trg_name
BEFORE INSERT ON table_name
FOR EACH ROW
BEGIN
  -- 逻辑
END;

2. BEFORE 与 AFTER 触发器的区别

  • BEFORE:在数据修改前执行,可修改 NEW 值,常用于数据校验、格式化;
  • AFTER:在数据修改后执行,只能读取 NEW,常用于日志记录、级联更新。

3. NEW 和 OLD 关键字

  • INSERT:只有 NEW
  • DELETE:只有 OLD
  • UPDATE:既有 NEW 也有 OLD

面试常问:如何在触发器中修改即将插入的值?答:只能在 BEFORE INSERT 中通过 SET NEW.col = value 修改。

4. 触发器的限制与注意事项

  • 不能对同一张表进行显式查询或修改,否则可能报错“Can't update table … already used”;
  • 触发器执行失败会导致原操作回滚(对于事务表);
  • 触发器隐式执行,难以调试,容易造成死锁或性能问题;
  • MySQL 5.7 之前不支持一个表多个同类型触发器,5.7+ 支持但需注意顺序。

5. 面试题:触发器与存储过程的区别?

触发器是自动执行的,不能传参;存储过程需要显式调用,可传参。触发器依附于表,存储过程独立存在。

三、事件调度器

1. 什么是事件调度器?

事件调度器是 MySQL 的定时任务机制,类似 Linux 的 crontab,可以在指定时间或周期执行 SQL。它由事件调度线程管理,需要开启 event_scheduler

查看与开启:

SHOW VARIABLES LIKE 'event_scheduler';
SET GLOBAL event_scheduler = ON;

2. 创建事件示例

CREATE EVENT ev_clean
ON SCHEDULE EVERY 1 DAY
STARTS '2025-01-01 00:00:00'
DO
  DELETE FROM logs WHERE created_at < NOW() - INTERVAL 30 DAY;

支持 ATEVERYSTARTSENDSON COMPLETION 等子句。

3. 事件调度器与操作系统的 cron 对比

  • 事件调度器在 MySQL 内部运行,不依赖外部脚本;
  • 精度可达秒级,但受数据库负载影响;
  • 需要数据库常驻运行,且 event_scheduler 开启;
  • 权限要求较高,通常需要 EVENT 权限。

4. 面试常问:事件调度器是否会影响主从复制?

会。事件在 master 上执行后,会写入 binlog 并复制到 slave。如果 slave 也开启了 event_scheduler,可能导致事件重复执行。因此通常建议 slave 关闭事件调度器,或使用 DISABLE ON SLAVE

5. 如何查看和管理事件?

SHOW EVENTS;
SELECT * FROM information_schema.EVENTS;
ALTER EVENT ev_name ON COMPLETION PRESERVE DISABLE;
DROP EVENT IF EXISTS ev_name;

四、综合面试题精选

  1. 存储过程、触发器、事件调度器分别适合什么场景?
    存储过程适合封装复杂业务逻辑;触发器适合数据校验、审计日志、级联操作;事件调度器适合定时清理、统计汇总。

  2. 三者中谁可以调用事务?
    存储过程和事件可以显式使用事务;触发器在事务中隐式执行,不能单独提交或回滚。

  3. 触发器会导致死锁吗?
    会。如果触发器内操作其他表,且与外部事务加锁顺序不一致,可能形成死锁。

  4. 如何调试存储过程?
    可使用 SELECT 输出中间变量,或借助 MySQL Workbench 调试器,也可用日志表记录执行轨迹。

  5. 事件调度器未执行的可能原因?
    event_scheduler 未开启、事件被禁用、ON COMPLETION NOT PRESERVE 导致执行后删除、时间未到、权限不足。

五、总结

存储过程、触发器和事件调度器是 MySQL 中实现数据库编程与自动化的核心工具。面试中不仅要掌握语法,更要理解它们的适用场景、限制、对性能与复制的影响。回答时结合具体案例,比如“用触发器记录用户操作日志”“用事件每天凌晨归档数据”,能显著提升说服力。建议在本地环境动手实践,观察执行计划和锁行为,做到知其然也知其所以然。

未经允许不得转载:任鹏个人博客 » MySQL 中的存储过程、触发器与事件调度器面试要点

赞 (0) 打赏

评论 0

取消
  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏