Redis系列之位图简介

举报
yd_273762914 发表于 2020/12/02 23:03:46 2020/12/02
【摘要】 文章目录 位图定义应用场景基本使用查找统计 位图定义 位图并不是一种数据结构,其实就是一种普通的字符串,也可以说是byte数组。基本语法是setbit/getbit,刚才说了是一个byte数组,所以也可以用set/get设置或获取 SetBit语法: Setbit KEY_NAME OFFSET GetBit语法: Getbit KEY_N...

位图定义

位图并不是一种数据结构,其实就是一种普通的字符串,也可以说是byte数组。基本语法是setbit/getbit,刚才说了是一个byte数组,所以也可以用set/get设置或获取

SetBit语法: Setbit KEY_NAME OFFSET

GetBit语法: Getbit KEY_NAME OFFSET

应用场景

上面介绍了redis的位图,对于redis位图有什么应用场景?假如要统计用户一年签到次数,这里如果用记录表来记录的话,每个用户就用存365条记录,一千个用户就是365*1000条记录,想一下这个数据量是不少的,而且实际业务意义不是很明显,那么有什么高效的方法可以替换?其实可以用本博客介绍的Redis位图来实现,刚才说了位图就是byte数字,假如签到就表示1,没签到就表示0,这里可以用365个字节来记录前端数,这样很节省资源了,提高了效率。这个例子就是redis位图的很好应用,比如用户签到统计,月活跃用户数统计等等业务场景都适合用位图实现

基本使用

Redis位图的基本语法是setbit/getbit,按照一次只存一个字节,还是一次一个数组字符串整个存的情况,分为[零存整取]、[零存零取]、[整存零取],下面介绍的例子来自《Redis深度历险:核心原理与应用实践》一书

对于字符串’hello’,换成ASCII码的二进制为:
‘h’:0b1101000’

‘e’:0b1100101’

‘l’:0b1101100’

‘l’:0b1101100’

‘o’:‘0b1101111’
[零存整取]的情况:setbit key为tk

//在第二位存“1”
127.0.0.1:6379> setbit tk 1 1
(integer) 0
//在第三位存"1"
127.0.0.1:6379> setbit tk 2 1
(integer) 0
//在第五位存"1"
127.0.0.1:6379> setbit tk 4 1
(integer) 0
//整个字节数组取出来
127.0.0.1:6379> get tk
"h"
127.0.0.1:6379>

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

[零存零取]的情况:

//在第二位加“1”位
127.0.0.1:6379> setbit tk 1 1
(integer) 1
//在第三位加“1”位
127.0.0.1:6379> setbit tk 2 1
(integer) 1
//在第五位加“1”为
127.0.0.1:6379> setbit tk 4 1
(integer) 1
//取出第二位
127.0.0.1:6379> getbit tk 1
(integer) 1
//取出第三位
127.0.0.1:6379> getbit tk 2
(integer) 1
//取出第五位
127.0.0.1:6379> getbit tk 4
(integer) 1
//取出第六位
127.0.0.1:6379> getbit tk 5
(integer) 0
127.0.0.1:6379>

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

[整存零取]

//存整个字符
127.0.0.1:6379> set tk h
OK
//获取一下第二位
127.0.0.1:6379> getbit tk 1
(integer) 1
//获取一下第三位
127.0.0.1:6379> getbit tk 2
(integer) 1
//获取一下第五位
127.0.0.1:6379> getbit tk 4
(integer) 1
//获取一下第六位
127.0.0.1:6379> getbit tk 5
(integer) 0
127.0.0.1:6379>

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

特殊情况:

127.0.0.1:6379> setbit tk 0 1
(integer) 1
127.0.0.1:6379> setbit tk 1 1
(integer) 1
//不代表任何字符,返回16进制符号
127.0.0.1:6379> get tk
"\xc0"
127.0.0.1:6379>

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

查找统计

Redis有提供查询和统计函数,分别是bitpos和bitcount函数,其语法分别为:

bitcount语法:bitcount key [start end]

bitpos语法:bitpos key bit [start] [end]

127.0.0.1:6379> set tk hello
OK
//从第1个字符h算起,第一个“1”位的位置
127.0.0.1:6379> bitpos tk 1 1 1
(integer) 9
//从第2个字符2算起,第一个“1”位的位置
127.0.0.1:6379> bitpos tk 1 2 2
(integer) 17
//第一个“0”位
127.0.0.1:6379> bitpos tk 0
(integer) 0
//第一个“1”位
127.0.0.1:6379> bitpos tk 1
(integer) 1
//统计tk“1”的数量
127.0.0.1:6379> bitcount tk
(integer) 21
//第一个字符h的“1”位数量
127.0.0.1:6379> bitcount tk 0 0
(integer) 3
//第一个字符h和第二个字符e“1”位的数量
127.0.0.1:6379> bitcount tk 0 1
(integer) 7
127.0.0.1:6379>

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

文章来源: smilenicky.blog.csdn.net,作者:smileNicky,版权归原作者所有,如需转载,请联系作者。

原文链接:smilenicky.blog.csdn.net/article/details/87923407

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。