Redis-4-针对String数据类型中Bit的相关命令

概述

上篇文章我们对String数据类型中一些基本的命令进行了介绍,但是没有涉及到Bit相关的命令,本文我们就来看看几个和Bit相关的命令.

redis中的字符串都是以二进制的方式进行存储的,举个例子,执行以下命令:

1
2
172.16.12.3:6379> set k1 a
OK

a对应的ASCII码是97,转换为二进制数据是01100001,我们Bit相关命令都是对这个二进制数据进行操作

ASCII码对照表

常用命令

getbit

getbit命令可以返回key对应的value在offset处的bit值,以上文提到的k1为例,a对应的二进制数据是01100001,所以当offset为0时,对应的bit值为0,offset为1时,对应的bit值为1,offset为2时,对应的bit值为1,offset为3时,对应的bit值为0,依此类推…如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
172.16.12.3:6379> getbit k1 0
(integer) 0
172.16.12.3:6379> getbit k1 1
(integer) 1
172.16.12.3:6379> getbit k1 2
(integer) 1
172.16.12.3:6379> getbit k1 3
(integer) 0
172.16.12.3:6379> getbit k1 4
(integer) 0
172.16.12.3:6379> getbit k1 5
(integer) 0
172.16.12.3:6379> getbit k1 6
(integer) 0
172.16.12.3:6379> getbit k1 7
(integer) 1

setbit

setbit可以用来修改二进制数据, 举个例子,如下对照表:

控制字符 ASCII值 二进制值
a 97 01100001
b 99 01100011

可以看到 a和c的二进制值,区别在于第六位(下标从0开始), 一个是0 一个是 1, 我们可以通过setbit命令,将上面添加的k1的第六位改为1,如下:

1
2
3
4
5
6
172.16.12.3:6379> get k1
"a"
172.16.12.3:6379> setbit k1 6 1
(integer) 0
172.16.12.3:6379> get k1
"c"

这时,可以看到,k1的value从a变成了c, setbit命令的返回值,是该位上原本的bit值.

bitcount

bitcount命令,可以统计二进制数据中的,1的个数,比如我们k1现在的二进制值是01100011,里面有4个1,然后返回就是4,如下:

1
2
172.16.12.3:6379> bitcount k1
(integer) 4

关于这个命令,redis官网上有一个使用案例:统计用户上线次数,如下:

举个例子,如果今天是网站上线的第 100 天,而用户 peter 在今天阅览过网站,那么执行命令 SETBIT peter 100 1 ;如果明天 peter 也继续阅览网站,那么执行命令 SETBIT peter 101 1 ,以此类推。
当要计算 peter 总共以来的上线次数时,就使用 BITCOUNT 命令:执行 BITCOUNT peter ,得出的结果就是 peter 上线的总天数。

用这种方式去统计,好处就是节省空间而且运行速度快,每天占用一个bit,年也就365个bit,10年也就10*365个bit,也就是456个字节,对于这么大的数据,bit的操作速度非常快.

bitop

该命令语法如下:

1
BITOP operation destkey key [key ...]

对一个或多个保存二进制位的字符串 key 进行位元操作,并将结果保存到 destkey 上,bittop 命令支持 AND(并), OR(或) , NOT(非) , XOR(异或) 这四种操作中的任意一种

除了 NOT 操作之外,其他操作都可以接受一个或多个 key 作为输入, 执行结果将始终保持到destkey里面

使用案例如下:

1
2
3
4
5
6
7
8
9
10
11
12
172.16.12.3:6379> set k1 a
OK
172.16.12.3:6379> set k2 c
OK
172.16.12.3:6379> bitop and k3 k1 k2
(integer) 1
172.16.12.3:6379> get k3
"a"
172.16.12.3:6379> bitop xor k3 k1 k2
(integer) 1
172.16.12.3:6379> get k3
"\x02"

执行not只能有一个key作为输入,使用如下:

1
2
172.16.12.3:6379> bitop not k3 k4
(integer) 2

这里会对k4的二进制位串取反,将取反结果交给k3.

这个逻辑运算,我没搞懂到底是怎算的, 官网文档在这里

bitpos

bitops命令,用来获取二进制位串中的第一个1或者0的位置,使用如下

1
2
3
4
172.16.12.3:6379> bitpos k1 1
(integer) 1
172.16.12.3:6379> bitpos k1 0
(integer) 0

他的语法其实是bitpos key bit [start] [end],就是说可以在后面设置一个范围,但是这个范围是字节的范围,而不是二进制位串的范围