4. redis数据类型之String-bit

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6


Redis 字符串 string-bit


前面我们介绍了Redis中的字符串类型的基本命令操作。但是没有涉及到bit相关的命令。本文我们来看几个bit相关的命令。

bit相关的命令指的是 bitcount , bitfield, bitop, bitpos, setbit, getbit 几个命令。

准备知识

在学习这几个命令之前。我们需要知道,redis中的字符串的存储方式,是采用二进制的方式进行存储的,如果下面的命令:

127.0.0.1:6379> set name a
OK

a对应的ASCII码对应的是97,转换为二进制就是 0110 0001 ,我们bit相关的命令就是基于这个二进制数据进行操作的。

getbit

getbit 命令可以返回key对应的value在offset处的bit值。例如如上key为name,value为a。a对应的二进制是 0110 0001,所以当offset为0时,对应的bit值是0.当offset为1时,对应的bit值是1,offset为2时,对应的bit值为1…以此类推。 如下:

127.0.0.1:6379> set name a
OK
127.0.0.1:6379> getbit name 0
(integer) 0
127.0.0.1:6379> getbit name 1
(integer) 1
127.0.0.1:6379> getbit name 2
(integer) 1
127.0.0.1:6379> getbit name 3
(integer) 0
127.0.0.1:6379> getbit name 4
(integer) 0
127.0.0.1:6379> getbit name 5
(integer) 0
127.0.0.1:6379> getbit name 6
(integer) 0
127.0.0.1:6379> getbit name 7
(integer) 1

setbit

setbit命令可以用来修改二进制数据,比如a对应的ASCII码对应为97,而 b的ASCII码对应为98. 98所对应的二进制数为 0110 0010.下面我们通过setbit来修改对应位置上的数据。只需将第六位设置1,第七位设置为0即可。如下:

127.0.0.1:6379> setbit name 6 1
(integer) 0
127.0.0.1:6379> setbit name 7 0
(integer) 1
127.0.0.1:6379> get name
"b"

此时,name的存储的字符串由a变成了b。setbit在执行时返回的数据,表示该位置上原来的bit值。

bitcount

bitcount 可以用来统计这个二进制数据中的1的个数。如下:

127.0.0.1:6379> set name a
OK
127.0.0.1:6379> bitcount name
(integer) 3

关于bitcount,redis官方网站上有一个非常有意思的案例:用户上线次数统计。节选部分原文如下:

举一个例子,如果今天是网站上线的第100天,而用户Peter在今天浏览过网站,那么执行命令 setbit peter 100 1; 如果明天也继续浏览了网站,那么执行命令setbit peter 101 1,以此类推。当要计算peter总共以来上线了多少次。就可以是用bitcount命令。执行bitcount peter,得出的结果就是peter上线的总天数。

这种统计方式最大的好处就是节省空间并且计算速度非常快。每天占用一个bit。一年也就只要365个bit。10年也才3650个bit。也就是456个字节。对于这么大的数据。bit操作速度是非常快的。

bitop

bitop可以对一个或者多个二进制位串执行并(and),或(or),异或(xor)以及非(not)运算。如下:a对应的ASCII码对应的是0110 0001 , c对应的二进制为 0110 0011.对于这两个二进制串分别执行 and/or/xor/not的结果为:

127.0.0.1:6379> set k1 a
OK
127.0.0.1:6379> set k2 c
OK
127.0.0.1:6379> bitop and k3 k1 k2
(integer) 1
127.0.0.1:6379> get k3
"a"
127.0.0.1:6379> bitop or k3 k1 k2
(integer) 1
127.0.0.1:6379> get k3
"c"
127.0.0.1:6379> bitop xor k3 k1 k2
(integer) 1
127.0.0.1:6379> get k3
"\x02"

另外,bitop也可以执行not操作,但是只需一个参数,如下:

127.0.0.1:6379> bitop not k3 k1
(integer) 1
127.0.0.1:6379> get k3
"\x9e"

下面我们手动来验证一下:a = > 0110 0001. c => 011 0011

and.

1 1 得 1, 1 0 得 0 , 0 1 得 0 , 0 0 得 0;

0 1 1 0 0 0 0 1

0 1 1 0 0 0 1 1

0 1 1 0 0 0 0 1 => a

or.

1 1 得 1,1 0 得 1, 0 1 得 1, 0 0 得 0

0 1 1 0 0 0 0 1

0 1 1 0 0 0 1 1

0 1 1 0 0 0 1 1 => c

xor.

1 1 得 0,1 0 得 1 ,0 1 得 1 ,0 0 得 0

0 1 1 0 0 0 0 1

0 1 1 0 0 0 1 1

0 0 0 0 0 0 1 0 => 2 转为16进行为 2

not.

0 1 1 0 0 0 0 1

1 0 0 1 1 1 1 0 => 2^7 + 2^ 4 + 2^3 + 2^2 + 2^1 = 128 + 16 + 8 + 4 + 2 = 158 转为16进制为 9e

bitpos

bitops 用来获取二进制位串中第一个1或者0 的位置。如下:

127.0.0.1:6379> bitpos k1 1
(integer) 1
127.0.0.1:6379> bitpos k1 0
(integer) 0

也可以在后面设置一个范围,不过后面的范围是字节的范围,而不是二进制位串的范围。

关于redis的bit字符串类型就先介绍到这里,如果需要更加详细的文档,可以移步官方文档:

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: redis