关闭

MySQL计数器表

标签: 计数器表mysql
1224人阅读 评论(0) 收藏 举报
分类:

在Web开发中经常会遇到需要计数器表的场景,如果将计数器保存在表中,在操作表时可能会遇到并发问题。因此,通常的做法是为计数器单独建立一个表,在写入操作时通过事务在处理业务表的同时处理计数器。

        比如一个典型的场景:记录新闻的浏览量。这个场景的表结构可能如下所示:

create table article(
	article_id int unsigned auto_increment primary key,
	article_author varchar(20) not null,
	article_title  varchar(50) not null,
	article_content text not null
);
create table article_counter(
	article_id int unsigned primary key,
	cnt int unsigned not null
);


在添加或者删除新闻纪录时,需要在事务中操作计数器表。此时有一个问题,当大量的事务访问同一个新闻的计数器时,只能串行执行。

为了更高的并发更新性能,我们为计数器表增加一个池子slot,此时计数器表的结构如下:

create table article_counter(
	article_id int unsigned,
        slot tinyint unsigned,
	cnt int unsigned not null,
    <span style="white-space:pre">	</span>primary key(article_id,slot)
);

池子slot的存在使得每条新闻不再只有一个计数器,而是多个计数器。比如可以设置slot的大小是10。这样不同的事务在访问的时候,随机生成一个数字(1-10)作为slot,如何该slot存在则更新cnt=cnt+1,否则插入cnt=1。

能够表达上面意思的语句如下:

insert into article_counter values(1,RAND()*10,1) on duplicate key update cnt=cnt+1;

  在这里有必要说下onduplicate key update的用法,它不是标准的sql语句,而是mysql特有的语句。它表示的含义是:如果插入行后会导致在一个唯一键索引或主键索引中出现重复值,则执行UPDATE

  通过上面叙述的slot设计方案,可以避免多个事务更新一个新闻的同一行,而是更新一个新闻的多个行。当需要查询某个新闻的浏览量时,可以使用下面的语句:

select sum(cnt) from article_counter where article_id=1;
  对于上面的查询语句,可以建立一个覆盖索引以提高性能,如下:

alter table article_counter add index index_articleid_cnt(`article_id`,`cnt`);

  有些时候,一个常见的需求是每隔一段时间开始一个新的计数器(比如每一天),如果需要这么做,仅仅需要修改下表的设计:

create table article_counter(
	article_id int unsigned,
	day date,
        slot tinyint unsigned,
	cnt int unsigned not null,
        primary key(article_id,day,slot)
);
  对于上面的表,我们先来插入一些数据(多执行几次):

insert into article_counter values(1,LEFT(NOW(),10),RAND()*10,1) on duplicate key update cnt=cnt+1;
insert into article_counter values(1,LEFT(NOW(),10)-interval 10 day,RAND()*10,1) on duplicate key update cnt=cnt+1;

  如果希望减少表的行数,以避免表变的太大,可以写一个周期的任务,合并所有的结果到0slot中去,并且删除其他的slot。

update article_counter as o
inner join
(select article_id,day,min(slot) as mslot,sum(cnt) as scnt from article_counter group by article_id,day) as n
using(article_id,day)
set o.cnt=if(o.slot=n.mslot,n.scnt,0),o.slot=if(o.slot=n.mslot,0,o.slot);
delete from article_counter where  slot<>0 and cnt=0;

        PS:凡事都是双刃剑。为了更快的读我们通常要牺牲一些东西。在读比较多的表要加快读的速度,在写较多的表要加快写的速度。各自权衡。在加快读的速度的时候,我们牺牲的并不仅仅是写的性能,还有开发成本,开发变的更复杂,维护成本等。所以并不是读的速度越快越好,需要找一个平衡点。







0
0
查看评论

MySQL实现计数器的表设计及实现

