MySQL 計數器表

2021-09-20 18:45:24 字數 1981 閱讀 1810

計數器表的建立

create table hit_counter(

cnt int unsigned not null

) engine = innodb;

update hit_counter 

set cnt = cnt + 1;

問題在於,對於任何想要更新這一行的事務來說,這條記錄上都有乙個全域性的互斥鎖(mutex)。這會使得這些事務只能序列執行。要獲得更高的併發更新效能,也可以將計數器儲存在多行中,每次隨機選擇一行進行更新。這樣做需要對計數器表進行如下修改:

create table hit_counter(

slot tinyint unsigned not null primary key,

cnt int unsigned not null

) engine = innodb;

然後預先在這張表增加100行資料。現在選擇乙個隨機的槽(slot)進行更新:

update hit_counter

set cnt = cnt + 1

where slot = rand() * 100;

要獲得統計結果,需要使用下面這樣的聚合查詢:

select sum(cnt)

from hit_counter;

乙個常見的需求是每隔一段時間開始乙個新的計數器(例如,每天乙個)。如果需要這麼做,則可以再簡單地修改一下表設計:

create table daily_hit_counter(

day date not null,

slot tinyint unsigned not null,

cnt int unsigned not null,

primary key(day, slot)

) engine = innodb;

在這個場景中,可以不用像前面的例子那樣預先生成行,而用on duplicate key update代替:

insert into daily_hit_counter(day, slot, cnt)

values(current_date, rand() * 100, 1)

on duplicate key update cnt = cnt + 1;

如果希望減少表的行數,以避免表變得太大,可以寫乙個週期執行的任務,合併所以結果到0號槽,並且刪除所有其他的槽:

update daily_hit_counter as c

inner join (

select day, sum(cnt) as cnt, min(slot) as mslot

from daily_hit_counter

gruop by day

) as x using(day)

set c.cnt = if(c.slot = x.mslot, x.cnt, 0),

c.slot = if(c.slot = x.mslot, 0, c.slot);

delete from daily_hit_counter where slot <> 0 and cnt = 0;

更快地讀,更慢地寫

為了提公升讀查詢的速度,經常會需要建一些額外所有,增加冗餘列,甚至是建立快取表和彙總表。這些方法會增加寫查詢的負擔,也需要額外的維護任務,但在設計高效能資料庫時,這些都是常見的技巧:雖然寫操作變得更慢了,但更顯著地提高了讀操作的效能。

然而,寫操作變慢並不是讀操作變得快所付出的唯一代價,還可能同時增加了讀操作和寫操作的開發難度。

Mysql計數器表設計

mysql create table hit counter cnt int unsigned not null engine innodb mysql update hit counter set cnt cnt 1 問題在於,對於任何想要更新這一行的事務來說,這條記錄上都有乙個全域性的互斥鎖 m...

mysql計數 mysql實現計數器

本文 如果是在非常高的併發之下,還是建議用記憶體資料庫redis去實現計數的功能。如果不是那麼高的併發,用表實現就可以。drop table access counter create table access counter cnt int unsigned not null insert int...

計數器 智慧型計數器簡介

計數器主要是應用於電子科技領域,計數器是一種運用得比較多的時序邏輯電路。計數器可以對數字進行運算,它是一種沒有辦法顯示計算結果的顯示器。隨著電子科技的不斷發展,現在的計數器也實現了智慧型功能。智慧型計數器的出現幫助我們實現了很多高強度生產問題 複雜的技術問題,並且節約了生產成本和人力成本。智慧型計數...