5.4 位图数据类型的应用

在Redis里,位图(Bitmap)是由一串二进制数字组成的,它不是一种数据类型,而是基于字符串、能面向字节操作的对象.位图的长度不固定,但是在计算机里8位(bit)能组成一个字节(Byte),所以位图的长度一般是8或者是8的倍数

5.4.1 SETBITGETBIT操作

  • SETBIT

    • 语法:SETBIT key offset value.其中:

      • offset:偏移量(偏移量从左到右计算)

      • value:待设置的值

    • 功能:设置指定键的位图数据

  • GETBIT

    • 语法:GETBIT key offset

    • 功能:读取位图指定位数据.若指定位不存在则返回0

例:

设置位图:

127.0.0.1:6379> SETBIT myBitmap 0 1
(integer) 0
127.0.0.1:6379> SETBIT myBitmap 1 1
(integer) 0
127.0.0.1:6379> SETBIT myBitmap 2 0
(integer) 0
127.0.0.1:6379> SETBIT myBitmap 3 0
(integer) 0
127.0.0.1:6379> SETBIT myBitmap 5 1
(integer) 0

注意:设置位图数据时只能将值设置为0或1:

127.0.0.1:6379> SETBIT myBitmap 7 3
(error) ERR bit is not an integer or out of range

读取位图:

127.0.0.1:6379> GETBIT myBitmap 1
(integer) 1
127.0.0.1:6379> GETBIT myBitmap 3
(integer) 0

读取一个不存在的位:

127.0.0.1:6379> GETBIT myBitmap 7
(integer) 0

5.4.2 用BITOP对位图进行运算

  • BITOP

    • 语法:BITOP operation destkey key [key ...].其中:

      • operation:操作符.

        • AND:按位与

        • OR:按位或

        • XOR:按位异或(如果两个比较的位相同,则结果为0;如果两个比较的位不同,则结果为1)

        • NOT:按位取反

      • destkey:用于保存运算结果的key名

    • 功能:操作位图

例:

创建2个位图:

127.0.0.1:6379> SETBIT bit1 0 1
(integer) 0
127.0.0.1:6379> SETBIT bit1 1 1
(integer) 0
127.0.0.1:6379> SETBIT bit1 3 1
(integer) 0
127.0.0.1:6379> SETBIT bit2 2 1
(integer) 0

即:

  • bit1:1011

  • bit2:0100

按位与操作:

注:按位与操作的结果应为0000

127.0.0.1:6379> BITOP AND result bit1 bit2
(integer) 1

查看结果:

127.0.0.1:6379> GETBIT result 0
(integer) 0
127.0.0.1:6379> GETBIT result 1
(integer) 0
127.0.0.1:6379> GETBIT result 2
(integer) 0
127.0.0.1:6379> GETBIT result 3
(integer) 0
127.0.0.1:6379> get result
"\x00"

按位或操作:

注:按位或操作的结果应为1111

127.0.0.1:6379> BITOP OR result bit1 bit2
(integer) 1

查看结果:

127.0.0.1:6379> GETBIT result 0
(integer) 1
127.0.0.1:6379> GETBIT result 1
(integer) 1
127.0.0.1:6379> GETBIT result 2
(integer) 1
127.0.0.1:6379> GETBIT result 3
(integer) 1

按位取反操作:

注:bit1按位取反的结果应为0100

127.0.0.1:6379> BITOP not result bit1
(integer) 1

查看结果:

127.0.0.1:6379> GETBIT result 0
(integer) 0
127.0.0.1:6379> GETBIT result 1
(integer) 0
127.0.0.1:6379> GETBIT result 2
(integer) 1
127.0.0.1:6379> GETBIT result 3
(integer) 0

按位异或操作:

注:按位异或的结果应为1111

BITOP xor result bit1 bit2

查看结果:

127.0.0.1:6379> GETBIT result 0
(integer) 1
127.0.0.1:6379> GETBIT result 1
(integer) 1
127.0.0.1:6379> GETBIT result 2
(integer) 1
127.0.0.1:6379> GETBIT result 3
(integer) 1

5.4.3 BITCOUNT操作

  • BITCOUNT

    • 语法:BITCOUNT key [start end]

    • 功能:统计key在指定范围内的1的出现次数.0, -1或不写参数表示统计范围为整个key

注:关于BITCOUNT命令中的start, end:

start, end表示字符串中的字节偏移,而不是比特偏移.这一点非常重要.

  • start:是子范围的起始字节位置(从0开始)

  • end:是子范围的结束字节位置

例如,对于字符串"foobar":

  • 字符"f"在字节偏移0中

  • 字符"o"在字节偏移1和2中

  • 字符"b"在字节偏移3中

  • ...以此类推。

如果你执行命令BITCOUNT key 0 1.它会计算"fo"中设置为1的比特位的数量,因为"fo"占据了字节偏移0到1

还有一些其他需要注意的事项:

  1. 当start和end都是正数或0时,范围包括start和end两端

  2. 当start或end是负数时,它表示从字符串的末尾开始的偏移.例如,-1表示字符串的最后一个字节

  3. 如果start大于字符串的长度,或end小于0,结果将是 0

  4. 如果end在start之后,则它们会被交换.所以命令BITCOUNT key 2 0BITCOUNT key 0 2会产生相同的结果

例:统计用户在线天数

设置用户在线天数

127.0.0.1:6379> SETBIT user1 0 1
(integer) 0
127.0.0.1:6379> SETBIT user1 3 1
(integer) 0
127.0.0.1:6379> SETBIT user1 7 1
(integer) 0

统计用户在线天数:

127.0.0.1:6379> BITCOUNT user1
(integer) 3
127.0.0.1:6379> BITCOUNT user1 0 0
(integer) 3

Last updated