zoukankan      html  css  js  c++  java
  • 计数器表的简单使用

    本文整理自《高性能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号槽,并且删除所有其他的槽。实现起来也很简单,就不赘述了
  • 相关阅读:
    WebService
    JavaMail
    ssh框架整合
    CSS3初步
    SpringMVC 文件上传及下载
    Java多线程
    SpringMVC 数据校验
    初始化参数绑定——日期格式
    SpringMVC入门
    Quartz
  • 原文地址:https://www.cnblogs.com/zzliu/p/12079544.html
Copyright © 2011-2022 走看看