首先也是最重要的,因为 MySQL 触发器是基于行的,因此无需重新计算所有统计信息,而是一次应用更改一条记录。
其次,您可以利用INSERT INTO ... ON DUPLICATE KEY UPDATE
它来简化您的代码。要使其正常工作,您必须对表中的列进行PRIMARY KEY
orUNIQUE
约束。date
statistics
据说INSERT
s 和DELETE
s 进出您的transactions
表的触发器是非常简单的单语句触发器(因此您甚至不需要更改DELIMITER
和使用BEGIN ... END
block)
CREATE TRIGGER tg_ai_transactions
AFTER INSERT ON transactions
FOR EACH ROW
INSERT INTO statistics (date, bought, sold)
VALUES (NEW.tran_date,
CASE WHEN NEW.tran_type = 'buy' THEN 1 ELSE 0 END,
CASE WHEN NEW.tran_type = 'sale' THEN 1 ELSE 0 END)
ON DUPLICATE KEY UPDATE bought = bought + VALUES(bought),
sold = sold + VALUES(sold);
CREATE TRIGGER tg_ad_transactions
AFTER DELETE ON transactions
FOR EACH ROW
UPDATE statistics
SET bought = bought - CASE WHEN OLD.tran_type = 'buy' THEN 1 ELSE 0 END,
sold = sold - CASE WHEN OLD.tran_type = 'sale' THEN 1 ELSE 0 END
WHERE date = OLD.tran_date;
现在UPDATE
s 有点棘手,因为日期和交易类型都可能更改。因此,我们使用OLD
值来减去更新前状态下的行的值,然后应用NEW
值。
DELIMITER $$
CREATE TRIGGER tg_au_transactions
AFTER UPDATE ON transactions
FOR EACH ROW
BEGIN
UPDATE statistics
SET bought = bought - CASE WHEN OLD.tran_type = 'buy' THEN 1 ELSE 0 END,
sold = sold - CASE WHEN OLD.tran_type = 'sale' THEN 1 ELSE 0 END
WHERE date = OLD.tran_date;
INSERT INTO statistics (date, bought, sold)
VALUES (NEW.tran_date,
CASE WHEN NEW.tran_type = 'buy' THEN 1 ELSE 0 END,
CASE WHEN NEW.tran_type = 'sale' THEN 1 ELSE 0 END)
ON DUPLICATE KEY UPDATE bought = bought + VALUES(bought),
sold = sold + VALUES(sold);
END$$
DELIMITER ;
这是SQLFiddle演示