Redis bitmap
作者:互联网
文章目录
Redis的位图bitmap【字节数组】
bitmap(位图)不是真正的数据类型,它是定义在字符串类型中一个字符串类型的值最多能存储512M字节的内容
位上限:2^(9(512)+10(1024)+10(1024)+3(8b=1B))=2^32b
1. getbit
获取某一位上的值
GETBIT key offset
首先设置一个key-value
127.0.0.1:6379> set keya a
OK
127.0.0.1:6379> get keya
"a"
a的ASCII码为97
a的字节数组表示:0110 0001
127.0.0.1:6379> getbit keya 0
(integer) 0
127.0.0.1:6379> getbit keya 1
(integer) 1
127.0.0.1:6379> getbit keya 2
(integer) 1
127.0.0.1:6379> getbit keya 3
(integer) 0
127.0.0.1:6379> getbit keya 4
(integer) 0
127.0.0.1:6379> getbit keya 5
(integer) 0
127.0.0.1:6379> getbit keya 6
(integer) 0
127.0.0.1:6379> getbit keya 7
(integer) 1
2. setbit
设置某一位上的值
SETBIT key offset value
- offset:位偏移量,从0开始
- value:0或1
将keya的值的第6为设置为2
keya的值为a,ASCII码值为97,二进制:0110 0001
将第六位设置为1后:0110 0011,ASCII码为99,是字符c
127.0.0.1:6379> set keya a
OK
127.0.0.1:6379> setbit keya 6 1
(integer) 0
127.0.0.1:6379> get keya
"c"
127.0.0.1:6379> getbit keya 0
(integer) 0
127.0.0.1:6379> getbit keya 1
(integer) 1
127.0.0.1:6379> getbit keya 2
(integer) 1
127.0.0.1:6379> getbit keya 3
(integer) 0
127.0.0.1:6379> getbit keya 4
(integer) 0
127.0.0.1:6379> getbit keya 5
(integer) 0
127.0.0.1:6379> getbit keya 6
(integer) 1
127.0.0.1:6379> getbit keya 7
(integer) 1
127.0.0.1:6379> set str ab
OK
127.0.0.1:6379> setbit str 6 1
(integer) 0
127.0.0.1:6379> setbit str 7 0
(integer) 1
str的值是什么?
ab -> ascii码 97 98 -> 转为二进制
0110 0001 0110 0010
将第6位改为1
0110 0011 0110 0010
将第7为改为0
0110 0010 0110 0010
ASCII码:98 98 -> bb
127.0.0.1:6379> get str
"bb"
3. bitpos
返回指定值0或者1在指定区间上第一次出现的位置偏移量(从0开始)
BITPOS key bit [start] [end]
- bit:0或1
- start:开始字节索引,0表示第一个字节
- end: 结束字节索引
示例:
查看str(值为bb)1在第一个字节上第一次出现的位置偏移量
bb -> 0110 0010 0110 0010
1第一次出现在第一个字节的第2位,偏移量为1
127.0.0.1:6379> bitpos str 1 0 0
(integer) 1
查看str(值为bb)0在第二个字节上第一次出现的位置偏移量
bb -> 0110 0010 0110 0010
1第一次出现在第二个字节的第1位,在字节数组的第9位,偏移量为8
127.0.0.1:6379> bitpos str 0 1 1
(integer) 8
4. 位操作 bitop
对一个或多个保存二进制位的字符串 key 进行位元操作,并将结果保存到destkey 上operation 可以是 AND
、 OR
、 NOT
、 XOR
这四种操作中的任意一种
bitop and
BITOP AND destkey key [key ...]
对一个或多个 key 求逻与,并将结果保存到 destkey
127.0.0.1:6379> set keya a
OK
127.0.0.1:6379> set keyb b
OK
对keya和keyb做逻辑与操作
bitop and resand keya keyb
# 可以将0看作false,1看作true
# 对每一位做 && 操作
a: 0110 0001
b: 0110 0010
and: 0110 0000
结果:0110 0000 ,十进制:96,ASCII码:`
127.0.0.1:6379> get resand
"`"
bitop or
BITOP OR destkey key [key ...]
对一个或多个 key 求逻辑或,并将结果保存到 destkey
对keya和keyb做逻辑或操作
bitop or resor keya keyb
# 可以将0看作false,1看作true
# 对每一位做 || 操作
a: 0110 0001
b: 0110 0010
and: 0110 0011
结果:0110 0011 ,十进制:99,ASCII码:c
127.0.0.1:6379> get resor
"c"
bitop not
BITOP NOT destkey key
对给定 key 求逻辑非,并将结果保存到 destkey
对keya做逻辑非操作
bitop not resnot keya
# 可以将0看作false,1看作true
# 对每一位做 ! 操作
a: 0110 0001
not: 1001 1100
结果:1001 1100 ,十进制:156,ASCII码:没找到
127.0.0.1:6379> get resnot
"\x9e"
bitop xor
BITOP XOR destkey key [key ...]
对一个或多个 key 求逻辑异或,并将结果保存到 destkey
BITOP OR destkey key [key ...]
对一个或多个 key 求逻辑或,并将结果保存到 destkey
对keya和keyb做逻辑异或操作
bitop xor resxor keya keyb
# 可以将0看作false,1看作true
# 对每一位做 ^ 操作
a: 0110 0001
b: 0110 0010
xor: 0000 0011
结果:0000 0011 ,十进制:3
127.0.0.1:6379> get resnot
"\x9e"
5. bitcount
BITCOUNT key [start] [end]
- start:开始字节索引
- end:结束字节索引
统计指定位区间上值为1的个数
BITCOUNT key
:统计所有字节中1的个数
BITCOUNT key 0 -1
等同于BITCOUNT key
示例:
统计str 的第一个和第二个字节上值为1的个数
127.0.0.1:6379> set str ab
OK
127.0.0.1:6379> BITCOUNT str 0 1
(integer) 6
第一个字节 第二个字节
ab:0110 0001 0110 0010
有6个1
bitcount mykey 0 -1
6. 中文字符
一个英文字符占一个字节 8位(1Byte,8bit)
中文字符:
- utf-8:一个中文字符占3个字节 24位(3Byte,24bit)
- gbk:一个中文字符占2个字节 16位(2Byte,16bit)
7. 案例
7.1 网站用户的上线次数统计(活跃用户)
用户ID为key,天作为offset,上线置为1 366> 000000000000000
366 /8 50Byte 16 50
一共366位,50个字节,16个中文字符,50个英文字符
String userId = "u_54789247";
Calendar calendar = Calendar.getInstance();
calendar.setTime(new Date());
int dayOfYear = calendar.get(Calendar.DAY_OF_YEAR);
RedisUtils.setbit(userId, dayOfYear, 1);
统计一年内某个用户的活跃天数:
String userId = "u_54789247";
RedisUtils.bitcount(userId);
BITCOUNT u_54789247 0 -1
7.2 按天统计网站活跃用户
天作为key,用户ID为offset,上线置为1
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
String dateFormat = simpleDateFormat.format(new Date());
String userId = "u_54789247";
Long uid = Long.valueOf(userId.substring(userId.indexOf("_")+1));
RedisUtils.setbit(dateFormat, uid, 1);
求一段时间内活跃用户数
求6月1日到6月10日的活跃用户
BITOP OR active:count 20200601 20200602 20200603 20200610
BITCOUNT active:count 0 -1
标签:0110,127.0,0.1,Redis,bitmap,6379,key,keya 来源: https://blog.csdn.net/sinat_35400668/article/details/115331054