MySQL實現計數器的表設計及實現
阿新 • • 發佈:2019-02-02
如果是在非常高的併發之下,還是建議用記憶體資料庫redis去實現計數的功能。如果不是那麼高的併發,用表實現就可以。
DROP TABLE access_counter;
CREATE TABLE access_counter(cnt INT UNSIGNED NOT NULL
);
INSERT INTO access_counter VALUES(0);
UPDATE access_counter SET cnt=cnt+1;
SELECT * FROM access_counter;
--上面的方法在高併發性上有問題,會產生大量的鎖
DROP TABLE access_counter;
CREATE TABLE access_counter(
solt INT NOT NULL PRIMARY KEY,
cnt INT NOT NULL
);
DELIMITER $
DROP PROCEDURE IF EXISTS `proc1`$
CREATE PROCEDURE `proc1`()
BEGIN
DECLARE i INT;
SET i=0;
WHILE i<100 DO
INSERT INTO access_counter VALUES(i,0);
SET i=i+1;
END WHILE;
END$
DELIMITER ;
CALL proc1();
SELECT * FROM access_counter;
--這樣就隨機選擇一個solt進行更新
--RAND()函式呼叫可以在0和1之間產生一個隨機數
UPDATE access_counter SET cnt=cnt+1 WHERE solt=FLOOR(RAND()*100);
--如果每隔一天開始一個新的計數器,那方法是:
DROP TABLE access_counter;
CREATE TABLE access_counter(
access_day DATE NOT NULL,
solt INT NOT NULL,
cnt INT NOT NULL,
PRIMARY KEY(access_day,solt)
);
--DUPLICATE KEY UPDATE 跟Oracle的merge INTO 類似
INSERT INTO access_counter(access_day,solt,cnt)
VALUES(CURRENT_DATE,FLOOR(RAND()*100),1)
ON DUPLICATE KEY UPDATE cnt=cnt+1;
--如果不想有太多資料,那就每天刪一次
UPDATE access_counter AS a INNER JOIN
(SELECT access_day,SUM(cnt) AS cnt,MIN(solt) AS msolt FROM access_counter
GROUP BY access_day) AS b
USING (access_day)
SET a.cnt = IF(a.`solt`= b.msolt,b.cnt,0),
a.solt = IF(a.`solt`= b.msolt,0,a.`solt`);
DELETE FROM access_counter WHERE solt<>0 AND cnt=0;