美文网首页Redis
04_redis_位图

04_redis_位图

作者: A_l_A_n | 来源:发表于2020-07-07 11:36 被阅读0次

当存一些bool型数据,比如用户一年的签到此书。如果使用key/value 大数据量需要大量的存储空间。
redis的位图可以解决这个问题。每天签到的记录只占一个位,365天就是365个位,46个字节。大大节省了空间。
位图就是byte数组。

基本使用

127.0.0.1:6379> setbit s 1 1 
(integer) 0 
127.0.0.1:6379> setbit s 2 1 
(integer) 0 
127.0.0.1:6379> setbit s 4 1 
(integer) 0 
127.0.0.1:6379> setbit s 9 1 
(integer) 0 
127.0.0.1:6379> setbit s 10 1 
(integer) 0 
127.0.0.1:6379> setbit s 13 1
(integer) 0 
127.0.0.1:6379> setbit s 15 1 
(integer) 0 
127.0.0.1:6379> get s 
"he"

零存零取

127.0.0.1:6379> setbit w 1 1
(integer) 0
127.0.0.1:6379> setbit w 2 1
(integer) 0
127.0.0.1:6379> setbit w 4 1
(integer) 0
127.0.0.1:6379> getbit w 1 # 获取某个具体位置的值 0/1
(integer) 1
127.0.0.1:6379> getbit w 2
(integer) 1
127.0.0.1:6379> getbit w 4
(integer) 1
127.0.0.1:6379> getbit w 5
(integer) 0

整存零取

127.0.0.1:6379> set w h # 整存
(integer) 0
127.0.0.1:6379> getbit w 1
(integer) 1
127.0.0.1:6379> getbit w 2
(integer) 1
127.0.0.1:6379> getbit w 4
(integer) 1
127.0.0.1:6379> getbit w 5
(integer) 0

如果对应的字节是不能打印的字符,redis-cli会 显示该字符的十六进制

统计和查找

bitcount 、bitpos

bitcount 用来统计 制定范围内1的个数。可以统计用户一年的签到次数
bitpos 用来查找制定范围内第一次出现的0或者1
[start,end]参数用来指定某个时间范围内用户签到的天数, 用户哪一天开始签到的。
但是start和end都是字节参数,所以都必须是8的倍数。不能随意指定。因此我们不能直接计算用户在某个时间段签到了几次,必须要将这个月覆盖的所有字节全部取出来,放到内存中进行处理。

127.0.0.1:6379> set w hello
OK
127.0.0.1:6379> bitcount w
(integer) 21
127.0.0.1:6379> bitcount w 0 0 # 第一个字符中 1 的位数
(integer) 3
127.0.0.1:6379> bitcount w 0 1 # 前两个字符中 1 的位数
(integer) 7
Redis 深度历险:核心原理与应用实践 | 钱文品 著 第 39 页 共 226 页
127.0.0.1:6379> bitpos w 0 # 第一个 0 位
(integer) 0
127.0.0.1:6379> bitpos w 1 # 第一个 1 位
(integer) 1
127.0.0.1:6379> bitpos w 1 1 1 # 从第二个字符算起,第一个 1 位
(integer) 9
127.0.0.1:6379> bitpos w 1 2 2 # 从第三个字符算起,第一个 1 位
(integer) 17

魔术指令bitfield

用来操作多个位,最多连续处理64位,如果超过64位需要 使用多个指令,bitfield可以一次执行多个子指令

get

127.0.0.1:6379> set w hello
OK
127.0.0.1:6379> bitfield w get u4 0 # 从第一个位开始取 4 个位,结果是无符号数 (u)
(integer) 6
127.0.0.1:6379> bitfield w get u3 2 # 从第三个位开始取 3 个位,结果是无符号数 (u)
(integer) 5
127.0.0.1:6379> bitfield w get i4 0 # 从第一个位开始取 4 个位,结果是有符号数 (i)
1) (integer) 6
127.0.0.1:6379> bitfield w get i3 2 # 从第三个位开始取 3 个位,结果是有符号数 (i)
1) (integer) -3

所谓有符号数是指获取的位数组中第一个位是符号位,剩下的才是值。如果第一位是1,那就是负数。无符号数表示非负数,没有符号位,获取的位数组全部都是值。有符号数最多可以获取 64 位,无符号数只能获取 63 位 (因为 Redis 协议中的 integer 是有符号数,最大 64 位,不能传递 64 位无符号值)。如果超出位数限制,Redis 就会告诉你参数错误。
执行多个子指令:

127.0.0.1:6379> bitfield w get u4 0 get u3 2 get i4 0 get i3 2
1) (integer) 6
2) (integer) 5
3) (integer) 6
4) (integer) -3

set 子指令

将第二个字符 e 改成 a,a 的 ASCII 码是 97。

