MySQL计数器表的设计

  如果应用在表中保存计数器,则在更新计数器时可能碰到并发问题。计数器表在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;
时间: 2024-10-23 18:52:47

MySQL计数器表的设计的相关文章

mysql订单表如何设计?

mysql订单表如何设计? 商品表和订单表 . 通过一个表来关联. 那删除了商品,相关联的订单表如何显示出这个已经删除的商品? 订单表需要冗余商品名.商品编号.价格等基本信息. 不能只保存一个商品主键,这个是订单表的基本原则,同时生成了订单的商品是不能删除的. 订单表中引用商品表主键,删除使用状态假删. 同时引入商品的状态,总之就是反范式设计,保证一次可以获得全部要的状态,不要进行多表jion. 订单:  分为以下几种 订单凭证(接到客户的订单表),采购订单, 销售订单,委外订单 我的数据库 该

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

学习地址 http://www.jtthink.com/course/play/352 主表:prop_main 不仔细多说,正常业务都会涉及到并且考虑的相对周全.常用字段[商品id][商品名称][商品简介][商品类别][添加时间][点击数/点赞数/购买数/差评数等] 指的一提的是,[点击数/点赞数/购买数/差评数等]是通过定时更新的.但读取的时候为了速度和效率,作为冗余字段放在商品表中是很科学的. 这里重点关注[商品类别]的设计 商品类型表:prop_class 这个也很常见,每个商品都必须从

MySQL数据表的设计

数据表:数据表由表结构和表内容两部分组成,先建立表结构,然后才能输入数据. 数据表结构设计主要包括字段名称.字段类型.和字段属性的设置. 在关系数据库中,为了确保数据的完整性和一致性,在创建表时除了必须指定字段名称.字段类型.字段属性外,还需要使用约束(constraint).索引(index).主键(primary key)和外键(foreign key)等功能属性. 数据值和列类型(字段的类型): 对MySQL中数据值的分类:有数值型.字符型.日期型和空值等. MySQL中的列类型有三种:数

mysql web数据库的设计归范-2表设计原则

[职责分离原则] 职责分离原则是指在设计的时候应当考虑到数据的产生,聚合使用等原则,每个系统干自己能干的事情,每个系统只干自己的事情.一个数据表应该放在哪个系统中,通常取决于几点: 1. 谁产生这个信息:通常情况下谁产生了这个数据应当对此数据负责:也就是考虑该数据的创建,发展,销毁等全生命周期的定义,并将这个定义维护起来提供给消费者作为消费原则: 2. 谁最经常使用这个信息:如果某个系统最经常使用这个数据,最经常去修改某个数据,也应该由该系统来负责保存维护该数据: 3. 遵守高内聚,低耦合的考虑

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

一.数据库优化包含的方面 数据库优化是一种综合性的技术.并非通过某一种方式让数据库效率提高非常多.而是通过多方面的提高.从而使得数据库性能提高. 主要包含: 1.表的设计合理化(3范式) 2.给表加入合适的索引.怎样使用索引 3.分表技术(水平切割.垂直切割) 4.定时清除数据垃圾,定时碎片整理 5.多用存储过程和触发器 6.对mysql配置进行优化 7.读写分离 8.mysqlserver硬件升级. 二.数据库的设计 步骤: 1.收集信息:与该系统有关人员进行交流.充分了解数据库须要完毕的任务

MySQL 之 表设计注意事项

MySQL表设计好与坏直接关系到性能优化之根本,一般表的设计为了维护简单减少存储等因素都会遵循范式化的规则,为了查询效率我们一般都会有一些数据冗余,就会用到反范式化的设计,网上也有很多这方面的介绍,这里就不过多的解读了. 表字段类型直接关系数据的存储及查询效率,下面列举一些注意事情(引擎默认为innodb): 1.选择合适的字段类型,例如一个status状态字段,一般而言只会存在0.1.2几个不同值,我们可以使用tinyint绝不使用int,int占用空间为tinyint的四倍.又比如性别字段以

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

正文:表的设计及优化(真技术文) 优化①:创建规范化表,消除数据冗余 数据库范式是确保数据库结构合理,满足各种查询需要.避免数据库操作异常的数据库设计方式.满足范式要求的表,称为规范化表,范式产生于20世纪70年代初,一般表设计满足前三范式就可以,在这里简单介绍一下前三范式. 通俗的给大家解释一下(可能不是最科学.最准确的理解) 第一范式:属性(字段)的原子性约束,要求属性具有原子性,不可再分割: 第二范式:记录的惟一性约束,要求记录有惟一标识,每条记录需要有一个属性来做为实体的唯一标识. 第三

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

转自互联网整理. 优化之路高级进阶--表的设计及优化 优化①:创建规范化表,消除数据冗余 数据库范式是确保数据库结构合理,满足各种查询需要.避免数据库操作异常的数据库设计方式.满足范式要求的表,称为规范化表,范式产生于20世纪70年代初,一般表设计满足前三范式就可以,在这里简单介绍一下前三范式. 通俗的给大家解释一下(可能不是最科学.最准确的理解) 第一范式:属性(字段)的原子性约束,要求属性具有原子性,不可再分割: 第二范式:记录的惟一性约束,要求记录有惟一标识,每条记录需要有一个属性来做为实

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

MySQL基础 一:安装MySQL(按步骤操作,如果下载后使用不了,试着用360安全卫士卸载MySQL,清除残留的,方便在下载造成不必要的麻烦:如果这样也不行,那就需要重做系统在进行下载) 二:创建数据库/表 黑窗口:1:输入密码 2:show databases:查看数据库 3:create database 库名:创建库 4:use 库名:使用库 5:create table 表名:创建表( 列名数据类型(约束条件),    //用逗号隔开 ): 6:show tables:查看库里有哪些表