如果应用在表中保存计数器,则在更新计数器时可能碰到并发问题。计数器表在web应用中非常常见。可以用这个表缓存一个用户的朋友书、文件下载次数等。创建一张独立的表存储计数器是一种非常好的做法,这样可以使计数器表小并且快。使用独立的表可以帮助避免查询缓存失效。如下面这个例子:

  假设有一个计数器表,只有一行数据,记录网站的点击次数。

CREATE TABLE hit_counter(
cnt int unsigned not null
) ENGINE=InnoDB;

  网站的每次点击都会导致对计数器的更新:

UPDATE hit_counter SET cnt = cnt + 1;

  那么问题出现了,对于任何想要更新这一行的事务来说,这条记录上都有全局的互斥锁。这会使得这些事务只能串行执行。要活的跟高的冰法更新性能,我们可以这样解决:

  将技术其保存在多行中,每次随机选择一行进行更新,这样需要对计数器表作如下修改:

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;

  要获得统计结果,使用具和函数sum()进行查询:

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( 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 JION(
SEKECT day , SUM( cnt ) AS cnt , MIN( slot ) AS mslot
FROM daily_hit_counter
GROUP 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计数器表的设计的更多相关文章

  1. MySQL数据库表的设计和优化(下)

    二.基于单表设计的多表设计原则:(1)表关系: 一)一对一关系: 定义: 在这种关系中,关系表的每一边都只能存在一个记录.每个数据表中的关键字在对应的关系表中只能存在一个记录或者没有对应的记录.这种关 ...

  2. MySQL数据库表的设计和优化(上)

    一.单表设计与优化: (1)设计规范化表,消除数据冗余(以使用正确字段类型最明显):数据库范式是确保数据库结构合理,满足各种查询需要.避免数据库操作异常的数据库设计方式.满足范式要求的表,称为规范化表 ...

  3. mysql 商品表的设计思路(面向对象建表:类与对象)

    学习地址 http://www.jtthink.com/course/play/352 商品通用信息主表:prop_main 不仔细多说,正常业务都会涉及到并且考虑的相对周全.常用字段[商品id][商 ...

  4. 「mysql优化专题」优化之路高级进阶——表的设计及优化(6)

    正文:表的设计及优化(真技术文) 优化①:创建规范化表,消除数据冗余 数据库范式是确保数据库结构合理,满足各种查询需要.避免数据库操作异常的数据库设计方式.满足范式要求的表,称为规范化表,范式产生于2 ...

  5. 6.MySQL优化---高级进阶之表的设计及优化

    转自互联网整理. 优化之路高级进阶——表的设计及优化 优化①:创建规范化表,消除数据冗余 数据库范式是确保数据库结构合理,满足各种查询需要.避免数据库操作异常的数据库设计方式.满足范式要求的表,称为规 ...

  6. mysql数据库优化之表的设计和慢查询定位

    一.数据库优化包含的方面 数据库优化是一种综合性的技术.并非通过某一种方式让数据库效率提高非常多.而是通过多方面的提高.从而使得数据库性能提高. 主要包含: 1.表的设计合理化(3范式) 2.给表加入 ...

  7. MySQL基础/数据库和表的设计

    MySQL基础 一:安装MySQL(按步骤操作,如果下载后使用不了,试着用360安全卫士卸载MySQL,清除残留的,方便在下载造成不必要的麻烦:如果这样也不行,那就需要重做系统在进行下载) 二:创建数 ...

  8. MySql数据表设计,索引优化,SQL优化,其他数据库

    MySql数据表设计,索引优化,SQL优化,其他数据库 1.数据表设计 1.1数据类型 1.2避免空值 1.3text类型优化 2.索引优化 2.1索引分类 2.2索引优化 3.SQL优化 3.1分批 ...

  9. MySQL库表设计小技巧

    前言: 在我们项目开发中,数据库及表的设计可以说是非常重要,我遇到过很多库表设计比较杂乱的项目,像表名.字段名命名混乱.字段类型设计混乱等等,此类数据库后续极难维护与拓展.我一直相信只有优秀的库表设计 ...

随机推荐

  1. linux crontab运行

    Linux在相应用户下,用crontab -l 命令可以查看该用户定时执行的任务. 1- $>crontab -l 无内容. 则表示没有指定用户执行对应用户下的crontab文件. 2- $&g ...

  2. Stripies(POJ 1862 贪心)

    Stripies Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 14151   Accepted: 6628 Descrip ...

  3. x位全排列(next_permutation)

    擅长排列的小明 时间限制:1000 ms  |  内存限制:65535 KB 难度:4   描述 小明十分聪明,而且十分擅长排列计算.比如给小明一个数字5,他能立刻给出1-5按字典序的全排列,如果你想 ...

  4. 添加事件监听兼容IE6-8

    IE8一下浏览器不支持addEventListener,用attachEvent取而代之,但是在时间类型前面要加上’on‘,例如click时间在attachEvent中要写成onclick. var ...

  5. HTML常用字符

    显示结果 描述 实体名称 实体编号   空格     < 小于号 < < > 大于号 > > & 和号 & & " 引号 &quo ...

  6. 使用 asp.net Web API 2的坑

    使用工具: Googl  浏览器+PostMan 插件 写了个  控制器 添加了个Action,结果呢?GET 方式请求没问题. POST一直,在服务器端获取不了参数...找了官方的文档 .各种雨里雾 ...

  7. cf471B MUH and Important Things

    B. MUH and Important Things time limit per test 1 second memory limit per test 256 megabytes input s ...

  8. MATLAB三维曲面

    今天终于测试了,发下来第一张试卷中只会做一小题.我蒙了!!! 所以呢,我现在再做一下,总结总结! 作函数 f(x)=2(x1-1)4+2x22 的三维图. 这道题要用到的知识点有函数meshgrid. ...

  9. 使用GridBagLayout控制行列的高度和宽度

    摘自http://bbs.csdn.net/topics/340189065使用GridBagLayout控制行列的高度和宽度 gridwidth 指定组件显示区域的某一行中的单元格数. 默认值1,水 ...

  10. hdu 4750 Count The Pairs(并查集+二分)

    Problem Description With the 60th anniversary celebration of Nanjing University of Science and Techn ...