【Redis】zset 类型介绍

目录

  • 一、简介
  • 二、相关命令
    • [2.1 zadd](#2.1 zadd)
    • [2.2 zcard 和 zcount](#2.2 zcard 和 zcount)
    • [2.3 zrange 和 zrevrange 和 zrangebyscore](#2.3 zrange 和 zrevrange 和 zrangebyscore)
    • [2.4 zpopmax 和 bzpopmax](#2.4 zpopmax 和 bzpopmax)
    • [2.5 zpopmin 和 bzpopmin](#2.5 zpopmin 和 bzpopmin)
    • [2.6 zrank 和 zrevrank 和 zscore](#2.6 zrank 和 zrevrank 和 zscore)
    • [2.7 zrem 和 zremrangebyrank 和 zremrangebyscore](#2.7 zrem 和 zremrangebyrank 和 zremrangebyscore)
    • [2.8 zincrby](#2.8 zincrby)
    • [2.9 zinterstore 和 zunionstore](#2.9 zinterstore 和 zunionstore)
    • [2.10 命令小结](#2.10 命令小结)
  • 三、内部编码
  • 四、使用场景

一、简介

有序集合保留了集合不能有重复成员的特点,但与集合不同的是,有序集合中的每个元素都有⼀个唯⼀的浮点类型的分数(score)与之关联,这使得有序集合中的元素是可以维护有序性的,但这个有序不是⽤下标作为排序依据⽽是⽤这个

分数。

有序集合提供了获取指定分数和元素范围查找、计算成员排名等功能,有序集合中的元素是不能重复的,但分数允许重复。类⽐于⼀次考试之后,每个⼈⼀定有⼀个唯⼀的分数,但分数允许相同。

列表、集合、有序集合三者的异同点:

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

二、相关命令

2.1 zadd

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

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

  • XX:仅仅⽤于更新已经存在的元素,不会添加新元素。
  • NX:仅⽤于添加新元素,不会更新已经存在的元素。
  • LT:如果更新的分数比已经存在的分数才更新已经存在的元素,不会影响添加新元素。
  • GT:如果更新的分数比已经存在的分数才更新已经存在的元素,不会影响添加新元素。
  • CH:默认情况下,zadd 返回的是本次添加的元素个数,但指定这个选项之后,就会还包含本次更新的元素的个数。
  • INCR:此时命令类似 zincrby 的效果,将元素的分数加上指定的分数。此时只能指定⼀个元素和分数。

命令有效版本:1.2.0 之后

时间复杂度:O(logN),N是有序集合中已经存在的元素个数

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

2.2 zcard 和 zcount

zcard获取⼀个 zset 的基数(cardinality),即 zset 中的元素个数。

语法:
zcard key

命令有效版本:1.2.0 之后

时间复杂度:O(1)

返回值:zset 内的元素个数。

zcount返回分数在 min 和 max 之间的元素个数,默认情况下,min 和 max 都是包含的,可以通过 ( 排除。min 和 max支持浮点数,inf : 代表无穷大,-inf:代表负无穷大。

语法:
zcount key min max

命令有效版本:2.0.0 之后

时间复杂度:O(logN),N是有序集合中已经存在的元素个数

返回值:满⾜条件的元素列表个数。

2.3 zrange 和 zrevrange 和 zrangebyscore

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

语法:
zrange key start stop [WITHSCORES]

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

命令有效版本:1.2.0之后

时间复杂度:O(log(N)+M),N是有序集合中已经存在的元素个数,M是查找到的元素个数

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

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

备注:这个命令可能在 6.2.0 之后废弃,并且功能合并到zrange中。

语法:
zrevrange key start stop [WITHSCORES]

命令有效版本:1.2.0之后

时间复杂度:O(log(N)+M),N是有序集合中已经存在的元素个数,M是查找到的元素个数

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

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

备注:这个命令可能在 6.2.0 之后废弃,并且功能合并到zrange 中。

语法:
zrangebyscore key min max [WITHSCORES]

命令有效版本:1.0.5 之后

时间复杂度:O(log(N)+M),N是有序集合中已经存在的元素个数,M是查找到的元素个数

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

2.4 zpopmax 和 bzpopmax

zpopmax删除并返回分数最⾼的 count 个元素。

语法:
zpopmax key [count]

命令有效版本:5.0.0 之后

时间复杂度:O(log(N) * M),N是有序集合中已经存在的元素个数,M是删除的元素个数

返回值:分数和元素列表。

bzpopmax 命令zpopmax的阻塞版本,一次只能删一个元素,可以设置最大阻塞时间timeout单位秒。

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

命令有效版本:5.0.0 之后

时间复杂度:O(log(N)),N是有序集合中已经存在的元素个数

返回值:元素列表。

2.5 zpopmin 和 bzpopmin

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

语法:
zpopmin key [count]

命令有效版本:5.0.0之后

时间复杂度:O(log(N) * M),N是有序集合中已经存在的元素个数,M是删除的元素个数

返回值:分数和元素列表。

bzpopmin 命令 zpopmin的阻塞版本,一次只能删一个元素,可以设置最大阻塞时间timeout单位秒。
bzpopmin key [key ...] timeout

命令有效版本:5.0.0 之后

时间复杂度:O(log(N)),N是有序集合中已经存在的元素个数

返回值:元素列表

2.6 zrank 和 zrevrank 和 zscore

zrank返回指定元素的排名,升序。

语法:
zrank key membe

命令有效版本:2.0.0 之后

时间复杂度:O(log(N)),N是有序集合中已经存在的元素个数

返回值:排名。

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

语法:
zrevrank key member

命令有效版本:2.0.0之后

时间复杂度:O(log(N)),N是有序集合中已经存在的元素个数

返回值:排名。

zscore返回指定元素的分数。

语法:
zscore key member

命令有效版本:1.2.0之后

时间复杂度:O(1)

返回值:分数。

2.7 zrem 和 zremrangebyrank 和 zremrangebyscore

zrem删除指定的元素。

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

命令有效版本:1.2.0之后

时间复杂度:O(M*log(N)),N是有序集合中已经存在的元素个数

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

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

语法:
zremrangebyrank key start stop

命令有效版本:2.0.0之后

时间复杂度:O(log(N)+M),N是有序集合中已经存在的元素个数,M是删除的元素个数

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

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

语法:
zremrangebyscore key start stop

命令有效版本:2.0.0之后

时间复杂度:O(log(N)+M),N是有序集合中已经存在的元素个数,M是删除的元素个数

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

2.8 zincrby

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

语法:
zincrby key increment member

命令有效版本:1.2.0之后

时间复杂度:O(log(N)),N是有序集合中已经存在的元素个数

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

2.9 zinterstore 和 zunionstore

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

求交集

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

  • destination : ⽬标有序集合
  • numkeys : 给定有序集合的个数,为了区分key和后面的可选项
  • weight : 权重,会乘上前面对应的key里元素的score
  • aggregate : 求和(默认),取最小值,取最大值

命令有效版本:2.0.0之后

时间复杂度:O(NK)+O(Mlog(M)) N 是输⼊的有序集合中, 最⼩的有序集合的元素个数; K 是输⼊了⼏个有序集合; M 是最终结果的有序集合的元素个数.

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

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

求并集

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

命令有效版本:2.0.0之后

时间复杂度:O(N)+O(M*log(M)) N 是输⼊的有序集合总的元素个数; M 是最终结果的有序集合的元素个数.

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

2.10 命令小结

命令 执行效果 时间复杂度
zadd key score member [score member ...] 添加或者更新指定的元素以及关联的分数到 zset 中 O(k * log(n)),k 是添加成员的个数,n 是当前有序集合的元素个数
zcard key 获取⼀个 zset 的基数(cardinality),即 zset 中的元素个数。 O(1)
zscore key member 返回指定元素的分数 O(1)
zrank key member 返回指定元素的排名 O(log(n)),n 是当前有序集合的元素个数
zrevrank key member 返回指定元素的排名,降序 O(log(n)),n 是当前有序集合的元素个数
zcount 返回分数在 min 和 max 之间的元素个数 O(log(n)),n 是当前有序集合的元素个数
zincrby key increment member 为指定的元素的关联分数添加指定的分数值 O(log(n)),n 是当前有序集合的元素个数
zrange key start end [withscores] 返回指定区间⾥的元素,分数按照升序 O(log(N)),N是有序集合中已经存在的元素个数
zrevrange key start end [withscores] 返回指定区间⾥的元素,分数按照降序 O(k + log(n)),k 是获取成员的个数,n 是当前有序集合的元素个数
zrangebyscore key min max[withscores] 返回分数在 min 和 max 之间的元素,升序 O(k + log(n)),k 是获取成员的个数,n 是当前有序集合的元素个数 zcount O(log(n)),n 是当前有序集合的元素个数
zrevrangebyscore key max min [withscores] 返回分数在 min 和 max 之间的元素,降序 O(k + log(n)),k 是获取成员的个数,n 是当前有序集合的元素个数
zrem key member [member ...] 删除指定的元素 O(k * log(n)),k 是删除成员的个数,n 是当前有序集合的元素个数
zremrangebyrank key start end 按照下标排序,升序删除指定范围的元素,左闭右闭 O(k + log(n)),k 是获取成员的个数,n 是当前有序集合的元素个数
zremrangebyscore key min max 按照分数排序,降序删除指定范围的元素,左闭右闭 O(k + log(n)),k 是获取成员的个数,n 是当前有序集合的元素个数
zinterstore destination numkeys key [key ...] 求出给定有序集合中元素的交集并保存进⽬标有序集合中 O(n * k) + O(m * log(m)),n 是输⼊的集合最⼩的元素个数,k 是集合个数, m 是⽬标集合元素个数
zunionstore destination numkeys key [ key ...] 求出给定有序集合中元素的并集并保存进⽬标有序集合中 O(n) + O(m * log(m)),n 是输⼊集合总元素个数,m 是⽬标集合元素个数

三、内部编码

有序集合类型的内部编码有两种:

  • ziplist(压缩列表):当有序集合的元素个数⼩于 zset-max-ziplist-entries 配置(默认 128 个),同时每个元素的值都⼩于 zset-max-ziplist-value 配置(默认 64 字节)时,Redis 会⽤ ziplist 来作为有序集合的内部实现,ziplist 可以有效减少内存的使⽤。
  • skiplist(跳表):当 ziplist 条件不满⾜时,有序集合会使⽤ skiplist 作为内部实现,因为此时 ziplist 的操作效率会下降。

四、使用场景

有序集合⽐较典型的使⽤场景就是排⾏榜系统。例如常⻅的⽹站上的热榜信息,榜单的维度可能是多⽅⾯的:按照时间、按照阅读量、按照点赞量。

相关推荐
一只鹿鹿鹿15 小时前
信息安全等级保护安全建设防护解决方案(总体资料)
运维·开发语言·数据库·面试·职场和发展
堕27415 小时前
MySQL数据库《基础篇--数据库索引(2)》
数据库·mysql
wei_shuo15 小时前
数据库优化器进化论:金仓如何用智能下推把查询时间从秒级打到毫秒级
数据库·kingbase·金仓
雷工笔记16 小时前
Navicat Premium 17 软件安装记录
数据库
wenlonglanying16 小时前
Ubuntu 系统下安装 Nginx
数据库·nginx·ubuntu
数据库小组16 小时前
10 分钟搞定!Docker 一键部署 NineData 社区版
数据库·docker·容器·database·数据库管理工具·ninedata·迁移工具
爬山算法16 小时前
MongoDB(38)如何使用聚合进行投影?
数据库·mongodb
l1t17 小时前
Deep Seek总结的APSW 和 SQLite 的关系
数据库·sqlite
Pocker_Spades_A18 小时前
基于代价模型的连接条件下推:复杂SQL查询的性能优化实践
数据库·sql·性能优化
huan19911018 小时前
Python使用PyMySQL操作MySQL完整指南
数据库·python·mysql