文档章节

MySql计数器,如网站点击数,如何实现高性能高并发的计数器功能

海水凝蓝
 海水凝蓝
发布于 2017/09/02 15:27
字数 839
阅读 10
收藏 0
现在有很多的项目,对计数器的实现甚是随意,比如在实现网站文章点击数的时候,是这么设计数据表的,如:”article_id, menu_id, article_name, article_content, article_author, article_view......在article_view中记录该文章的浏览量。诈一看似乎没有问题。对于小站,比如本博客,就是这么做的,因为小菜的博客难道会涉及并发问题吗?答案显而易见,一天没多少IP,而且以后不会很大。
      言归正传,对文章资讯类为主的项目,在浏览一个页面的时候不但要进行大量的查(查询上文的记录,已经所属分类的名字、热门文章资讯评论、TAG等),还要进行写操作(更新浏览数点击数)。把文章的详细内容和计数器放在一张表尽管对开发很方便,但是会造成数据库的压力过大(不然为什么大项目都要分库分表呢)。
      那么,分两张表存放就好了么?一张表存文章详细信息,另一张表单独存计数器。
CREATE TABLE `article_view`( `article_id` int(11) NOT NULL, `view` int(11) NOT NULL, PRIMARY KEY (`article_id`) )ENGINE=InnoDB;

这种方式,虽然分担了文章表的压力,但是每当有一个进程请求更新的时候,都会产生全局的互斥锁,只能串行,不能并行。在高并发下会有较长的等待时间。 另一种比较好的办法是对每一个文章的计数器不是一行,而是多行,比如吧,一百行。每次随机更新其中一行,该文章的浏览数就是所有行的和。

CREATE TABLE `article_view`(
    `article_id` int(11) NOT NULL,
    `pond` tinyint(4) NOT NULL COMMENT '池子,就是用来随机用的',
    `view` int(11) NOT NULL,
    PRIMARY KEY (`article_id`, `pond`)
)ENGINE=InnoDB;

小访问量的随机池子100个肯定多了,三五个足矣。每次访问的时候,随机一个数字(1-100)作为pond,如何该pond存在则更新view+1,否则插入,view=1。借助DUPLICATE KEY,不然在程序里是实现得先SELECT,判断一下再INSERT或者UPDATE。

INSERT INTO `article_view` (`article_id`, `pond`, `view`) VALUES (`123`, RAND()*100, 1) ON DUPLICATE KEY UPDATE `view`=`view`+1

获取指定文章的总访问量的时候:

SELECT SUM(`view`) FROM `article_view` WHERE `article_id`='123'

Ps:凡事都是双刃剑。为了更快的读我们通常要牺牲一些东西。在读比较多的表要加快读的速度,在写较多的表要加快写的速度。各自权衡。在加快读的速度的时候,我们牺牲的并不仅仅是写的性能,还有开发成本,开发变的更复杂,维护成本等。所以并不是读的速度越快越好,需要找一个平衡点。 注:这里仅仅是Mysql方面,有人会说高并发下你这是直接读写Mysql啦,项目的瓶颈本来就在数据库啦。。。其实。。。这里只是说Mysql的表怎么去设计而已。你完全可以在这个地方用队列去写表,你也可以把计数器在内存中保存,一直来累加,1个小时持久化一次。你也可以去用号称每秒读写十万次的Redis。

本文转载自:

共有 人打赏支持
海水凝蓝
粉丝 0
博文 8
码字总数 23021
作品 0
珠海
程序员
私信 提问
按钮点击数统计计数器(PHP+MYSQL+JS)

最近因工作上的需求,需要实现一个统计每天某个超链接点击次数的功能,经过考虑,我觉得用php+mysql还是挺容易实现的,过程很简单,就是通过点击超链接,触发表单提交,完成一次数据库的+1输...

我爱一碗香
2016/09/29
0
0
qieangel2013/zys

zys高性能服务框架 核心特性 1.基于swoole提供分布式服务器通讯服务2.基于thrift提供rpc远程调用服务3.基于HTML5提供在线网络直播平台服务4.基于swoole提供同步异步数据库连接池服务5.基于s...

qieangel2013
2016/08/29
0
0
如何用Windows 性能监视器进行SMB性能监控和分析

SMB是Windows系统上主要的共享文件访问协议。作为微软设计的原生文件系统协议,和其它网络文件系统协议相比,SMB提供Windows文件系统语义,并且在网络短时间断开和服务器重启等出错情况下能保...

nas-hz
09/30
0
0
Redis 的 8 大应用场景!

之前讲过Redis的介绍,及使用Redis带来的优势,这章整理了一下Redis的应用场景,也是非常重要的,学不学得好,能正常落地是关键。 下面一一来分析下Redis的应用场景都有哪些。 1、缓存 缓存现...

Java技术栈
08/29
0
0
科普一下,什么是网站系统的性能,可用性,可伸缩性,可扩展性?

最近在读李智慧大拿写的<

chancein007
2017/01/02
0
0

没有更多内容

加载失败,请刷新页面

加载更多

mybatis批量update操作的写法,及批量update报错的问题解决方法

mybatis的批量update操作写法很简单,如下: 如果想学习Java工程化、高性能及分布式、深入浅出。微服务、Spring,MyBatis,Netty源码分析的朋友可以加我的Java高级交流:854630135,群里有阿...

编程SHA
13分钟前
0
0
EOS怎样删除钱包

在使用Eos的keosd钱包软件时,如果要删除EOS中指定名称的钱包,最简单的办法是 直接删除钱包文件,不过在删除钱包之前,需要先停止钱包软件的运行。 学习EOS应用开发要选这个:【EOS智能合约...

汇智网教程
20分钟前
3
0
Java语言快速实现简单MQ消息队列服务

使用 JAVA 语言自己动手来写一个MQ (类似ActiveMQ,RabbitMQ) 主要角色 首先我们必须需要搞明白 MQ (消息队列) 中的三个基本角色 ProducerBrokerConsumer 整体架构如下所示 自定义协议 首...

微笑向暖wx
29分钟前
3
0
ES5和ES6那些你必须知道的事儿

  ES5和ES6那些你必须知道的事儿      ES5新增的东西      一、数组方法      1、forEach      用途:遍历,循环      对于空数组不会执行回调函数      复制代码...

SEOwhywhy
56分钟前
9
0
转:[windows]DOS批处理添加任务计划

[windows]DOS批处理添加任务计划 博客分类: Windows 转自:http://gwmold.blog.163.com/blog/static/1553319892010117113457232/ 自动创建每周运行一次的计划任务 创建计划任务可用at,sch...

SamXIAO
今天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部