暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Redis每日一练(09):BITCOUNT和BITFIELD命令

原创 AlbertS 2019-12-10
4084

版权声明: 转载请注明出处!本文采用 知识共享 署名-非商业性使用-禁止演绎 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>

总结

  1. BITCOUNT 其实就是用来数1的,一个命令就实现,不用再写什么算法了,Redis 直接封装。
  2. BITFIELD 命令参数非常长,需要仔细研究一下,本质上就是把字符串当成位数组来操作,可以指定类型和偏移量。

2019-12-1 17:27:52

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论