剑指 Offer:一文带你吃透麻辣鲜香的redis数据类型!

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: 剑指 Offer:一文带你吃透麻辣鲜香的redis数据类型!

引言

一日三餐不可少,好友宴请炊烟袅,干煸烘烤一起炒,String、list、hash、set不难搞!

话说小面的朋友张三近日寻得一新东家,近期就要上任了,特于周末宴请自己的同事到小窝吃饭,张三为显诚意,特地在家自制晚餐招待大家,同事大大是老前辈了,率先提出让大家就今天的饭菜制作过程和菜品来谈一谈redis的value类型

大大:想必大家都用过redis,但总共有哪些存储结构的数据类型呢?

可可:我知道,redis的value类型有字符串(strings), 散列(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets)

string

不不:张三这会正在搓面团,我就这个面来谈一谈String类型,面粉可以衍生出多种常吃食物比如包子、馒头、面条、面包、抄手等等。我们平常都会说一坨面或者一团面,那其实就像是我们大多数时候往redis里放的数据结构k,v->k是String类型,value是Object类型,管他三七二十一,将想要缓存的对象用这种方式放到redis,需要时直接取出来使用,当我们装好redis服务端并用客户端连接上后,在redis客户端对String常用的操作有

set k1 aabb
get k1

还可以help set查看跟哪些参数

helpset.png

set k1 hello
set k1 ooxx nx      #这个nx表示当k1这个key不存在时才去设置,应用场景比如分布式锁
get k1

这个nx比如一堆连接去创建某个Key,但是只有一个会返回成功,其他都会失败

set k2 hello xx #xx表示只能更新,就是说这个Key是预先存在的

mset 这个命令后面可以跟多个key-valuemget 对应多个key取出


更多的可以直接 help@string来查看更多命令 比如APPENDGETRANGESTRLEN k1 取长度

就说面粉做的那个小笼包,外面基本上都是蒸笼一笼一笼的重着放,我们可以把最上面的一笼标记为1也可以把最下面的一笼标记为1,在redis对String类型处理中就类似的情况是正反向索引

我们可以通过0到-1来遍历整个字符串

type命令 可以查看key的value类型,属于哪个分组就是哪个类型OBJECT 命令可以查看key的encoding,查看更多关于object可以 输入object help查看帮助

object简单使用

在key的结构里除了存储key的名字还存储了vaule的type以及encoding,客户端如java代码对某些key操作时,比如类型不匹配可以直接报错

继续拿这个面粉说事,我每天早上去办公室楼下买早餐,里面卖的各色馅的包子,花卷,馒头都是有价格的,柜台流水关于这个包子等都是一个一个相加的,也就是说可以进行计算,redis也设计了这个数值类型的String,可以直接在redis侧进行数值计算

INCR

继续看个小实验,我们将k2用字符和数值的方式都来搞一下可以看见k2的type会根据操作进行变换 继续跟着实验

set k3 a
strlen k3 # 结果为1
APPEND k3 中
strlen k3 #长度为4,为什么?因为二进制安全,当前用的xshell连接的字符集是utf-8,一个中占3个字节,a一个字节

二进制安全

redis在存储时使用的是字节流,是二进制安全的,所以比如java代码在设置和取值时就要约定好编码解码的字符集。我们分别在utf-8和GBK的字符下set一个中字,结果在utf-8下长度为3,GBK下长度为2

我们再看一下value的存储字节加上参数raw后它就会按照utf-8进行结果输出

bitmap

你们看张三做的那个红糖锅盔和红糖糍粑就像是二进制的0101010100011这样的,不禁就想到了redis的String当中还有一种bitmap的操作,我们先来看下有关它的操作

setbitsetbit是对位进行操作置1,取值是二进制对应的ASCII码,01000000对应@,01000001对应Abitpos,找的是二进制字符流指定的位置,结果是二进制的位的位置命令bitcount* 统计key的字节里包含1的个数命令bitop对两个Key进行按位与、或、非、异或bitop应用场景比如:

  • 统计某个网站的用户一年365天某个随即时间段的登录天数
  • 比如京东是我们在开发,现在有个需求双十一要给用户送礼物,京东总共有2亿用户要准备多少礼品呢?这就涉及到到底有多少活跃用户

