<返回目录     Powered by claud/xia兄

第7课: 有序集合

Sorted Set与排行榜实现

一、Sorted Set简介

Redis的Sorted Set(有序集合)是Set和Hash的结合体。每个成员都关联一个分数(score),成员按分数从小到大排序。Sorted Set非常适合实现排行榜、延时队列、优先级队列等场景。

Sorted Set特点

二、基本操作命令

1. ZADD - 添加成员

# 添加单个成员
ZADD leaderboard 100 "player1"
# 返回: (integer) 1

# 添加多个成员
ZADD leaderboard 200 "player2" 150 "player3" 300 "player4"
# 返回: (integer) 3

# 更新成员分数
ZADD leaderboard 250 "player2"
# 返回: (integer) 0

# 实际应用:游戏排行榜
ZADD game:rank 9500 "user1001" 8800 "user1002" 9200 "user1003"

2. ZSCORE - 获取成员分数

# 获取成员分数
ZSCORE leaderboard "player1"
# 返回: "100"

# 获取不存在的成员
ZSCORE leaderboard "player999"
# 返回: (nil)

3. ZRANK - 获取成员排名

# 获取成员排名(从0开始,分数从小到大)
ZRANK leaderboard "player1"
# 返回: (integer) 0

ZRANK leaderboard "player4"
# 返回: (integer) 3

# 实际应用:查询用户排名
ZRANK game:rank "user1001"

4. ZREVRANK - 获取逆序排名

# 获取逆序排名(分数从大到小)
ZREVRANK leaderboard "player4"
# 返回: (integer) 0

ZREVRANK leaderboard "player1"
# 返回: (integer) 3

5. ZRANGE - 按排名范围获取成员

# 获取排名0-2的成员(分数从小到大)
ZRANGE leaderboard 0 2
# 返回:
# 1) "player1"
# 2) "player3"
# 3) "player2"

# 获取排名并显示分数
ZRANGE leaderboard 0 2 WITHSCORES
# 返回:
# 1) "player1"
# 2) "100"
# 3) "player3"
# 4) "150"
# 5) "player2"
# 6) "250"

# 获取所有成员
ZRANGE leaderboard 0 -1

6. ZREVRANGE - 按排名范围获取成员(逆序)

# 获取前3名(分数从大到小)
ZREVRANGE leaderboard 0 2 WITHSCORES
# 返回:
# 1) "player4"
# 2) "300"
# 3) "player2"
# 4) "250"
# 5) "player3"
# 6) "150"

# 实际应用:获取排行榜前10名
ZREVRANGE game:rank 0 9 WITHSCORES

7. ZRANGEBYSCORE - 按分数范围获取成员

# 获取分数在100-200之间的成员
ZRANGEBYSCORE leaderboard 100 200
# 返回:
# 1) "player1"
# 2) "player3"

# 获取分数大于150的成员
ZRANGEBYSCORE leaderboard 150 +inf

# 获取分数小于200的成员
ZRANGEBYSCORE leaderboard -inf 200

# 限制返回数量
ZRANGEBYSCORE leaderboard 0 1000 LIMIT 0 10

8. ZREM - 删除成员

# 删除单个成员
ZREM leaderboard "player1"
# 返回: (integer) 1

# 删除多个成员
ZREM leaderboard "player2" "player3"
# 返回: (integer) 2

9. ZCARD - 获取成员数量

# 获取有序集合大小
ZCARD leaderboard
# 返回: (integer) 1

10. ZCOUNT - 统计分数范围内的成员数

# 统计分数在100-200之间的成员数
ZCOUNT leaderboard 100 200
# 返回: (integer) 2

# 统计分数大于150的成员数
ZCOUNT leaderboard 150 +inf

三、高级操作

1. ZINCRBY - 增加成员分数

# 增加成员分数
ZINCRBY leaderboard 50 "player4"
# 返回: "350"

# 减少成员分数(使用负数)
ZINCRBY leaderboard -10 "player4"
# 返回: "340"

# 实际应用:用户获得积分
ZINCRBY game:rank 100 "user1001"

2. ZREMRANGEBYRANK - 按排名范围删除

# 删除排名0-1的成员(保留前2名之后的)
ZREMRANGEBYRANK leaderboard 0 1
# 返回: (integer) 2

# 实际应用:只保留前100名
ZREMRANGEBYRANK game:rank 100 -1

3. ZREMRANGEBYSCORE - 按分数范围删除

# 删除分数小于100的成员
ZREMRANGEBYSCORE leaderboard -inf 100
# 返回: (integer) 1

# 实际应用:删除低分用户
ZREMRANGEBYSCORE game:rank -inf 1000

四、实际应用场景

1. 游戏排行榜

# 添加玩家分数
ZADD game:rank 9500 "player1" 8800 "player2" 9200 "player3"

# 玩家获得积分
ZINCRBY game:rank 100 "player1"

# 获取前10名
ZREVRANGE game:rank 0 9 WITHSCORES

# 查询玩家排名
ZREVRANK game:rank "player1"

# 查询玩家分数
ZSCORE game:rank "player1"

2. 延时队列

# 添加延时任务(分数为执行时间戳)
ZADD delay:queue 1707024000 "task1" 1707024060 "task2"

# 获取到期的任务(当前时间之前的)
ZRANGEBYSCORE delay:queue -inf 1707024000

# 删除已执行的任务
ZREM delay:queue "task1"

3. 热门文章排序

# 添加文章(分数为热度值)
ZADD hot:articles 1000 "article:1001" 800 "article:1002"

# 文章被点赞,热度+10
ZINCRBY hot:articles 10 "article:1001"

# 获取热门文章前20
ZREVRANGE hot:articles 0 19

# 获取热度在500-1000的文章
ZRANGEBYSCORE hot:articles 500 1000

4. 优先级队列

# 添加任务(分数为优先级)
ZADD task:queue 1 "task:low" 5 "task:medium" 10 "task:high"

# 获取最高优先级任务
ZREVRANGE task:queue 0 0

# 删除已处理任务
ZREM task:queue "task:high"

5. 时间线功能

# 添加动态(分数为时间戳)
ZADD timeline:user:1001 1707024000 "post:1" 1707024060 "post:2"

# 获取最新10条动态
ZREVRANGE timeline:user:1001 0 9

# 获取某个时间段的动态
ZRANGEBYSCORE timeline:user:1001 1707020000 1707030000

五、常用命令对照表

命令 功能 时间复杂度
ZADD 添加成员 O(log N)
ZSCORE 获取分数 O(1)
ZRANK 获取排名 O(log N)
ZRANGE 按排名获取 O(log N + M)
ZRANGEBYSCORE 按分数获取 O(log N + M)
ZREM 删除成员 O(M log N)
ZCARD 获取数量 O(1)
ZINCRBY 增加分数 O(log N)
性能优化建议:

六、实践练习

练习任务:
  1. 实现一个游戏排行榜,支持添加玩家、更新分数、查询排名
  2. 实现一个延时队列,支持添加延时任务、获取到期任务
  3. 实现一个热门文章排序功能,支持点赞增加热度
  4. 实现一个优先级任务队列,按优先级处理任务
  5. 实现一个用户时间线功能,按时间倒序显示动态
  6. 查询分数在1000-2000之间的所有成员
  7. 只保留排行榜前100名,删除其他成员
  8. 统计分数大于5000的用户数量

七、总结

Redis的Sorted Set是一个功能强大的数据结构,特别适合需要排序的场景。通过合理使用Sorted Set,可以高效实现排行榜、延时队列、优先级队列等功能。掌握Sorted Set的各种操作命令,是Redis进阶的重要一步。