Redis:zset类型

Redis:zset类型


在Redis中,有两种集合类型,set和zset,其中set是无序集合,zset是有序集合,本博客讲解Redis中的有序集合。

在有序集合中,要按照一定的指标给集合元素进行排序,Redis个每个集合的元素引入了一个score属性,这是一个双精度浮点型,每次排序的时候,依据socre的大小进行排序。如果分数相同,那么以字典序排序。


zset命令

ZADD
  • 往zset中添加元素和分数
bash 复制代码
zadd key [NX|XX] [GT|LT] [CH] [INCR] score member [score member ...]

选项:

  • [XX|NX]
    • XX:只更新,如果element或者key不存在,操作失败
    • NX:只添加,如果element或者key不存在,添加数据,如果存在,操作失败
  • [GT|LT]
    • LT:如果新的socre小于(Less Than)当前的score,那么更新元素
    • GT:如果新的socre大于(Greater Than)当前的score,那么更新元素
  • [CH]
    • 不加CH:zadd返回新增的元素个数
    • 加CH:zadd返回修改的元素个数
  • [INCR]:对现有的socre进行运算

示例:

此处插入了四个数据,随后通过zrange查询结果(后面讲),可以看到输出结果是以score排序的。

还可以通过zadd更新数值,把mike的值提升到80.5后,再次查询顺序就变了。

此处演示ch的功能,第一次先通过add添加了两个成员lora和meg。第二次修改lora和meg的score,结果返回值为0,这不是说明修改失败了,而是其只返回新增元素个数,而不是修改的元素个数。第三次修改lora和meg的score,并且加入ch选项,返回2说明有两个元素修改成功了。

第一次通过zadd设置peter的score为100,第二次添加incr选项,表示在当前的score基础上再加20,返回120为增加后的结果。


ZCARD
  • 获取zset的元素个数
bash 复制代码
zcard key

返回zset的元素个数。


ZCOUNT
  • 返回指定区间内的元素个数
bash 复制代码
zcount key min max

