当前位置: 首页 > news >正文

Redis数据结构-Zset有序集合

1.Zset有序集合

有序集合保留了集合不能有重复成员的特点,但与集合不同的是,有序集合中的每个元素都有一个唯一的浮点类型的分数与之关联,这使得有序元素中的元素是可以维护有序行的,但这个有序不是用下表作为排序依据而是用这个分数(进行排序时,就是按照分数大小来进行按照升/降序排序)

注:有序集合中的元素是不能重复的,但是分数运行重复。当分数相同时,会安好元素自身的字符串的字典序来排序

2.常用命令

2.1 ZADD

添加或者更新指定的元素以及关联的分数到zset中,分数应该符合double类型,+inf/-inf作为正负极线也是合法的

ZADD的相关选项:

XX:仅仅用于更新已经存在的元素,不会添加新的元素

NX:仅用于添加新元素,不会更新已经存在的元素

CH:默认情况下,ZADD返回本次添加元素的个数,但是指定这个选项后,就会包干本次更新的元素个数(添加的元素个数+更新的元素个数)

INCR:此时命令类似于ZINCRBY的效果,将元素的分数加上指定的分数,此时只能制定一个元素和分数

LT:小于

GT:大于

score:可以填写小数

语法:ZADD key [ NX | XX ] [ GT | LT ] [ CH ] [ INCR ] score member [score member ...]

时间复杂度:O(logN),由于Zset是有序结构的,要求新增的元素要放到合适的位置上

返回值:本次添加成功的元素个数

示例:

由此可见,Zset内部默认是按照升序方式排列的

2.2 ZCARD

获取一个zset的技术(cardinality),即zset中元素的个数

语法:ZCARD key

时间复杂度:O(1)

返回值:zset内的元素个数

示例:

2.3 ZCOUNT

返回分数在min和max之间的元素个数,默认情况下,min和max都是包含的,可以通过(排除(此处的min,max表示的分数)

语法:ZCOUNT key min max

时间复杂度:O(logN)

返回值:满足条件的元素列数个数

示例:

2.4 ZRANGE

返回指定区间里的元素,分数按照升序。带上WITHSCORES可以吧分数也返回

语法:ZRANGE key start stop

此处的[start,stop]为下标构成的区间,从0开始支持负数

时间复杂度:O(logN+M)

返回值:区间内的元素列表

示例:

2.5 ZREVRANGE

返回指定区间里的元素,分数按照降序。带上withscores可以把分数也返回

语法:ZREVRANGE key start stop [WITHSCORES]

时间复杂度:O(logN+M)

返回值:区间内的元素列表

2.6 ZRANGEBYSCORE

返回分数在min和max之间的元素,默认情况下,min和max都是包含的,可以通过(排除

语法:ZRANGEBYSCORE key min max [WITHSCORES]

时间复杂度:O(logN+M)

返回值:区间内的元素列表

示例:

2.7 ZPOPMAX

删除并返回分数最高的count个元素

语法:ZPOPMAX key [count]

时间复杂度:O(log(N)*M)

返回值:分数和元素列表

示例:

2.8 ZPOPMIN

删除并返回分数最低的count个元素

语法:ZPOPMIN key [count]

时间复杂度:O(log(N)*M)

返回值:分数和元素列表

示例:

2.9 ZRANK

返回指定元素的排名,次序

语法:ZRANK key member

时间复杂度:O(logN)

返回值:排名(当member不存在时,返回nil)

示例:

2.10 ZREVRANK

返回指定元素的排名,降序

语法:ZREVRANK key member

时间复杂度:O(logN)

返回值:排名(member不存在时,返回nil)

示例:

2.11 ZSCORE

返回指定元素的分数

语法:ZSCORE key member

时间复杂度:O(1)(此处相当于Redis针对查询操作做了优化处理,付出了额外的空间代价,优化到O(1))

返回值:分数

示例:

2.12 ZREM

删除指定元素

语法:ZREM key member [member ...]

时间复杂度:O(M*logN)

返回值:本次操作删除的元素个数

示例:

2.13 ZREMRANGEBYRANK

按照排序,升序删除指定范围的元素,左闭右闭

语法:ZREMRANGEBYRANK key start stop

时间复杂度:O(logN+M)

返回值:本次操作删除的元素个数

示例:

2.14 ZREMRANGEBYSCORE

按照分数删除指定返回的元素,左闭右闭

语法:ZREMRANGEBYSCORE key min max

时间复杂度:O(logN+M)

返回值:本次操作删除的元素个数

示例:

2.15 ZINCRBY

为指定的元素的关联分数添加指定的分数值

语法:ZINCRBY key increment member(increment支持负数和小数)

时间复杂度:O(logN)

返回值:增加后元素的分数

示例:

阻塞版本指令

2.16 BZPOPMAX

ZPOPMAX的阻塞版本,当有序集合中为空时阻塞,阻塞到队列中插入元素

语法:BZPOPMAX key [key ...] timeout

时间复杂度:O(logN)

返回值:元素列表

2.17 BZPOPMIN

ZPOPMIN的组设版本,与BZPOPMAX用法一致

语法:BZPOPMIN key [key ...] timeout

时间复杂度:O(logN)

返回值:元素列表

集合间操作指令

2.18 ZINTERSTORE

求出给定有序集合中元素的交集并保存到目标有序集合中,在合并过程中以元素为单位进行合并,元素对应的分数按照不同的聚合方式和权重得到新的分数

语法:ZINTERSCORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE <SUM | MIN | MAX>]

destination:表示保存到的目标有序结合

numkeys:整数,描述了后续有多少个key参与交集运算(为了避免选项和keys混淆)

AGGREGATE:总数,合计。默认情况下求和

WEIGHTS:权重,分数会乘以对应的权重

时间复杂度:O(N*K)+O(M*logM),N是输入的有序集合中,最小的有序集合的元素个数,K是输入了几个有序集合,M是最终结果的有序集合的元素个数

返回值:目标集合中的元素个数

示例:

 

2.19 ZUNIONSTORE

求出给定有序集合中元素的并集并保存进目标有序集合中,在合并过程中以元素为单位进行合并,元素对应的分数按照不同的聚合方式和权重重新得到新的分数

语法:ZUNIONSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE <SUM | MIN | MAX>]

