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