假设我在 MySQL/InnoDB 上有一个包含 100 万用户的用户表:
用户
- userId(主键,Int)
- 状态(整数)
- 更多数据
如果我想精确统计 status = 1
的用户数量(表示激活帐户),大表的方法是什么,我在想:
用户数
- 状态
- 计数
然后运行 TRIGGER AFTER INSERT
上users
更新 usercounts
中的相应列
这是最好的方法吗?
ps。一个额外的小问题:因为你还需要一个 TRIGGER AFTER UPDATE
上users
何时 status
更改,是否有可用的语法:
- 涵盖
TRIGGER AFTER INSERT
和TRIGGER AFTER UPDATE
上status
? - 增加
count
如果count
加一已存在,否则插入新的(status, count = 0)
一对?
最佳答案
Would this be the best way to go?
是否最好(基于意见),但这绝对是一种可行的方法。
is there a syntax available that: covers both the TRIGGER AFTER INSERT and TRIGGER AFTER UPDATE on status?
没有。 MySQL 中没有复合触发器语法。您必须创建单独的触发器。
is there a syntax available that: increments the count by one if a count already is present, else inserts a new (status, count = 0) pair?
是的。您可以在 INSERT
语句中使用 ON DUPLICATE KEY
子句。确保 status
是 usercounts
表中的 PK。
现在,如果可以删除用户,即使只是出于维护目的,您也需要使用 AFTER DELETE
触发器来覆盖它。
话虽这么说,你的触发器可能看起来像这样
CREATE TRIGGER tg_ai_users
AFTER INSERT ON users
FOR EACH ROW
INSERT INTO usercounts (status, cnt)
VALUES (NEW.status, 1)
ON DUPLICATE KEY UPDATE cnt = cnt + 1;
CREATE TRIGGER tg_ad_users
AFTER DELETE ON users
FOR EACH ROW
UPDATE usercounts
SET cnt = cnt - 1
WHERE status = OLD.status;
DELIMITER $$
CREATE TRIGGER tg_au_users
AFTER UPDATE ON users
FOR EACH ROW
BEGIN
IF NOT NEW.status <=> OLD.status THEN -- proceed ONLY if status has been changed
UPDATE usercounts
SET cnt = cnt - 1
WHERE status = OLD.status;
INSERT INTO usercounts (status, cnt) VALUES (NEW.status, 1)
ON DUPLICATE KEY UPDATE cnt = cnt + 1;
END IF;
END$$
DELIMITER ;
最初填充usercounts
表使用
INSERT INTO usercounts (status, cnt)
SELECT status, COUNT(*)
FROM users
GROUP BY status
这里是SQLFiddle 演示
关于mysql - InnoDB 和计数 : Are helper tables the way to go?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20926149/