MySQL—触发器详解

基本介绍

触发器是与表有关的数据库对象,在 INSERT、UPDATE、DELETE 操作之前或之后触发并执行触发器中定义的 SQL 语句。

触发器的这种特性可以协助应用在数据库端确保数据的完整性、日志记录、数据校验等操作。

使用别名 NEW 和 OLD 来引用触发器中发生变化的记录内容,这与其他的数据库是相似的。

现在触发器还只支持行级触发,不支持语句级触发。

触发器类型 OLD的含义 NEW的含义
INSERT 型触发器 无 (因为插入前状态无数据) NEW 表示将要或者已经新增的数据
UPDATE 型触发器 OLD 表示修改之前的数据 NEW 表示将要或已经修改后的数据
DELETE 型触发器 OLD 表示将要或者已经删除的数据 无 (因为删除后状态无数据)

基本操作

创建触发器

sql 复制代码
DELIMITER $

CREATE TRIGGER 触发器名称
BEFORE|AFTER  INSERT|UPDATE|DELETE
ON 表名
FOR EACH ROW  -- 行级触发器
BEGIN
	触发器要执行的功能;
END$

DELIMITER ;

查看触发器的状态、语法等信息

sql 复制代码
SHOW TRIGGERS;

删除触发器,如果没有指定 schema_name,默认为当前数据库

sql 复制代码
DROP TRIGGER [schema_name.]trigger_name;

注意事项

  • 确保触发器中的逻辑不影响性能,尤其是在高频操作的表上。
  • 避免在触发器中出现无限循环的情况,例如更新触发器又触发了同一操作。

代码示例

通过触发器记录账户表的数据变更日志。包含:增加、修改、删除。

数据准备

sql 复制代码
CREATE TABLE accounts
(
    id         INT AUTO_INCREMENT PRIMARY KEY,                                 -- 账户ID
    username   VARCHAR(50)  NOT NULL UNIQUE,                                   -- 用户名,必须唯一
    password   VARCHAR(255) NOT NULL,                                          -- 密码,建议加密存储
    email      VARCHAR(100) NOT NULL UNIQUE,                                   -- 邮箱,必须唯一
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,                            -- 创建时间,默认当前时间
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP -- 更新时间,自动更新
);
CREATE TABLE account_change_log
(
    log_id         INT AUTO_INCREMENT PRIMARY KEY,      -- 日志ID
    account_id     INT,                                 -- 被更改的账户ID
    operation_type VARCHAR(10),                         -- 操作类型:INSERT, UPDATE, DELETE
    old_value      VARCHAR(255),                        -- 更新前的值
    new_value      VARCHAR(255),                        -- 更新后的值
    changed_at     TIMESTAMP DEFAULT CURRENT_TIMESTAMP, -- 变更时间,默认当前时间
    FOREIGN KEY (account_id) REFERENCES accounts (id)   -- 外键约束,引用账户表
);
# 创建 INSERT 型触发器
-- 更改存储过程的结束符为$$
DELIMITER $$
-- 创建一个触发器,在accounts表插入数据后触发
CREATE TRIGGER after_account_insert
    AFTER INSERT
    ON accounts
    FOR EACH ROW
BEGIN
    -- 将插入操作记录到account_change_log表中
    INSERT INTO account_change_log (account_id, operation_type, new_value)
    VALUES (NEW.id, 'INSERT', NEW.username); -- 记录新增账户的用户名
END $$
-- 复原存储过程的结束符为默认的;
DELIMITER ;

# 创建 UPDATE 型触发器
-- 再次更改存储过程的结束符为$$
DELIMITER $$
-- 创建一个触发器,在accounts表更新数据后触发
CREATE TRIGGER after_account_update
    AFTER UPDATE
    ON accounts
    FOR EACH ROW
BEGIN
    -- 将更新操作记录到account_change_log表中
    INSERT INTO account_change_log (account_id, operation_type, old_value, new_value)
    VALUES (OLD.id, 'UPDATE', OLD.username, NEW.username); -- 记录更新前后的用户名
END $$
-- 复原存储过程的结束符为默认的;
DELIMITER ;

-- 创建 DELETE 型触发器
-- 再次更改存储过程的结束符为$$
DELIMITER $$
-- 创建一个触发器,在accounts表删除数据后触发
CREATE TRIGGER after_account_delete
    AFTER DELETE
    ON accounts
    FOR EACH ROW
BEGIN
    -- 将删除操作记录到account_change_log表中
    INSERT INTO account_change_log (account_id, operation_type, old_value)
    VALUES (OLD.id, 'DELETE', OLD.username); -- 记录删除账户的用户名
END $$
-- 复原存储过程的结束符为默认的;
DELIMITER ;
sql 复制代码
# 插入测试:执行上述插入操作后,可以查看 account_change_log 表,确认新用户的插入记录是否正确。
INSERT INTO accounts (username, password, email) VALUES
('user1', 'password1', 'user1@example.com'),
('user2', 'password2', 'user2@example.com'),
('user3', 'password3', 'user3@example.com');
sql 复制代码
# 更新测试:更新某个用户的信息,查看 account_change_log 表,确认更新的记录是否正确。
UPDATE accounts SET username = 'updated_user1' WHERE id = 1;
sql 复制代码
# 删除测试:删除某个用户,查看 account_change_log 表,确认删除的记录是否正确。
DELETE FROM accounts WHERE id = 2;

参考资料

相关推荐
for_ever_love__2 分钟前
MySQL SELECT 与 WHERE 优化实战:可搜索条件、联合索引与执行计划
数据库·mysql·oracle·select·where·条件优化·查询优化技巧
2501_9318037514 分钟前
MySQL 锁机制详解
数据库·mysql
Nturmoils35 分钟前
SQL 编辑器不只是写查询:我用 KStudio 排查一次订单异常
数据库
IvorySQL1 小时前
PostgreSQL 日报|逻辑解码 DDL 子事务缺陷修复(10 月 12 日)
数据库·postgresql
这个DBA有点耶1 小时前
研发规模/投入最大的国产数据库厂商是谁?拆解五个衡量维度
数据库·程序员·产品
葡萄城技术团队2 小时前
数据库里的数据明明是对的,为什么 BI 报表还是错?
数据库
野生数据人2 小时前
日志平台每日巡检我压成了一条命令链:从 SHOW BACKENDS 到扩缩容的完整步骤
大数据·数据库
bmxy小明同学2 小时前
2026-10-09-token与成本
java·前端·数据库
路远的数据库笔记2 小时前
Oracle报ORA-00020连接打满?从专用进程模型到静态参数,一次生产排查全记录
数据库·oracle·国产数据库·ora-00020·dba实战·sharedserver
瀚高PG实验室2 小时前
瀚高数据库序列介绍、使用及值不连续、重复写入等现象处理
数据库·postgresql·瀚高数据库