返回score在[min, max]闭区间的元素个数,可以通过(min (max来设置开区间。

在zset3中,有五个分数12 20 42 68 88。第一次查询20 68,在闭区间内有三个数值,返回3。第二次查询(20 68,表示左开右闭区间,第三次查询(20 (68表示开区间,第四次查询20 (68表示左闭右开区间。

此处实现计数,不是查询到min和max后,遍历区间内的元素然后计数。在zset内部,会给每个元素存储其当前的排名,查询到min和max后,直接将两者的排名做差就可以得到count。

另外的,区间还支持浮点数的负无穷大-inf和正无穷大inf。

这种格式就是统计zset中所有元素个数。


ZRANGE
  • 返回指定区间内的元素,按升序排序
bash 复制代码
zrange key start stop [withscores]

按升序返回[start, stop]区间内的元素,如果带上withscores则将score一起返回。

此处的start和stop不是分数,而是元素的排名,从0开始,支持负数。

示例:

加上withcores参数后,每个元素的下一行是它的socre。


ZREVRANGE
  • 返回指定区间内的元素,按降序排序
bash 复制代码
zrevrange key start stop [withscores]

按降序返回[start, stop]区间内的元素,如果带上withscores则将score一起返回。

此处的rev表示reverse翻转,只是将原先的输出顺序颠倒了一下,用法和zrange没有区别。


ZRANGEBYSCORE
  • 返回指定区间内的元素,按升序排序
bash 复制代码
zrangebyscore key min max [withscores]

按升序返回score在[min, max]区间内的元素,如果带上withscores则将score一起返回。

之前的zrange是通过元素排名返回,zrangebyscore则是通过score区间返回。

示例:

注意:官方文档表明,该命令即将被废弃,并且功能会合并到zrange中。


ZREVRANGEBYSCORE
  • 返回指定区间内的元素,按降序排序
bash 复制代码
zrevrangebyscore key min max [withscores]

按降序返回score在[min, max]区间内的元素,如果带上withscores则将score一起返回。

只是将输出顺序颠倒了一下,用法和zrangebyscore一样。

注意:官方文档表明,该命令即将被废弃,并且功能会合并到zrevrange中。


ZPOPMAX
  • 获取并删除score最高的多个元素
bash 复制代码
zpopmax key [count]

返回当前的count个最大元素,并且将这些元素从zset中删除。

示例:

如果多个元素的score相同,那么会按照member的字典序进行比较,字典序高的先删除。


BZPOPMAX
  • 读取并删除zset最大元素,如果没有元素则陷入阻塞
bash 复制代码
bzpopmax key [key ...] timeout

bzpopmax 可以同时指定多个key,也就是多个zset,只要任何一个zset有数据,就返回结果。还可以设置超时时间timeout,以秒为单位,如果超过时间了,返回nil。

如果超时时间设置为0,则一直阻塞,不会超时。

示例:

此处启动了两个终端,左侧终端通过bzpopmax读取zset1的最大值。但是由于zset1内没有元素陷入阻塞。不久后在右侧终端插入66 lisa,此时左侧终端检测到后,立刻返回结果。zset1表示自己读取到的数据属于哪一个zset,lisa是member,66是score。


ZPOPMIN
  • 获取并删除score最小的多个元素
bash 复制代码
zpopmin key [count]

返回当前的count个最小元素,并且将这些元素从zset中删除。


BZPOPMIN
  • 读取并删除zset最小元素,如果没有元素则陷入阻塞
bash 复制代码
bzpopmin key [key ...] timeout

bzpopmin 可以同时指定多个key,也就是多个zset,只要任何一个zset有数据,就返回结果。还可以设置超时时间timeout,以秒为单位,如果超过时间了,返回nil。

如果超时时间设置为0,则一直阻塞,不会超时。


ZRANK
  • 获取指定元素的排名
bash 复制代码
zrank key member

返回指定元素member的排名,这个排名就是socre从小到大的顺序,从0开始排,也可以当作下标。

示例:

此处排名最前的是lisa,下标为0。


ZREVRANK
  • 获取指定元素的排名
bash 复制代码
zrevrank key member

返回指定元素member的排名,这个排名就是socre从大到小的顺序,从0开始排。

示例:


ZSCORE
  • 获取指定元素的分数
bash 复制代码
zscore key member

返回指定元素member的分数。


ZREM
  • 删除指定元素
bash 复制代码
zrem key member [member ...]

返回成功删除的元素个数。


ZREMRANGEBYRANK
  • 根据排名,删除指定区间内的元素
bash 复制代码
zremrangebyrank key start stop

删除排名在[start, stop]闭区间范围内的元素,返回成功删除的元素个数。

示例:


ZREMRANGEBYSCORE
  • 根据score,删除指定区间内的元素
bash 复制代码
zremrangebyscore key min max

删除分数在[min, max]闭区间范围内的元素,返回成功删除的元素个数。

示例:


ZINCRBY
  • 为指定元素的score增加指定的值
bash 复制代码
zincrby key increment member

给member的score增加increment的值,返回增加后的结果,increment可以为负值和浮点数。


集合间操作

在set中,提供了sinter、sunion、sdiff处理交集、并集、差集。那么zset是否也有对应的zinter、zunion、zdiff?是有的,但是在Redis 6.2后才开始支持,在那之前,zset只提供了两个集合间操作。

ZINRERSTORE
  • 求多个集合的交集,结果保存到指定zset中
bash 复制代码
zinterstore destination numkeys key [key ...] [weights weight [weight ...]] [aggregate <sum | min | max>]
  • destination :输出结果到给zset中
  • numkeys:指定后续输入的key的个数
  • weights:权重,每一个zset都配一个weight,计算时score乘对应的weight
  • aggreate:score的合并方式
    • sum:求和(默认值)
    • min:取最小
    • max:取最大

示例:

此处创建了两个zset,通过zinterstore合并,其中zset1的权重是1,zset2的权重是100,以sum方式合并。最后求出交集bob 1 * 100 + 20,lisa 3 * 100 + 12。


ZUNIONSTORE
  • 求多个集合的并集,结果保存到指定zset中
bash 复制代码
zunionstore destination numkeys key [key ...] [weights weight [weight ...]] [aggregate <sum | min | max>]

这个参数和zinterstore完全一致,只是从交集变成并集。


  • 总结:
命令 功能
zadd 往zset中添加元素和分数
zcard 获取zset的元素个数
zcount 计算在指定分数范围内的元素个数
zrange 获取指定区间内的元素
zrevrange 获取指定区间内的元素(按分数从高到低)
zrangebyscore 获取指定分数范围内的元素
zrevrangebyscore 获取指定分数范围内的元素(按分数从高到低)
zpopmax 弹出zset中分数最高的元素
bzpopmax 阻塞弹出zset中分数最高的元素
zpopmin 弹出zset中分数最低的元素
bzpopmin 阻塞弹出zset中分数最低的元素
zrank 获取元素在zset中的排名(按分数从小到大)
zrevrank 获取元素在zset中的排名(按分数从大到小)
zscore 获取元素在zset中的分数
zrem 移除zset中的一个或多个元素
zremrangebyrank 移除zset中给定排名区间的元素
zremrangebyscore 移除zset中给定分数区间的元素
zincrby 增加zset中元素的分数
zinterstore 计算两个或多个zset的交集,并将结果存储在新的zset中
zunionstore 计算两个或多个zset的并集,并将结果存储在新的zset中

内部编码

ziplist

当有序集合的元素个数小于zset-max-ziplist-entries配置(默认128个),同时每个元素的值都⼩于zset-max-ziplist-value配置(默认64字节)时,Redis会用ziplist来作为有序集合的内部实现,ziplist可以有效减少内存的使⽤。


skiplist

当ziplist条件不满⾜时,有序集合会使用skiplist作为内部实现,因为此时ziplist的操作效率会下降。

跳表是一种搜索结构,搜索时间复杂度为O(lgN),与平衡二叉搜索树是一个级别。


相关推荐
ss27331 分钟前
AI时代首先数据库-PostgreSQL实战笔记 | 28 PostgreSQL MVCC机制介绍
数据库·笔记·postgresql
奇牙coding43 分钟前
doubao-seed-2.1-pro 报 HTTP 401 怎么办?Key 正确也要检查请求头和端点
网络·数据库·http·ai
Lucis__9 小时前
Redis持久化机制解析
redis·缓存·操作系统·文件·非关系型数据库·1024程序员节
不脱发的程序猿9 小时前
纳指ETF量化策略
数据库·人工智能·1024程序员节
程序员塔塔喵10 小时前
【MySQL篇|第一篇】索引失效的情况
数据库·mysql·索引失效
北京青蓝智慧马老师10 小时前
比外部黑客更难防的,是那个有权限的自己人(3 个脱敏复盘)
大数据·数据库·人工智能
笃行35010 小时前
拆一台数据集成产品:KFS 的骨架、肌肉和神经
数据库
4SAPI11 小时前
搭建 AI 数据分析工具大模型 API 选型指南
数据库·人工智能·架构·php·1024程序员节
用户0942485680312 小时前
第7章:Redis有序集合 ZSet 实战:排行榜与延时任务
redis·架构·源码
码士集团小青12 小时前
面霸篇:高频 Java 基础问题(核心卷一)
linux·服务器·数据库·redis·缓存·1024程序员节