假设老板给你提了个需求:“小胖儿,来给我统计下咱们系统最近一个月的活跃(登录)用户数。”。
熟悉关系数据库的我们都知道,建个用户登录表呗,一个sql查询搞定。
就像这样:
select distinct userid from login_log
where login_date >20201101 and log_date<20201130;
假设用户登录表数据特别庞大,一来占用很大磁盘空间,二来,这样的sql查询效率一定不高。
你可能会问,那不然呢?
对于这个问题,Redis还真有解决方案。对,就是这个命令。
什么意思呢?
举个例子:
setbit k1 1 1
/*设置k1的第二位为1,此时k1就是 0100 0000
(此命令会以字节为单位计值,ascii码是@,使用get k1会返回@)*/
setbit k1 14 1
/*此时 k1就是 0100 0000 0000 0010,十六进制是 @\x02 */
对于上面一开始提到的问题,我们可以用日期作为Redis的key,把各个用户排序后映射到value上的每一个bit,然后取出当月的每一天,进行或运算,即可计算出当月的登录用户数,而位运算正是计算机非常擅长做的事情。
下面我们看下Reids的位运算这个知识点。
这样用:
经过setbit操作后,上述k1的值是0100 0000,k2的值是0000 0000,进行bitop与运算后,将结果存入k3,此时k3的值是0000 0000,所以get k3结果是\x00。
不难理解,进行“或运算”的情况。
好了,回到开头时说的问题。
我们设置了20201101、20201102、20201103三个key来代表每天的用户登录情况,使用bit位上的每一位代表每个用户的登录情况,当天登录就设置为1。
假设第一天第20个用户登录,第二天第一个用户登录,03这天还是第一个用户登录,即2个用户登录三次。如下图:
在对每天的登录情况进行“或运算”(对用户去重),把运算结果存入reslut变量中,再统计该变量中1的个数。
最后,用bitcount计算出登录用户数为2。
总结
简单总结一下,我们统计用户登录情况,除了传统的使用关系型数据库查询之外,还可以有另外一种思路,就是使用基于key-value的内存数据库Redis。
使用Redis的setbit命令,以日期为key,并将每一个用户映射到value中的每一个bit。然后使用bitop进行计算机非常擅长的位运算,最后通过bitcount计算出value中1的bit位数,也就是登录用户数。
好了,这个问题我们先介绍到这里。如果你觉得有收获,就请毫不留情地转发吧。