计数器表的简单使用
Posted zzliu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了计数器表的简单使用相关的知识,希望对你有一定的参考价值。
本文整理自《高性能mysql》第三版,修正了部分错误
计数器表
web应用中经常需要保存用户的朋友数,点击次数,文件下载次数等,如果在应用表里面保存计数器,那么在更新计数器时可能遇到并发文婷,因此创建要给独立的表存储计数器通常是个好主意,这样可以使计数器小且快,使用独立的表可以帮助避免查询缓存失效。
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,
cnt int unsigned not null,
PRIMARY KEY (slot)
) ENGINE=InnoDB;
然后预先在这张表里增加100行(根据业务需要确定)数据,更新时随机选择一行更新
UPDATE hit_counter set cnt = cnt + 1 where slot = ROUND(RAND() * 100);
注:mysql的RAND()函数返回0,1之间的随机浮点数
一个常见的需求是每隔一段时间开始一个新的计数器(例如,每天一个),可以通过修改表结构实现
CREATE TABLE daily_hit_counter (
day date not null,
slot tinyint unsigned not null,
PRIMARY KEY (day,slot)
) ENGINE=InnoDB;
更新时只需要执行下面的语句
insert into daily_hit_counter values (CURRENT_DATE,ROUND(RAND()*100), 1)
ON DUPLICATE KEY UPDATE cnt = cnt + 1;
如果希望减少表的行数,可以写一个周期性的任务,合并所有结果到0号槽,并且删除所有其他的槽。实现起来也很简单,就不赘述了
以上是关于计数器表的简单使用的主要内容,如果未能解决你的问题,请参考以下文章