使用的是MySQL数据库
1. 触发器
- 触发器是在插入、更新或删除语句前后自动执行的一堆SQL代码。
- 触发器的作用(2个):1)增强数据一致性;2)记录对数据库的修改(创建审计表进行记录);
- 触发器的命名规则(取个能自己一眼看懂的),比如payments_after_insert(payments是触发器关联的表;after表示在sql语言触发之后,如果是之前可以用before;insert表示点燃触发器的sql语句),这个名字的意思就是在对payments表执行插入语句之后点燃触发器。当然这只是触发器的名字,并不能让MySQL知道我们要它干嘛。
- 注意:触发器可以修改任何表中的数据,除了这个触发器所在的表,因为触发器会自燃,如果触发器修改自己所在的表,就会陷入永无止尽的循环。
DELIMITER $$
CREATE TRIGGER payments_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;
END $$
DELIMITER ;
INSERT INTO payments
VALUES (DEFAULT,5,2,'2022-1-10',50,1);
DELIMITER $$
DROP TRIGGER IF EXISTS payments_after_delete;
CREATE TRIGGER payments_after_delete
AFTER DELETE ON payments
FOR EACH ROW
BEGIN
UPDATE invoices
SET payment_total = payment_total - OLD.amount
WHERE invoice_id = OLD.invoice_id;
END $$
DELIMITER ;
2. 查看触发器
SHOW TRIGGERS;
SHOW TRIGGERS LIKE 'payments%';
3. 删除触发器
DROP TRIGGER IF EXISTS payments_after_insert;
4. 使用触发器进行审计(触发器的第二个作用)
- 实际工作中需要为多张表记录变更,每张表添加触发器太重复劳动了,不建议为每张表创建审计表;(学到设计数据库,会教建立一个总架构来记录变更,也就是要创建一个总审计表)
DELIMITER $$
DROP TRIGGER IF EXISTS payments_after_delete;
CREATE TRIGGER payments_after_delete
AFTER DELETE ON payments
FOR EACH ROW
BEGIN
UPDATE invoices
SET payment_total = payment_total - OLD.amount
WHERE invoice_id = OLD.invoice_id;
INSERT INTO payments_audit
VALUES (OLD.client_id,OLD.date,OLD.amount,'Delete',NOW());
END $$
DELIMITER ;
- 结果显示 - 对payments表做插入或删除操作后,查询payments_audit表

5. 事件
- 事件是根据计划执行的任务或一堆SQL代码,可以只执行一次或者按照某种规律执行,帮助我们自动化数据库维护任务。
- 在设计事件前,需要先打开MySQL事件调度器。
SHOW VARIABLES;
SHOW VARIABLES LIKE 'event%';
SET GLOBAL event_scheduler = ON;
- 显示查询事件调度器

5.1 创建事件
DELIMITER $$
CREATE EVENT yearly_delete_stale_audit_rows
ON SCHEDULE
EVERY 1 YEAR STARTS '2022-01-01' ENDS '2029-01-01'
DO BEGIN
DELETE FROM payments_audit
WHERE action_date < DATE_SUB(NOW(),INTERVAL 1 YEAR);
END $$
DELIMITER ;
6. 查看、删除和修改事件
SHOW EVENTS;
SHOW EVENTS LIKE 'yearly%';
DROP EVENT IF EXISTS yearly_delete_stale_auidt_rows;
ALTER EVENT yearly_delete_stale_auidt_rows DISABLE;