如果是在非常高的并发之下,还是建议用内存数据库redis去实现计数的功能。如果不是那么高的并发,用表实现就可以。 DROP TABLE access_counter; CREATE TABLE access_counter(   cnt  INT UNSIGNED NOT NUL...
  • guogang83
  • guogang83
  • 2017-04-28 11:11
  • 733

MySQL计数器

1.MySQL使用show status返回计数器信息,既有服务器级别的全局计数器,也有基于某个连接的会话级别的计数器信息。2.show status并不是一款分析工具,它可以显示某些活动例如读索引的频繁程度,但无法给出消耗时间信息。3.其中对于我们优化SQL来说,最有用的计数器包括句柄计数器,临时...
  • xujiali5172923
  • xujiali5172923
  • 2016-01-05 17:08
  • 1055

高性能mysql(四)缓存表和计数器表

缓存表(汇总表)假如统计一个网站23小时发出的消息数,在一个比较忙碌的网站下不可能随时维护一个精准的计数器。代替方案是每小时生成一张汇总表,这样比实时计算要高效的多。简单的说就是维护一些复杂 耗时的计算 那么用汇总表是比较好的选择。计数器表要计数我们可以创建一个计数器表。create table h...
  • wangguoyang429883793
  • wangguoyang429883793
  • 2017-05-21 22:33
  • 479

mysql常用计数器

mysql常用计数器 计数器 计数器分析 Threads_connected 表示当前有多少个客户连接该mysql服务器,连接数是否过多,网络是否存在问题,它是动态变化的,当达到最大连接数时,数据库系统就不能提供更多 的连接数了,这时,程序还想新建连接线程,数据库系统就会拒绝,...
  • ocean73737
  • ocean73737
  • 2017-08-28 14:04
  • 237

SQLServer MySql 计数器表

例子参考《高性能MySql》第三版4.4.2 计数器表(page 135) 由于mysql 没有执行成功,现在用sqlserver 模拟样本。计数器表可用于缓存一个用户的朋友数,文件下载次数等。 创建表 hit_counter 用于计数,先插入一行数据,每次更新增加1,总计则求和!...
  • kk185800961
  • kk185800961
  • 2015-10-12 21:11
  • 972

数据库网站统计之mysql计数器优化【转载-单曲兄弟的博文】

如果应用在表中保存计数器,则在更新计数器时可能碰到并发问题。计数器表在WEB应用中很常见。可以用这种表缓存一个用户的朋友书、文件下载次数等。创建一张独立的表存储计数器通常是一个好主意,这样可使计数器表小且快。使用独立的表可以帮助避免查询缓存失效。假设只有一个计数器表,只有一行数据,记录网站的点击次数...
  • zqtsx
  • zqtsx
  • 2014-12-22 17:07
  • 1088

mysql统计表中条目个数的方法举例

【1】、统计某张或某几张表的数据量: 【2】、统计某数据库中所有表的数据量: 【3】、统计某张表占用存储大小:
  • huangjin0507
  • huangjin0507
  • 2015-09-11 10:29
  • 5442

乘风多用户PHP+MYSQL计数器

  • 2012-11-28 16:06
  • 127KB
  • 下载

loadrunner 利用sitescope监测监控mysql性能(添加mysql计数器)

1.下载sitescope 2.安装sitescope 可以一路默认安装,许可证号可以先为空,为空代表试用,有期限,可以到安装完之后,再填写。安装完之后就 会弹出一个页面,点击页面上的http://localhost:8080/SiteScope.就会进入sitescope界面。当进入界面中显...
  • hualusiyu
  • hualusiyu
  • 2014-10-04 11:27
  • 696

【MySQL】计数器表

如果应用在表中保存计数器,则在更新计数器是可能碰到并发问题。计数器表在Web应用中很常见。可以用这种表缓存一个用户的朋友数、文件下载次数等。创建一张独立的表存储计数器通常是个好主意,这样可使计数器表小且快。使用独立的表可以帮助避免查询缓存失效,并且可以使用一些高级技巧。假设有一个计数器表,只有一行数...
  • u012386311
  • u012386311
  • 2017-12-17 17:41
  • 57
    个人资料
    • 访问:151285次
    • 积分:1778
    • 等级:
    • 排名:千里之外
    • 原创:138篇
    • 转载:11篇
    • 译文:0篇
    • 评论:39条
    最新评论