redis系列全家桶(八):深入浅出数据结构-有序集合

2021/10/19 19:15:37

本文主要是介绍redis系列全家桶(八):深入浅出数据结构-有序集合,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

有序集合相对于哈希、列表、集合来说会有一点点陌生,但既然叫有序集合,那么它和集合必然有着联系,它保留了集合不能有重复成员的特性,但不同的是,有序集合中的元素可以排序。但是它和列表使用索引下标作为排序依据不同的是,它给每个元素设置一个分数(score)作为排序的依据。如图所示,该有序集合包含kris、mike、frank、tim、martin、tom, 它们的分数分别是1、91、200、220、250、251,有序集合提供了获取指定分数和元素范围查询、计算成员排名等功能,合理的利用有序集合,能帮助我们在实际开发中解决很多问题。

  • 有序集合中的元素不能重复,但是score可以重复,就和一个班里的同学学号不能重复,但是考试成绩可以相同。如图是列表、集合、有序集合三者的异同点

常用命令

集合内

  • 添加成员:zadd key score member [score member ...]
    有关zadd命令有两点需要注意:
    第一、Redis3.2为zadd命令添加了nx、xx、ch、incr四个选项:
    ·nx:member必须不存在,才可以设置成功,用于添加。
    ·xx:member必须存在,才可以设置成功,用于更新。
    ·ch:返回此次操作后,有序集合元素和分数发生变化的个数
    ·incr:对score做增加,相当于后面介绍的zincrby。
    第二、有序集合相比集合提供了排序字段,但是也产生了代价,zadd的时间 复杂度为O(log(n)),sadd的时间复杂度为O(1)。

  • 计算成员个数:zcard key

  • 计算某个成员的分数:zscore key member

  • 计算成员的排名:
    zrank key member
    zrevrank key member
    zrank是从分数从低到高返回排名,zrevrank反之。

  • 删除成员:zrem key member [member ...]

  • 增加成员的分数:zincrby key increment member

  • 返回指定排名范围的成员:
    zrange key start end [withscores]
    zrevrange key start end [withscores]
    有序集合是按照分值排名的,zrange是从低到高返回,zrevrange反之。 如果加上withscores选项,同时会返回成员的分数

  • 返回指定分数范围的成员:
    zrangebyscore key min max [withscores] [limit offset count]
    zrevrangebyscore key max min [withscores] [limit offset count]
    其中zrangebyscore按照分数从低到高返回,zrevrangebyscore反之。withscores选项会同时返回每个成员的分数,[limit offset count]选项可以限制输出的起始位置和个数.
    同时min和max还支持开区间(小括号)和闭区间(中括号),-inf和 +inf分别代表无限小和无限大.

  • 返回指定分数范围成员个数:zcount key min max

  • 删除指定排名内的升序元素:zremrangebyrank key start end

  • 删除指定分数范围的成员:zremrangebyscore key min max

集合间操作

  • 交集:zinterstore destination numkeys key [key ...] [weights weight [weight ...]] [aggregate sum|min|max]
    这个命令参数较多,下面分别进行说明:
    ·destination:交集计算结果保存到这个键。
    ·numkeys:需要做交集计算键的个数。
    ·key[key...]:需要做交集计算的键。
    ·weights weight[weight...]:每个键的权重,在做交集计算时,每个键中的每个member会将自己分数乘以这个权重,每个键的权重默认是1。
    ·aggregate sum|min|max:计算成员交集后,分值可以按照sum(和)、 min(最小值)、max(最大值)做汇总,默认值是sum。

  • 并集:zunionstore destination numkeys key [key ...] [weights weight [weight ...]] [aggregate sum|min|max]
    该命令的所有参数和zinterstore是一致的,只不过是做并集计算。

使用场景

有序集合比较典型的使用场景就是排行榜系统。例如视频网站需要对用户上传的视频做排行榜,榜单的维度可能是多个方面的:按照时间、按照播放数量、按照获得的赞数。本节使用赞数这个维度,记录每天用户上传视频的排行榜。主要需要实现以下4个功能。

  • 添加用户赞数
    例如用户mike上传了一个视频,并获得了3个赞,可以使用有序集合的 zadd和zincrby功能:
    zadd user:ranking:2016_03_15 mike 3
    如果之后再获得一个赞,可以使用zincrby:
    zincrby user:ranking:2016_03_15 mike 1

  • 取消用户赞数
    由于各种原因(例如用户注销、用户作弊)需要将用户删除,此时需要将用户从榜单中删除掉,可以使用zrem。例如删除成员tom:
    zrem user:ranking:2016_03_15 tom

  • 展示获取赞数最多的十个用户
    此功能使用zrevrange命令实现:
    zrevrangebyrank user:ranking:2016_03_15 0 9

  • 展示用户信息以及用户分数
    此功能将用户名作为键后缀,将用户信息保存在哈希类型中,至于用户的分数和排名可以使用zscore和zrank两个功能:
    hgetall user:info:tom zscore user:ranking:2016_03_15 mike zrank user:ranking:2016_03_15 mike



这篇关于redis系列全家桶(八):深入浅出数据结构-有序集合的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程