Redis bitmap 操作
在redis中,字符串是以二进制形式存储的。redis提供了按位操作。
位(bit)是存储器的最小单位,可以表示一位二进制数。1字节(Byte)由8个位组成,即1Byte=8bit,是存储器的基本单位,通常被作为一个存储单元。
redis的几个位操作方法:setbit,getbit,bitcount,bitop,bitops
搞个例子:
127.0.0.1:6379> set name a OK设置 键:name;值:a
a的二进制是:01100001
b的二进制是:01100010
这里右边开始数数,从0开始,可以看到这两个二进制红色部分不一样,我们用setbit设置一下:
127.0.0.1:6379> setbit name 6 1 //第6位改为1 (integer) 0 127.0.0.1:6379> setbit name 7 0 //第7位改为0 (integer) 1 127.0.0.1:6379> get name //name 以前是 a 现在变成 b "b"
再看一个命令:bitcount:统一所有为 1 的个数。这里统计一下b,看上面,b的二进制中有3个1,所以这里返回3:
127.0.0.1:6379> bitcount name (integer) 3
看起来好像没什么卵用,要改一个key重新set一下就好了,干嘛还用位操作?谁记得二进制是多少啊,还要一个一个数着设置……
搞一个实例:统计每天网站活跃用户,比如每天有多少用户登录……
思路:这里用bitmap来搞,取用户的id:user_id(必须是数字)user_id对应bitmap的offset位置,该位置的值为1或者0,1表示登录过。
假设三个用户:张三的user_id:100,李四:101,王二:102,key 搞一个标识+时间,那么可以这样设置:
127.0.0.1:6379> setbit is_sign_2019_08_01 100 1 // 101表示张三,1表示登录过 (integer) 0 127.0.0.1:6379> setbit is_sign_2019_08_01 101 1 (integer) 0 127.0.0.1:6379> setbit is_sign_2019_08_01 102 1 (integer) 0假设2019.08.01这天,他们三个都登录过,就是这样设置,那么我要统计这一天有多少人登录过,怎么搞?这又用到了上面说的一个命令:bitcount(该命令是统计所有bit为1的,而我们规定1就是代表已登录,所以统计1的数量就是登录的数量)
127.0.0.1:6379> bitcount is_sign_2019_08_01 (integer) 3可以看到这里为 3 ,OK
如果我要查询张三 在2019_08_01这天是否登录过?怎么搞?这又用到了一个命令:getbit。
getbit:用于对 key 所储存的字符串值,获取指定偏移量上的位(bit)
语法:getbit key offset
2019_08_01这天的key是:is_sign_2019_08_01,offset是我们的user_id,bit的值是 1或者0,1表示登录过
127.0.0.1:6379> getbit is_sign_2019_08_01 100 (integer) 1
看起来就是这样!
bittop:对于所给定key按位操作存入 destkey中
bittop and destkey k1 k2 .... 求交集(在k1,k2同时存在) bittop or destkey k1 k2 ... 并集(k1,k2之和) bittop xor destkey k1 k2 .. 异或……