当前位置:首页 > 问答 > 正文

Redis里怎么遍历有序集合,方法和技巧分享,适合新手了解

在Redis里,有序集合(Sorted Set)是一个非常有用的数据结构,你可以把它想象成一个排行榜,每个成员都有一个分数,根据这个分数从小到大排序,你可以用它来存储游戏玩家的分数,分数高的排在前面,怎么查看或者“遍历”这个排行榜里的所有成员呢?这里就分享几个最常用、最适合新手的方法和技巧。

最基本的方法:ZRANGE 和 ZREVRANGE

这是你首先要学会的两个命令,它们就像是一对双胞胎,一个从低分到高分(正序)查看,一个从高分到低分(倒序)查看。

Redis里怎么遍历有序集合,方法和技巧分享,适合新手了解

  • ZRANGE key start stop [WITHSCORES]:这个命令用来获取索引在start和stop之间的成员,这里的关键是理解索引从0开始,如果你想看整个有序集合,就把start设为0,stop设为-1。
    • 举例:假设有个叫leaderboard的游戏排行榜。
      • 输入 ZRANGE leaderboard 0 -1,你会得到从第一名(最低分)到最后一名(最高分)的所有玩家ID。
      • 如果你想知道具体的分数,就在命令后面加上 WITHSCORES,像这样:ZRANGE leaderboard 0 -1 WITHSCORES,这时,返回的结果就是“成员1,分数1,成员2,分数2……”这样交替显示,一目了然。
  • ZREVRANGE key start stop [WITHSCORES]:这个命令和ZRANGE一模一样,只是顺序反过来,从分数高的开始显示,这对于排行榜场景特别有用,因为我们通常最关心前几名。
    • 举例:想看前三名是谁,就输入 ZREVRANGE leaderboard 0 2 WITHSCORES,这样返回的就是第一名、第二名、第三名的玩家和他们的分数。

(参考来源:Redis官方文档对ZRANGE命令的定义)

当集合很大时怎么办?使用游标扫描:ZSCAN

刚才的ZRANGE命令虽然简单,但如果你的有序集合非常大,比如有几百万元素,一次性用ZRANGE全部取出来可能会把Redis服务器或者你的网络卡住,导致一段时间内无法响应其他请求,这就像你不可能一口吃掉一个巨大的蛋糕,需要切开来一小块一小块地吃。

Redis里怎么遍历有序集合,方法和技巧分享,适合新手了解

这个时候,就要用到 ZSCAN 命令了,ZSCAN是一种增量式的迭代命令,它每次只返回一小部分数据,并给你一个“游标”(cursor),你拿着这个游标进行下一次查询,就能拿到下一部分数据,直到遍历完所有数据。

  • ZSCAN key cursor [MATCH pattern] [COUNT count]
    • cursor:游标,第一次查询时设为0,之后使用上一次查询返回的新游标。
    • MATCH pattern:可选参数,允许你只匹配特定模式的成员,user:*
    • COUNT count:可选参数,提示Redis每次大概返回多少元素,但请注意,这只是一个提示,返回的数量可能或多或少。
  • 工作流程
    1. 第一次调用:ZSCAN myzset 0,返回一个包含两个元素的数组,第一个是下一次要用的新游标(比如是18),第二个是本次扫描到的成员和分数列表。
    2. 第二次调用:ZSCAN myzset 18,再次返回一个新游标和下一批数据。
    3. 不断重复,直到返回的游标值变成0,这表示遍历已经完成。

(参考来源:Redis官方文档对SCAN系列命令的说明,ZSCAN属于其中一种)

按分数范围遍历:ZRANGEBYSCORE 和 ZREVRANGEBYSCORE

Redis里怎么遍历有序集合,方法和技巧分享,适合新手了解

你并不需要所有数据,只关心某个分数段的成员,你想找出所有分数在80分到90分之间的学生,这时候就用不上索引了,而是直接用分数来筛选。

  • ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]:这个命令获取分数在min和max之间的所有成员。
    • 小技巧
      • 你可以使用 (80 来表示“大于80”,而不是默认的“大于等于80”。ZRANGEBYSCORE scores (80 100 表示分数大于80且小于等于100的成员。
      • 可以用 -inf+inf 分别表示负无穷和正无穷,代表没有下限和上限。
      • LIMIT 参数和SQL里的很像,用于在结果中再进行分页。
  • 举例ZRANGEBYSCORE scores 80 100 WITHSCORES LIMIT 0 5 表示:获取分数在80到100之间(含80和100)的成员,并带上分数,只返回前5个结果。
  • ZREVRANGEBYSCORE:顾名思义,就是按分数从高到低的顺序返回指定分数范围内的成员,它的参数顺序和ZRANGEBYSCORE有点不一样,是 ZREVRANGEBYSCORE key max min,max在前,min在后,因为它是从大到小排的。

(参考来源:Redis官方文档对ZRANGEBYSCORE命令的定义)

给新手的实用技巧总结

  1. 日常查询用ZRANGE/ZREVRANGE:如果你的集合不大,或者你确定要操作的数据量很小,直接用这两个命令最简单快捷,查前几名用ZREVRANGE,查全部用ZRANGE。
  2. 海量数据遍历用ZSCAN:这是唯一安全的方式,记得在程序里写一个循环,直到游标为0才停止。
  3. 按分数筛选用ZRANGEBYSCORE:当你需要“分数段”查询时,这是最佳选择,非常灵活。
  4. 善用WITHSCORES:除非你确定不需要分数,否则加上这个选项,免得以后还要为获取分数再发一次命令。
  5. 注意命令的代价:ZRANGE这样的命令,如果集合很大,可能会比较耗时,在正式环境中使用前,最好对数据量有一个估计。

希望这些直接的方法和技巧能帮助你更好地在Redis中使用有序集合,多动手试一试,理解得会更深刻。