做个小结并把刚刚bitop应用简单说明一下

List

哔哔:刚刚不不讲解了String类型的value,我来讲讲这个list吧。话说张三刚刚做凉虾的时候我看那个米浆糊糊是挨着密漏一点点的往下挤到盆里,这个过程是连续的并且是先挨着出口的先出,后挨着出口的后出,就像是一个链先进先出就像队列一样 描述队列,反向命令lpush rpop张三穿的烧烤肉块串在吃的时候是先吃的最后穿上去的,就像是栈一样后进先出 描述栈的命令有lpush lpoprpush rpop,后进先出,同向命令接下来我们看看有关一些list的操作命令LRANGE遍历list list也是有正负向索引的LINDEX 根据索引取值LSET根据索引更新

LINSERT插入操作

LREM移除元素,中间的count有正数负数和零,正数就是从左数

LLEN统计长度,BLPOP,BRPOP阻塞的,一直等着有元素了就pop出来,模拟一下就是我开redis3个客户端,第一个和第二个使用blpop ooxx 0,这时候2个都阻塞着了,第三个客户端使用rpush ooxx hello,第一个拿到元素,第二个还是阻塞,第三个客户端重复压入数据,第二个拿到元素。更多关于list操作我们可以通过help @list查看关于list类型的命令帮助

hash

点点:你们都说的挺好的,我看张三做的糖醋排骨非常香,总共有15块,颜色是红泛黑,每块大约30g重量共计450g,形状都是长方体非常的标准,有着浓浓的番茄酱香,说着都有点流口水了,我刚刚描述的糖醋排骨可以用redis中的hash来存储,我们把key设为糖醋排骨,它有数量、重量、颜色、香味、形状这几个特征,并且可以根据特征类型来赋予不同类型的值,接下来就简单谈一谈hash的操作

help @hash命令基本上可以理解为在string命令前加了Hhset hmset hget hmget hkeys hvals

HINCRBYFLOAT hash也支持对数值的操作

set

赞赞:张三刚刚做的芋儿烧鸡中一个一个的芋儿是不重复的,每个都是独立的,一锅芋儿鸡中的芋儿是混乱的没有任何顺序可言,这个就像是redis中的set类型,接下来我来谈一谈set相关的操作

SADD 添加,SMEMBERS遍历set也可以做多个key的交并差集,SINTER 做多个key的交集,SINTERSTORE 会将结果存在一个目标key里SUNION并集且结果去重SDIFF差集,是有方向性的随机事件SRANDMEMBER,也区分正负数,0不返回,一批人抽3个人中奖,正数不重复一批人抽3个奖,负数可重复(1个人可多次中奖)一批人(比如7个热)来抽20个奖还有一个场景,比如公司年会,奖品数一定小于参会人数且还分1等奖2等奖等等SPOPset小结

sorted_set

张三:接着刚刚赞赞说的这个芋儿,其实我们也可以给它排个序,我们可以根据每个芋儿的重量或者大小来进行排序,这个应用就可以用redis的sorted_set来实现,我就来谈谈它的相关操作吧 理解sorted_set要理解元素是根据排序依据来排序的,这个排序依据就是一些维度指标就比如我刚刚说的重量和大小,再比如我要把水果中的苹果、香蕉、鸭梨来排序,可以根据名称、含糖量、大小、价格、吃货热度来排序,在redis中会给出一个权重分手动的指定你想要的的排序规则命令开头基本上都是Z开头的ZADD添加元素,ZRANGE遍历ZRANGEBYSCORE给权重分比如想取价格由低到高的前2名,该怎么做呢ZRANGE k1 0 1比如想取价格由高到低的前2名呢ZrevRANGE k1 0 1 反向命令(比如取出网易云播放量前10名的歌曲,这个数据就是倒序,因为sorted-set在物理存放的时候是由小到大存放的)ZRANGE k1 -2 -1这个取法还是改变不了顺序