127.0.0.1:6379> bitfield w set u8 8 97 # 从第 8 个位开始,将接下来的 8 个位用无符号数 97 替换
1) (integer) 101
127.0.0.1:6379> get w
"hallo"

incrby

指定范围内自增。如果溢出,redis的默认方法是折返, 将溢出的符号位丢掉。比如8位 无符号位255,增加一位就会溢出,变成0。如果是8位有符号位位127,加1溢出变为-128

127.0.0.1:6379> set w hello
OK
127.0.0.1:6379> bitfield w incrby u4 2 1 # 从第三个位开始,对接下来的 4 位无符号数 +1
1) (integer) 11
127.0.0.1:6379> bitfield w incrby u4 2 1
1) (integer) 12
127.0.0.1:6379> bitfield w incrby u4 2 1
1) (integer) 13
127.0.0.1:6379> bitfield w incrby u4 2 1
1) (integer) 14
127.0.0.1:6379> bitfield w incrby u4 2 1
1) (integer) 15
127.0.0.1:6379> bitfield w incrby u4 2 1 # 溢出折返了
1) (integer) 0

overflow

bitfield指令 提供了溢出策略子指令overflow。
可以选择溢出折返,溢出报错,饱和截断,超过范围就会停留到最大/最小值。overflow只影响下来的第一条指令,这条指令执行完溢出策略会变成默认的折返

饱和截断

127.0.0.1:6379> set w hello
OK
127.0.0.1:6379> bitfield w overflow sat incrby u4 2 1
1) (integer) 11
127.0.0.1:6379> bitfield w overflow sat incrby u4 2 1
1) (integer) 12
127.0.0.1:6379> bitfield w overflow sat incrby u4 2 1
1) (integer) 13
127.0.0.1:6379> bitfield w overflow sat incrby u4 2 1
1) (intege) 14 
127.0.0.1:6379> bitfield w overflow sat incrby u4 2 1 
1) (integer) 15 
127.0.0.1:6379> bitfield w overflow sat incrby u4 2 1 # 保持最大值
1) (integer) 15

失败不执行

127.0.0.1:6379> set w hello
OK
127.0.0.1:6379> bitfield w overflow fail incrby u4 2 1
1) (integer) 11
127.0.0.1:6379> bitfield w overflow fail incrby u4 2 1
1) (integer) 12
127.0.0.1:6379> bitfield w overflow fail incrby u4 2 1
1) (integer) 13
127.0.0.1:6379> bitfield w overflow fail incrby u4 2 1
1) (integer) 14
127.0.0.1:6379> bitfield w overflow fail incrby u4 2 1
1) (integer) 15
127.0.0.1:6379> bitfield w overflow fail incrby u4 2 1 # 不执行
1) (nil)

相关文章

  • 04_redis_位图

    当存一些bool型数据,比如用户一年的签到此书。如果使用key/value 大数据量需要大量的存储空间。redi...

  • 两个位图覆盖合成为一个位图

    /** *把两个位图覆盖合成为一个位图,以底层位图的长宽为基准 *@parambackBitmap在底部的位图 *...

  • BMP位图格式解析

    一般BMP图像文件由以下4部分组成:位图文件头、位图信息头、调色板、实际的位图数据。位图文件头数据结构: 位图信息...

  • 干货 | 非常完整的人体穴位图与功效(果断收藏)

    人体穴位作用图解大全更清晰直观的标注了各个人体穴位,包括头部穴位图、胸部穴位图、背部穴位图、胳膊手部穴位图、人体腿...

  • CorelDRAW位图转换矢量图

    使用CorelDRAW 软件中的快速描摹位图就是可以使位图转化为矢量图的一个过程,不过描摹位图之后,会丢掉很多位图...

  • 位图和布隆过滤器

    位图 位图的概念 位图(bitmap)其实就是哈希表的一种特殊情况。不同的是位图是通过二进制位来表示数据是否存在。...

  • ESP8266学习:U8G2驱动OLED

    drawXBM x:X位置。y:Y位置。w:位图的宽度。h:位图的高度。bitmap:指向位图开始的指针 draw...

  • 关于一些东西

    简述矢量图和位图的区别。 答:根据存储方式的不同,电脑图形或图像可分为两大类,即位图和矢量图。 位图:位图比较适合...

  • iOS Skeleton Screen加载占位图

    iOS Skeleton Screen加载占位图 iOS Skeleton Screen加载占位图

  • Redis第1️⃣3️⃣课 BitMap 位图

    字母big的位图,对应上图 设置位图会触发补零操作 所以最好不要在一个很小的位图上往后很多位上设置位图。这不得不补...

网友评论

    本文标题:04_redis_位图

    本文链接:https://www.haomeiwen.com/subject/glqgqktx.html