版权声明: 转载请注明出处!本文采用 知识共享 署名-非商业性使用-禁止演绎 4.0 国际许可协议
前言
今天的内容包括两个命令,其中的 BITCOUNT 很简单,就是数一下指定键的值存储的二进制中有多少个1,而 BITFIELD 这个命令就复杂多了,接下来一起看一下。
BITCOUNT
- 最早出现版本:2.6.0
- 时间复杂度:O(1)
- 命令参数:BITCOUNT key [start end]
- 操作类型:strings
- 官方文档
作用
这个命令的作用看名字就明白了, BITCOUNT 其实就是数指定键的值(二进制表示)中包含了多少个1,其实就是数1问题,相信很多人在面试题中都看到过类似的,这个在Redis中一个命令就搞定了,不需要自己来实现其他的逻辑了,如果指定的键不存在,则返回0,这个命令还有额外的两个参数,起始索引和结束索引,单位是字节,默认是整个字符串,索引参数支持负数,-1表示最后一个字节或字符,-2表示倒数第二个,依次类推。
练习
命令的作用很简单,配合之前学的 SETBIT 命令,先设置几个位,然后使用 BITCOUNT 命令数一下到底有几个位的值是1:
127.0.0.1:6379> SETBIT var 7 1
(integer) 0
127.0.0.1:6379> SETBIT var 5 1
(integer) 0
127.0.0.1:6379> GET var
"\x05"
127.0.0.1:6379> BITCOUNT var
(integer) 2
127.0.0.1:6379>
我们设置了两个位置为1,十六进制的表示为0x05,其实二进制表示为0000 0101,所以其中有两个位置的值是1,返回值是2。
这个常用来事项Bitmap算法,可以使用位来记录用户登录的日期,然后使用 BITCOUNT 命令直接读取其中有几个1就可以轻松统计出来了。
BITFIELD
- 最早出现版本:3.2.0
- 时间复杂度:O(1) (对于每个子命令来说)
- 命令参数:BITFIELD key [GET type offset] [SET type offset value] [INCRBY type offset increment] [OVERFLOW WRAP|SAT|FAIL]
- 操作类型:strings
- 官方文档
作用
这个命令是我学习 Redis 命令以来见过的最长的命令,其实后面的命令都被叫做子命令,其实就是在 Redis 中把字符串看成是位数组,然后在指定的偏移位置,对指定的类型变量进行操作。
这个 BITFIELD 命令后面可以跟 GET 、 SET 和 INCRBY 三种命令,而 OVERFLOW 是用来指定设置越界以后的处理行为的,在这我们了解一下就可以了,先不深究,后面还会慢慢学到的。
BITFIELD 后面可以顺序跟着多个子命令,每个命令都会有一个返回值,最后形成一个返回值数组,GET 子命令会返回指定位置的值,SET 子命令会在设置成功以后返回设置之前的值,INCRBY 会在修改值之后返回新的值,接下来写两个例子就明白了。
练习
把字符串看成是8位一个字节的字节数组,然后将第二个字节代表的数字设置为1,前面的字节默认应该为0,我们测试一下:
127.0.0.1:6379> BITFIELD var SET i8 8 1
1) (integer) 0
127.0.0.1:6379> BITFIELD var GET i8 8
1) (integer) 1
127.0.0.1:6379> GET var
"\x00\x01"
127.0.0.1:6379>
仔细理解一下上面这个操作,实际上是把var对应的字符串看成是字节数组,参数i8表示要设置8位的有符号整数,参数8表示偏移量是8,其实就是第二个字节,第一个条命令是设置成了1,第二个命令是读取出来还是1,查询整个字符串的的值是"\x00\x01",转化成二进制其实就是0000 0000 0000 0001,与我们前面解释的是一致的。
接下来看下一次执行两种操作的情况,返回值会顺序排列的,分析方法按照上面来分析,很容易明白的。
127.0.0.1:6379> BITFIELD var SET i8 8 1 INCRBY i8 16 3
1) (integer) 1
2) (integer) 3
127.0.0.1:6379> GET var2
(nil)
127.0.0.1:6379> GET var
"\x00\x01\x03"
127.0.0.1:6379>
总结
- BITCOUNT 其实就是用来数1的,一个命令就实现,不用再写什么算法了,Redis 直接封装。
- BITFIELD 命令参数非常长,需要仔细研究一下,本质上就是把字符串当成位数组来操作,可以指定类型和偏移量。
2019-12-1 17:27:52