• 计数器表的简单使用


    本文整理自《高性能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号槽,并且删除所有其他的槽。实现起来也很简单,就不赘述了
  • 相关阅读:
    android 多线程
    Uva 10881 Piotr’s Ants 蚂蚁
    LA 3708 Graveyard 墓地雕塑 NEERC 2006
    UVa 11300 Spreading the Wealth 分金币
    UVa 11729 Commando War 突击战
    UVa 11292 The Dragon of Loowater 勇者斗恶龙
    HDU 4162 Shape Number
    HDU 1869 六度分离
    HDU 1041 Computer Transformation
    利用可变参数函数清空多个数组
  • 原文地址:https://www.cnblogs.com/zzliu/p/12079544.html
Copyright © 2020-2023  润新知