ZSCORE查分值,ZRANK查排名ZINCRBY也支持数值计算

也支持交并差集,ZUNIONSTORE,不带权重、分值,默认是将分值相加带上权重带上分值是怎么实现排序的呢

使用跳跃表,大致结果就是在链表的基础上增加层(基于二分),上面的每一层都像是链表,随机造层是牺牲存储空间来换取查询效率更多操作可以help @sorted_set查看

sorted_set小结

点点:我们刚刚说了它的命令,我用java或者其他语言怎么用呢?

大大:这些redis客户端的命令都会了,还需要去学api吗?不需要的,api也不过是根据这些命令做的一个封装而已,到时候想用那种命令直接用对应的api结合命令试一下就出来了,实在不行在查资料

张三:就是就是,饭也做好了,今天的考题就到此结束,开饭!

总结

通过一场简单的对话相信大家对redis的value类型有了一定的认知和理解,后续遇到问题可以直接使用help命令查看相关说明,api只是程序员具体CRUD的路径,第三方像spring等框架封装的api底层都是调用redis自身支持的命令实现的,得其根本才能变化万通,api不会都没关系,使用的时候查一下就好了

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
打赏
0
0
0
0
56
分享
相关文章
解决Redis缓存数据类型丢失问题
解决Redis缓存数据类型丢失问题
205 85
|
3月前
|
redis常见数据类型
Redis 是一种基于内存的键值存储数据库,支持字符串、哈希表、列表、集合及有序集合等多种数据类型,每种类型均有特定用途与适用场景,提供丰富的命令操作,适用于高速数据访问与处理。
64 5
使用Java操作Redis数据类型的详解指南
通过使用Jedis库,可以在Java中方便地操作Redis的各种数据类型。本文详细介绍了字符串、哈希、列表、集合和有序集合的基本操作及其对应的Java实现。这些示例展示了如何使用Java与Redis进行交互,为开发高效的Redis客户端应用程序提供了基础。希望本文的指南能帮助您更好地理解和使用Redis,提升应用程序的性能和可靠性。
73 1
Redis 数据类型
10月更文挑战第15天
67 1
深入探析Redis常见数据类型及应用场景
深入探析Redis常见数据类型及应用场景
104 2
Redis6入门到实战------ 三、常用五大数据类型(字符串 String)
这篇文章深入探讨了Redis中的String数据类型,包括键操作的命令、String类型的命令使用,以及String在Redis中的内部数据结构实现。
Redis6入门到实战------ 三、常用五大数据类型(字符串 String)
Redis5种数据类型
这篇文章介绍了Redis的五种数据类型:字符串、列表、集合、有序集合和哈希,并通过代码示例展示了如何在Spring框架中使用RedisTemplate操作这些数据类型。
Redis5种数据类型
深入理解Redis数据类型Hashes原理
本文深入分析了Redis中的hashes数据类型,这是一种用于存储行记录的数据结构,允许一个key下存储多条记录。
深入理解Redis数据类型Hashes原理
深入理解Redis数据类型Zset原理
本文深入探讨了Redis中的Zset(有序集合)数据类型,它是一种可以存储排序功能的集合,其中每个元素都具有一个浮点型的score属性,用于根据score进行排序。
深入理解Redis数据类型Zset原理
Redis6入门到实战------ 三、常用五大数据类型(列表(List)、集合(Set)、哈希(Hash)、Zset(sorted set))
这是关于Redis 6入门到实战的文章,具体内容涉及Redis的五大数据类型:列表(List)、集合(Set)、哈希(Hash)、有序集合(Zset(sorted set))。文章详细介绍了这些数据类型的特点、常用命令以及它们背后的数据结构。如果您有任何关于Redis的具体问题或需要进一步的帮助,请随时告诉我。
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等