目录
业务逻辑咱们就不说了。直接说技术选型。
技术选型
对于这种设计到统计、经常查询的聚合数据,那指定不能只使用mysql,没有缓存可咋整,那么慢的系统,那老板不得直接给你降薪百分之八十。所以我选择缓存在redis中然后异构到mysql中。查询就根据场景使用redis+mysql搭配查询。
签到和没签到不就这两种状态嘛,所以redis中
二值状态统计类型
bitmap很符合条件,并且自带统计函数
。
BITMAP
可以将 Bitmap 看成是一个 bit 为单位的数组,数组的每个单元只能存储 0 或者 1,数组的下标在 Bitmap 中叫做 offset 偏移量。图片来源于网上。
对于二值场景,我们用bitmap再合适不过了,如果我们统计当天的用户有1亿个放在一个bitmap里,占用内存也才≈ (100000000 / 8/ 1024/1024)12 MB。
redis-cli中的基本用法
setbit key offset value
getbit key offset
bitcount key [start end]
bitpos key bit [start] [end]
bitop operation destkey key [key …]
opration
可以是
and
、
OR
、
NOT
、
XOR
了解完它的大致摸样,我们来看看可以用它来解决哪些场景,
统计用户月打卡次数
统计当月打卡次数我们可以使用bitcount key的操作,具体步骤如下
1、设计key,可以是sign:{userId}:{yyyyMM},也可以是任何包含用户信息和月信息的设计。
2、记录用户打卡
3、使用方法统计指定用户当月打卡数
扩展业务场景
统计指定用户某天是否打卡
。比如17日
getbit sign:1:202307 17
统计指定用户当月第一次打卡日期
。
bitpos sign:1:202307 1
连续打卡用户总数统计
我们需要使用到bitmap的合并与运算,以及bitcount的功能。比如说统计15、16、17连续三天打卡用户总数。
1、设计key,既然是合并为一个bitmap统计个数,那必然offset代表的是用户,key就是日期了。
2、记录数据,可以看出user1在15、16、17都打卡了,user2、user3则没连续三天打卡
127.0.0.1:6379> setbit 15 1 1
(integer) 0
127.0.0.1:6379> setbit 16 1 1
(integer) 0
127.0.0.1:6379> setbit 17 1 1
(integer) 0
127.0.0.1:6379> setbit 15 2 1
(integer) 0
127.0.0.1:6379> setbit 17 2 1
(integer) 0
127.0.0.1:6379> setbit 15 3 1
(integer) 0
3、合并bitmap并进行与运算合成新的bitmap
bitop and destmap 15 16 17
4、统计连续三天都打卡的人数
小结
只需要一个 bit 位就能表示我们需要的统计状态。在统计海量数据的时候将大大减少内存占用,是一个不错的选择。