简介:
   位图(bitmap)同样属于string数据类型。Redis中一个字符串类型的值最多能存储 512 MB 的内容,每个字符串由多个字节组成,每个
字节又由 8 个Bit 位组成。位图结构正是使用“位”来实现存储的,它通过将比特位设置为0或1来达到数据存取的目的这大大增加了 value 
存储数量,它存储上限为2^32 。

 位图本质上就是一个普通的字节串,也就是 bytes 数组。您可以使用getbit/setbit命令来处理这个位数组,位图的结构如下所示:


     位图适用于一些特定的应用场景,比如用户签到次数、或者登录次数等。上图是表示一位用户 10 天内来网站的签到次数,1 代表签到,0 代表未签到,这样可以很轻松地统计出用户的活跃程度。相比于直接使用字符串而言,位图中的每一条记录仅占用一个 bit 位,从而大大降低了内存空间使用率。

位图常用命令

1) SETBIT命令

用来设置或者清除某一位上的值,其返回值是原来位上存储的值。key 在初始状态下所有的位都为 0 ,可以自动扩容,最大为40多个亿,语法格式如下:

SETBIT key offset value

其中 offset 表示偏移量,从 0 开始。示例如下:

127.0.0.1:6379> setbit k1 1 1
(integer) 0
127.0.0.1:6379> get k1
"@"
127.0.0.1:6379> STRLEN k1
(integer) 1


127.0.0.1:6379> setbit k1 7 1
(integer) 0
127.0.0.1:6379> get k1
"A"
127.0.0.1:6379> STRLEN k1
(integer) 1


127.0.0.1:6379> setbit k1 9 1  
(integer) 0
127.0.0.1:6379> get k1
"A@"
127.0.0.1:6379> STRLEN k1
(integer) 2

2) GETBIT命令

用来获取某一位上的值。语法格式如下:

GEIBIT KEY  OFFSET

示例如下:

127.0.0.1:6379> GETBIT K1  1
(integer) 1

当偏移量 offset 比字符串的长度大,或者当 key 不存在时,返回 0。

127.0.0.1:6379> GETBIT k1 100000   超过字符串长度
(integer) 0
127.0.0.1:6379> GETBIT k2 0   key不存在
(integer) 0

3) BITCOUNT命令

一般情况下,给定的整个字符串都会被进行计数,通过指定额外的 start 或 end 参数,可以让计数只在特定的位上进行。

start 和 end 参数的设置,都可以使用负数值:比如 -1 表示最后一个位,而 -2 表示倒数第二个位,

start、end 是指bit组的字节的下标数,二者皆包含。

如上 K1 【01000001 01000000  00000000 00100001】,对应【0,1,2,3】

bitcount K1 1 2  : 统计下标1、2字节组中bit=1的个数,即01000000  00000000。

语法格式如下:

BITCOUNT key [start end]

示例如下:

127.0.0.1:6379> setbit k1 1 1
(integer) 0
127.0.0.1:6379> setbit k1 7 1
(integer) 0
127.0.0.1:6379> setbit k1 9 1
(integer) 0
127.0.0.1:6379> get k1
"A@"
127.0.0.1:6379> BITCOUNT k1 0 0   获取字节索引为1   1的个数
(integer) 2
127.0.0.1:6379> BITCOUNT k1 0 1   获取字节索引为1-2  1的个数
(integer) 3

 通过指定的 start 和 end 参数,可以让计数只在特定的字节上进行。start 和 end 参数和 GETRANGE 命令的参数类似,都可以使用负数,比如 -1 表示倒数第一个位, -2 表示倒数第二个位。

4) .bitpos返回指定值0或者1在指定区间上首次出现的下标

语法:BITPOS key bit [start] [end](字节索引,0表示第一个字节)

summary: Find first bit set or clear in a string
since: 2.8.7
group: string

不指定查找范围,表示从全部内容中查找:BITPOS key bit

127.0.0.1:6379> BITPOS k1 1 
(integer) 1
127.0.0.1:6379> setbit k1 1 0
(integer) 1
127.0.0.1:6379> BITPOS k1 1 
(integer) 7

   红色位为setbit 修改的地方,绿色位修改完成的地方

  BITPOS key bit start :从start+1个字节开始查找,直到尾部
  BITPOS key bit start end:从start+1字节开始到end+1字节之间查找

127.0.0.1:6379> setbit k1 1 1
(integer) 0
127.0.0.1:6379> BITPOS k1 1 0
(integer) 1
127.0.0.1:6379> BITPOS k1 1 2 0   找不到返回-1
(integer) -1

5).bitop位操作

语法:BITOP operation destkey key [key ...]

summary: Perform bitwise operations between strings
since: 2.6.0
group: string

对一个或多个保存二进制位的字符串 key 进行位操作,并将结果保存到 destkey 上。operation 可以是 AND 、 OR 、 NOT 、 XOR 这四种操作中的任意一种

BITOP AND destkey key [key ...] ,对一个或多个 key 求逻与,并将结果保存到 destkey

BITOP OR destkey key [key ...] ,对一个或多个 key 求逻辑或,并将结果保存到 destkey

BITOP XOR destkey key [key ...] ,对一个或多个 key 求逻辑异或,并将结果保存到 destkey

BITOP NOT destkey key ,对给定 key 求逻辑非,并将结果保存到 destkey

除了 NOT 操作之外,其他操作都可以接受一个或多个 key 作为输入,当 BITOP 处理不同长度的字符串时,较短的那个字符串所缺少的部分会被看作 0,空的 key 也被看作是包含 0 的字符串序列。

BITOP AND destkey key [key ...]

演示:

127.0.0.1:6379> setbit k1 1 1
(integer) 0
127.0.0.1:6379> setbit k2 7 1
(integer) 0
127.0.0.1:6379> BITOP and andkey k1 k2
(integer) 1
127.0.0.1:6379> get andkey
"\x00"

        全为1则为1,否则为0

 BITOP OR destkey key [key ...]

演示:

127.0.0.1:6379> bitop or orkey k1 k2
(integer) 1
127.0.0.1:6379> get orkey
"A"

            全为0则为0,否则为1 

BITOP XOR destkey key [key ...]

演示:

127.0.0.1:6379> bitop xor xorkey k1 k2
(integer) 1
127.0.0.1:6379> get xorkey
"A"

       不同为1,相同为0

BITOP NOT destkey key 

演示:

127.0.0.1:6379> bitop not notkey k1
(integer) 1
127.0.0.1:6379> get notkey
"\xbf"

    按位取反

Bitmaps优势

假设网站有1亿用户,每天独立访问的用户有5千万,如果每天用集合类型和 Bitmaps分别存储活跃用户,很明显,假如用户id是Long型,64位,则集合类型占据的空间为64位x50 000 000= 400MB,而Bitmaps则需要1位×100 000 000=12.5MB,可见Bitmaps能节省很多的内存空间。

​​​​​​​

举例:1、普通字符串操作

           2、模拟用户点赞统计 

           3、统计用户活跃度

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