1 Trigger触发器
TRIGGER 是在插入、更新、删除语句前后自动执行的一段sql语句,分为INSERT/update/delete
- insert
DROP TRIGGER IF EXISTS PAYMENTS_AFTER_INSERT;
DELIMITER $$
CREATE TRIGGER PAYMENTS_AFTER_INSERT
AFTER INSERT ON PAYMENTS -- 触发器可以修改任何表数据,但不能修改所在表,即这个。
FOR EACH ROW
BEGIN
UPDATE INVOICES I
SET PAYMENT_TOTAL = PAYMENT_TOTAL + NEW.AMOUNT
WHERE I.INVOICE_ID = NEW.INVOICE_ID;
INSERT INTO PAYMENTS_AUDIT -- 加入审计表中
VALUES (NEW.CLIENT_ID,NEW.DATE,NEW.AMOUNT,'INSERT',NOW());
END $$
DELIMITER ;
- 执行insert
SET SQL_SAFE_UPDATES=0; -- 关闭更新的安全模式
INSERT INTO PAYMENTS
VALUES (DEFAULT,5,3,'2019-01-01',10,1);
-- delete审计
-- 创建trigger
DROP TRIGGER IF EXISTS PAYMENTS_AFTER_DELETE;
DELIMITER $$
CREATE TRIGGER PAYMENTS_AFTER_DELETE
AFTER DELETE ON PAYMENTS -- 触发器可以修改任何表数据,但不能修改所在表,即这个。
FOR EACH ROW
BEGIN
UPDATE INVOICES I
SET PAYMENT_TOTAL = PAYMENT_TOTAL - OLD.AMOUNT
WHERE I.INVOICE_ID = OLD.INVOICE_ID;
INSERT INTO PAYMENTS_AUDIT -- 加入审计表中
VALUES (OLD.CLIENT_ID, OLD.DATE, OLD.AMOUNT, 'DELETE', NOW());
END $$
DELIMITER ;
-- 执行delete审计
DELETE
FROM PAYMENTS
WHERE PAYMENT_ID = 13;
- 查看triggers
SHOW TRIGGERS LIKE 'PAYMENT%';
2 Event 事件
可以自动执行的一段sql,自动化数据库维护
SHOW VARIABLES LIKE 'EVENT%'; -- 查看sql变量
SET GLOBAL EVENT_SCHEDULER = 'ON'; -- 打开
-- 创建一个event
DELIMITER $$
CREATE EVENT HOUSLY_DELETE_AUDIT_ROWS
ON SCHEDULE
EVERY 1 HOUR STARTS '2021-06-01' ENDS '2021-07-01'
DO BEGIN
DELETE FROM PAYMENT_AUDIT
WHERE ACTION_DATE < NOW();
END $$
DELIMITER ;
-- SHOW
SHOW EVENTS;
DROP EVENT IF EXISTS HOUSLY_DELETE_AUDIT_ROWS;
ALTER EVENT HOUSLY_DELETE_AUDIT_ROWS DISABLE -- 关闭event
3 TRANSACTION 事务
使用事务处理(transaction processing),通过确保成批的SQL操作要么完全执行,要么完全不执行,来维护数据库的完整性。
USE SQL_STORE;
START TRANSACTION;
INSERT INTO ORDERS (CUSTOMER_ID, ORDER_DATE, STATUS )
VALUES (1,'2019-01-01',1);
INSERT INTO ORDER_ITEMS
VALUES (last_insert_id(),1,1,1);
COMMIT; -- rollback
并发与锁定 并发:多个用户同时访问同一个数据,因此当用户改变数据时,就有问题
– MYSQL默认机制是,当两个以上用户同时修改统一数据时,会按照提交的先后顺序进行修改。
USE SQL_STORE;
START TRANSACTION;
UPDATE CUSTOMERS
SET POINTS = pointS+10
WHERE CUSTOMER_ID = 1;
COMMIT;
– 常见的并发问题
-
dirty read
通过加入限制来解决。让只读已提交的数据。例如:user1给了客户a20积分,但没有提交,此时user2查看客户积分进行打折.如果user1进行rollbac,即user2拿到了不属于客户的积分数据,未提交的数据,由此是dirty data.
-
non-repeating
可以加入事务隔离级别,即使其他用户修改了数据,也使得数据和最开始读取的数据一致.例如:user1 读取客户数据积分a(未提交),user2修改了客户积分b,user1再次读取客户积分b,由此产生数据不一样。
-
phantom read 幻读
可以设置事务隔离级别,按照先后顺序。例如:事务A读取客户积分,事务B修改了一个客户的积分,且未返回,事务A查询的就会发生变化,无法在查询中看到。—
4个隔离级别
读未提交 -> 读已提交 -> 可重复读取 -> 可序化 、
针对以上三个并发问题,采用2,3,4等级即可解决。
– 随着限制级越高,所需要计算资源也就越大,但可以解决的并发问题就越多。综合起来优先选择repeated read第三级。
– 查看当前隔离级别
SHOW VARIABLES LIKE 'TRANSACTION%'
– 读未提交级别 read uncommitted / read committed / read repeat /