Sorted Set与排行榜实现
Redis的Sorted Set(有序集合)是Set和Hash的结合体。每个成员都关联一个分数(score),成员按分数从小到大排序。Sorted Set非常适合实现排行榜、延时队列、优先级队列等场景。
# 添加单个成员
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"
# 获取成员分数
ZSCORE leaderboard "player1"
# 返回: "100"
# 获取不存在的成员
ZSCORE leaderboard "player999"
# 返回: (nil)
# 获取成员排名(从0开始,分数从小到大)
ZRANK leaderboard "player1"
# 返回: (integer) 0
ZRANK leaderboard "player4"
# 返回: (integer) 3
# 实际应用:查询用户排名
ZRANK game:rank "user1001"
# 获取逆序排名(分数从大到小)
ZREVRANK leaderboard "player4"
# 返回: (integer) 0
ZREVRANK leaderboard "player1"
# 返回: (integer) 3
# 获取排名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
# 获取前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
# 获取分数在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
# 删除单个成员
ZREM leaderboard "player1"
# 返回: (integer) 1
# 删除多个成员
ZREM leaderboard "player2" "player3"
# 返回: (integer) 2
# 获取有序集合大小
ZCARD leaderboard
# 返回: (integer) 1
# 统计分数在100-200之间的成员数
ZCOUNT leaderboard 100 200
# 返回: (integer) 2
# 统计分数大于150的成员数
ZCOUNT leaderboard 150 +inf
# 增加成员分数
ZINCRBY leaderboard 50 "player4"
# 返回: "350"
# 减少成员分数(使用负数)
ZINCRBY leaderboard -10 "player4"
# 返回: "340"
# 实际应用:用户获得积分
ZINCRBY game:rank 100 "user1001"
# 删除排名0-1的成员(保留前2名之后的)
ZREMRANGEBYRANK leaderboard 0 1
# 返回: (integer) 2
# 实际应用:只保留前100名
ZREMRANGEBYRANK game:rank 100 -1
# 删除分数小于100的成员
ZREMRANGEBYSCORE leaderboard -inf 100
# 返回: (integer) 1
# 实际应用:删除低分用户
ZREMRANGEBYSCORE game:rank -inf 1000
# 添加玩家分数
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"
# 添加延时任务(分数为执行时间戳)
ZADD delay:queue 1707024000 "task1" 1707024060 "task2"
# 获取到期的任务(当前时间之前的)
ZRANGEBYSCORE delay:queue -inf 1707024000
# 删除已执行的任务
ZREM delay:queue "task1"
# 添加文章(分数为热度值)
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
# 添加任务(分数为优先级)
ZADD task:queue 1 "task:low" 5 "task:medium" 10 "task:high"
# 获取最高优先级任务
ZREVRANGE task:queue 0 0
# 删除已处理任务
ZREM task:queue "task:high"
# 添加动态(分数为时间戳)
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) |
Redis的Sorted Set是一个功能强大的数据结构,特别适合需要排序的场景。通过合理使用Sorted Set,可以高效实现排行榜、延时队列、优先级队列等功能。掌握Sorted Set的各种操作命令,是Redis进阶的重要一步。