数据库
首页 > 数据库> > Redis bitmap

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

将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]

示例:

查看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 可以是 ANDORNOTXOR 这四种操作中的任意一种

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]

统计指定位区间上值为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)
中文字符:

在这里插入图片描述

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