MySQL高阶:触发器和事件

发布于:2024-07-03 ⋅ 阅读:(49) ⋅ 点赞:(0)

1. 触发器

创建触发器

触发器是在增删改语句前后自动执行的一段SQL代码,通常我们使用触发器来保持数据的一致性。

创建触发器的语法要点:命名三要素,触发条件语句和触发频率语句,主体中 OLD/NEW 的使用。

  1. 命名习惯(遵守命名三要素):触发表_before/after(表示SQL语句执行之前或之后触发)_触发的SQL语句类型。
  2. 触发条件语句:BEFORE/AFTER INSERT/UPDATE/DELETE ON 触发表。
  3. 触发频率语句:这里 FOR EACH ROW 表明每一个受影响的行都会启动一次触发器。其它有的DBMS还支持表级别的触发器,即不管插入一行还是五行都只启动一次触发器。
  4. 主体:主体里可以对各种表的数据进行修改以保持数据一致性,但注意唯一不能修改的表是触发表,否则会引发无限循环(“触发器自燃”),主体中最关键的是使用 NEW/OLD 关键字来指代受影响的新/旧行(若INSERT用NEW,若DELETE用OLD,若UPDATE似乎理论上两个都可以用,但应该要用NEW)并可采用 ‘点+字段’ 来引用这些行的相应属性。

案例:一张发票对应多个付款,该发票下的付款金额变动时,发票下的总金额随之变化。

DELIMITER $$
CREATE TRIGGER payment_after_insert   -- 命名习惯
    AFTER INSERT ON payments   -- 触发条件语句
    FOR EACH ROW        -- 触发频率语句
BEGIN
    UPDATE invoices
    SET payment_total = payment_total + NEW.amount
    WHERE invoice_id = NEW.invoice_id;     -- 注意NEW和OLD的使用
END $$
DELIMITER ;

查看触发器

命令: SHOW TRIGGERS
筛选用LIKE字符串关键字赖查找,如 SHOW TRIGGERS LIKE ‘payments%’

删除触发器

命令:DROP TRIGGER [IF EXISTS] X_X_X,IF EXISTS是可选的一般都加上。
NOTE: 最好将删除和创建数据库/视图/储存过程/触发器的语句放在同一个脚本中(即将删除语句放在创建语句前,DROP IF EXISTS + CREATE,用于创建或更新数据库/视图/储存过程/触发器,等效于 CREATE OR REPLACE,但分成了两个语句)并将脚本录入源码库中,这样不仅团队都可以创建相同的数据库,还都能查看数据库的所有修改历史(查看每个版本)

使用触发器进行审计

触发器的另一个用途:为了审核的目的将修改数据的操作记录在日志里。
方法:建立一个审核表(日志表)以记录谁在什么时间做了什么修改,实现方法就是在触发器里加上创建日志记录的语句,日志记录应包含修改内容信息和操作信息两部分。

创建审计表:

CREATE TABLE payments_audit
(
    client_id     INT              NOT NULL,
    date          DATE             NOT NULL,
    amount        DECIMAL(9, 2)    NOT NULL,
    action_type   VARCHAR(50)      NOT NULL,
    action_date   DATETIME         NOT NULL
)

在每个触发器中,每触发一次再审计表中记录一次数据。添加代码如下:

INSERT INTO payments_audit
VALUES (NEW.client_id, NEW.date, NEW.amount, 'insert', NOW());
INSERT INTO payments_audit
VALUES (OLD.client_id, OLD.date, OLD.amount, 'delete', NOW());

NOTE: 实际运用中不会为数据库中的每张表建立一个审核表,相反,会有一个整体架构,通过一个总审核表来记录,这在之后设计数据库中会讲到.

2. 事件

事件是一段根据计划执行的代码,可以执行一次,或者按某种规律执行,比如每天早上10点或每月一次.
通过事件我们可以自动化数据库维护任务,比如删除过期数据、将数据从一张表复制到存档表或者汇总数据生成报告,所以事件十分有用。

前期工作:打开MySQL事件调度器(event_scheduler),这是一个时刻寻找需要执行的事件的后台程序。

查看MySQL所有系统变量:

SHOW VARIABLES LIKE 'event%';
SET GLOBAL event_scheduler = ON   -- 不用的时候将其关闭
DELIMITER $$
CREATE EVENT yearly_delete_stale_audit_row
-- 设定事件执行计划
ON SCHEDULE
    EVERY 1 YEAR STARTS '2019-01-01' ENDS '2029-01-01'
-- 执行部分
DO BEGIN
    DELETE FROM payments_audit
    WHERE action_date = NOW() - INTERVAL 1 YEAR;
END $$
DELIMITER ;
  1. 命 名 : 用 时 间 间 隔 ( 频 率 ) 开 头 , 可 以 方 便 之 后 分 类 检 索 , 时 间 间 隔 ( 频 率 ) 包 括once/hourly/daily/monthly/yearly 等等
  2. 执行计划:
    • 规律性周期性执行用 EVERY 关键字,可以是 EVERY 1 HOUR / EVERY 2 DAY 等等
    • 若只执行一次就用 AT 关键字,如:AT ‘2019-05-01’
    • 开始(STARTS)和结束(ENDS)时间都是可选的
  3. NOW() - INTERVAL 1 YEAR 等 效 于 DATE_ADD(NOW(), INTERVAL -1 YEAR) 或 DATE_SUB(NOW(), INTERVAL 1YEAR),也可以直接相加减(但INTERVAL关键字还是要用)

查看、删除和更改事件

  • 查看:SHOW EVENTS [LIKE ‘ ’];
  • 删除:DROP EVENT IF EXISTS X_X_X;
  • 更改:ALTER EVENT X_X_X [DOSABLE/ENABLE]
  1. 如果要修改事件内容(包括执行计划和主体内容),直接把 ALTER 当 CREATE 用(或者说更像是REPLACE)直接重建语句
  2. 暂时地启用或停用事件(用 DISABLE 和 ENABLE 关键字)

网站公告

今日签到

点亮在社区的每一天
去签到