时间复杂度:O(N)+O(M*logM)(N是输入有序集合中总的元素个数,M是最终结果的有序结合的元素个数)

返回值:目标集合中元素的个数

示例:

3.内部编码

3.1 ziplist

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

3.2 skiplist

skiplist(跳表):当ziplist条件不满足时,有序集合会使用skiplist作为内部实现,因为此时ziplist的操作效率会下降。(此处不详讲)

4.Zset的经典使用场景

4.1 排行榜系统

最常见的应用场景:微博热搜,游戏天梯排行榜,成绩排行

关键要点:用来排行的分数是实时变化的,虽然是实时变化的,也能够高效的更新排行

使用zset完成上述操作,就会非常简单。比如游戏天梯排行,只需要吧玩家信息和对应的分数给放到有序集合中即可,自动形成了一个排行榜,随时可以按照排行(下标)按照分数,进行范围查找随者分数发生变化,也可以比较方便的,zincrby修改分数,排行顺序也能自动调整(logN)

对于游戏排行榜,前后顺序非常容易确定,但是有些排行榜就要复杂一些,例如微博热搜(综合数值:浏览量,点赞量,转发量,评论量;具体有多少个维度,每个维度权重怎么分配以及怎么设定最优)根据每个维度,计算得到综合得分=热度,此时就可以借助zinterstore/zunionstor按照加权方式处理,此时就可以把上述维度的数值都放入一个有序集合中,member是微博id,score就是各自维度的数值,通过zinterstore或zunionstore把上述有序集合约定好的权重,进行集合间运算,得到的结果集合的分数就是热度

5.列表,集合,有序集合之间的异同点

数据结构是否允许重复元素是否有序有序依据应用场景
列表索引下标时间轴,消息队列
集合标签,社交
有序集合分数排行系统,社交等


http://www.mrgr.cn/news/93346.html

相关文章:

  • 【JAVA架构师成长之路】【持久层】第2集:SQL常用优化手段
  • 从零开始的 Kafka 学习(一)| 概念,Java API
  • 【JAVA架构师成长之路】【JDK源码】第5集:Map集合框架与泛型
  • 【leetcode hot 100 73】矩阵置零
  • PythonWeb开发框架—Flask工程创建和@app.route使用详解
  • Redis|集群 Cluster
  • 软考架构师笔记-存储管理
  • 【15】蚂蚁链产品与服务
  • AI绘画软件Stable Diffusion详解教程(6):文生图、提示词细说与绘图案例
  • java+jvm笔记
  • 【长安大学】苹果手机/平板自动连接认证CHD-WIFI脚本(快捷指令)
  • SQL注入的原理及详细运用
  • 从0到1入门Linux
  • java 重点知识 — JVM存储模块与类加载器
  • 从0开始的操作系统手搓教程21:进程子系统的一个核心功能——简单的进程切换
  • Webpack分包与合包深度解析
  • Python 网络爬虫教程与案例详解
  • qt实践教学(编写一个代码生成工具)持续更新至完成———
  • HCIA-IP路由动态-RIP
  • c++里左值和右值