Mysql 13: 触发器全解——创建、查看、使用与注意事项

触发器(Trigger)是与表相关联的特殊存储过程 ,它不能手动调用 ,而是在执行 INSERT/UPDATE/DELETE 操作时自动触发。常用于数据审计、日志记录、数据校验、级联操作。


一、触发器核心概念

1. 触发时机与事件

  • 触发事件 :INSERT、UPDATE、DELETE。
  • 触发时机 :
    • BEFORE:操作执行前触发(常用于数据校验、预处理)。
    • AFTER:操作执行后触发(常用于日志记录、级联更新)。
  • 触发对象 :FOR EACH ROW(行级触发,每影响一行执行一次)。

2. 核心限制

  • 不支持 SELECT 语句(直接返回结果)。
  • 不支持事务回滚(InnoDB 中,触发器执行失败会导致主事务回滚)。
  • 一个表同一事件同一时机只能有一个触发器。

二、创建触发器(核心代码)

1. 基础语法

sql 复制代码
DELIMITER //  -- 修改结束符,避免与内部;冲突
CREATE TRIGGER 触发器名
{BEFORE | AFTER} {INSERT | UPDATE | DELETE}
ON 表名 FOR EACH ROW
BEGIN
    -- 触发器体:SQL 语句集合
    -- 引用旧数据: OLD (修改前的值)
    -- 引用新数据: NEW (修改后的值)
END //
DELIMITER ;  -- 恢复结束符

2. 场景一:创建只有一个执行语句的触发器

需求:在学生表插入数据时,自动记录操作日志到日志表。

sql 复制代码
-- 1. 准备测试表
CREATE TABLE student (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(20) NOT NULL,
    age INT NOT NULL
);

CREATE TABLE log (
    id INT PRIMARY KEY AUTO_INCREMENT,
    operation VARCHAR(20) NOT NULL,
    operate_time DATETIME NOT NULL,
    table_name VARCHAR(20) NOT NULL,
    record_id INT NOT NULL
);

-- 2. 创建触发器
DELIMITER //
CREATE TRIGGER tr_student_insert
AFTER INSERT  -- 插入操作后触发
ON student FOR EACH ROW
BEGIN
    -- 记录日志:NEW.id 是刚插入的学生ID
    INSERT INTO log(operation, operate_time, table_name, record_id)
    VALUES ('INSERT', NOW(), 'student', NEW.id);
END //
DELIMITER ;

-- 3. 测试:插入一条学生数据
INSERT INTO student (name, age) VALUES ('张三', 18);

-- 4. 查看日志表:触发器自动插入了一条日志
SELECT * FROM log;

3. 场景二:创建有多个执行语句的触发器

需求:更新学生年龄时,记录新旧年龄对比日志。

sql 复制代码
DELIMITER //
CREATE TRIGGER tr_student_update
AFTER UPDATE  -- 更新操作后触发
ON student FOR EACH ROW
BEGIN
    -- 多个执行语句用 ; 分隔
    INSERT INTO log(operation, operate_time, table_name, record_id)
    VALUES ('UPDATE', NOW(), 'student', OLD.id);
    
    -- 记录新旧值差异
    IF OLD.age != NEW.age THEN
        INSERT INTO log(operation, operate_time, table_name, record_id)
        VALUES (CONCAT('AGE_CHANGE:', OLD.age, '->', NEW.age), NOW(), 'student', NEW.id);
    END IF;
END //
DELIMITER ;

-- 测试:修改年龄
UPDATE student SET age = 20 WHERE id = 1;

三、查看触发器

1. 利用 SHOW TRIGGERS 查看

sql 复制代码
SHOW TRIGGERS;
-- 查看特定数据库的触发器
SHOW TRIGGERS FROM 数据库名;

说明:列出所有触发器的详细信息(名称、表、事件、时机)。

2. 在 triggers 表中查看详细信息

从系统数据库 information_schema 中查询,支持更精准的筛选:

sql 复制代码
SELECT * FROM information_schema.TRIGGERS
WHERE TRIGGER_NAME = 'tr_student_insert' AND TRIGGER_SCHEMA = DATABASE();

关键字段:

  • EVENT_MANIPULATION:触发事件 (INSERT/UPDATE/DELETE)。
  • ACTION_TIMING:触发时机 (BEFORE/AFTER)。
  • ROUTINE_BODY:执行体语言 (SQL)。

四、触发器的使用(自动触发)

触发器无需手动调用,当触发事件发生时自动执行。

  • INSERT :插入数据时,NEW 字段有效。
  • UPDATE :更新数据时,OLD 和 NEW 字段有效。
  • DELETE :删除数据时,OLD 字段有效。

五、删除触发器

sql 复制代码
DROP TRIGGER [IF EXISTS] 触发器名;
-- 示例
DROP TRIGGER IF EXISTS tr_student_insert;

注意:删除触发器需具有 SUPER 权限或相关权限。


六、触发器的注意事项(避坑核心)

1. 性能与维护

  • 慎用触发器:触发器是隐式执行的,调试困难,会增加数据库开销。
  • 避免级联循环:触发器内操作同一张表,可能导致死循环。
  • 索引优化:触发器内的 SQL 语句必须优化,避免全表扫描。

2. 数据一致性

  • InnoDB 事务 :在 InnoDB 中,触发器执行失败会导致主事务(如 INSERT)回滚 。
    • 例:INSERT 学生成功,触发器 INSERT 日志失败 → 学生数据也会被回滚。
  • MyISAM 不支持事务:触发器执行失败,主操作可能已完成,数据不一致。

3. 数据迁移与备份

  • 迁移数据库时,触发器不会自动复制,需要手动导出创建语句。
  • 使用 mysqldump --triggers 导出触发器。

4. 常见错误陷阱

  • 在触发器中使用 SELECT ... INTO
相关推荐
Tapdata42 分钟前
被忽略的第三类上下文:Agent 进入真实业务后,还缺什么?
数据库·人工智能·架构
小科先生2 小时前
Java springboot调用数据库的基本流程
java·数据库·spring boot
星恒随风2 小时前
MySQL 从零入门(四):表的增删改查与基础查询详解
linux·服务器·数据库·笔记·mysql
Pniubi4 小时前
MySQL靠什么实现事务的?事务隔离级别有哪些?
java·数据库·mysql
数据库小学妹4 小时前
pgbouncer 事务池:prepared statement、临时表与会话状态
数据库·后端·postgresql
aiks_yuan4 小时前
MySQL 死锁怎么排查:看懂 INNODB STATUS 死锁日志,先查后插为什么必死锁(MySQL 8.2 实测)
mysql
Lucifer三思而后行6 小时前
最近折腾了一下金仓数据库的备份恢复
数据库·备份恢复
草莓熊Lotso7 小时前
【C++ 基于微服务的即时通讯系统】文件存储子服务实战:UUID生成、文件IO封装与全接口单元测试
开发语言·网络·数据库·c++·微服务·架构·单元测试
进击的荆棘7 小时前
MySQL——库的操作
数据库·mysql
2601_967980118 小时前
“小程序·云开发”上线 助力开发者的高效利器
数据库·存储管理·小程序云开发·云函数·开发者工具