Skip to content

Redis - 有序集合

Redis 有序集合是一种强大的混合数据结构,类似于常规的集合(Set),但每个成员都与一个浮点型“分数”(score)相关联。该分数用于保持成员的排序,这使得按分数或按排名(位置)检索元素效率极高。

  • 成员唯一:与常规集合一样,有序集合中的成员是唯一的。
  • 按分数排序:元素按分数从小到大排序。如果分数相等,则元素按字典顺序排序。
  • 高效操作:添加、移除或更新成员的分数是非常快的操作,通常是 O(log(N)),其中 N 是集合中成员的数量。按排名或分数检索元素也极其快速。

有序集合的最大成员数量为 2^32 - 1(超过 40 亿)。

有序集合使用双重数据结构实现:哈希表(hash table)和跳跃列表(skip list)。哈希表将成员映射到它们的分数,从而实现成员分数的快速 O(1) 查找。跳跃列表按分数保存所有排序后的元素,从而实现范围操作的高效 O(log(N))。

让我们构建和管理一个简单的排行榜。键将是 leaderboard:2023,成员将是玩家 ID,分数将是他们的高分。

# Add players and their scores. ZADD returns the number of new elements added.
# 添加玩家及其分数。ZADD 返回新添加的元素数量。
redis> ZADD leaderboard:2023 1550 player:jane
(integer) 1
redis> ZADD leaderboard:2023 2100 player:alex
(integer) 1
redis> ZADD leaderboard:2023 1800 player:pablo
(integer) 1
# Alex gets a new high score. The score is simply updated.
# Alex 获得了新的高分。分数被简单地更新了。
# Note that ZADD returns 0 because 'player:alex' is not a new element.
# 注意 ZADD 返回 0,因为 'player:alex' 不是一个新元素。
redis> ZADD leaderboard:2023 2350 player:alex
(integer) 0
# Get the Top 3 players (highest scores first)
# 获取前 3 名玩家(高分优先)
# ZREVRANGE returns a range by rank, in reverse (descending) order.
# ZREVRANGE 按排名返回一个范围,按逆序(降序)排列。
# 0 -1 means from the first element to the last.
# 0 -1 表示从第一个元素到最后一个元素。
# We ask for the top 3 by specifying a range from index 0 to 2.
# 我们通过指定从索引 0 到 2 的范围来获取前 3 名。
redis> ZREVRANGE leaderboard:2023 0 2 WITHSCORES
1) "player:alex"
2) "2350"
3) "player:pablo"
4) "1800"
5) "player:jane"
6) "1550"
# What is Jane's rank on the leaderboard?
# Jane 在排行榜上的排名是多少?
# ZREVRANK returns the 0-based rank of a member (highest score is rank 0).
# ZREVRANK 返回成员的基于 0 的排名(最高分排名为 0)。
redis> ZREVRANK leaderboard:2023 player:jane
(integer) 2

以下是一些最常用的有序集合命令。请注意,许多命令都有 REV 变体(例如 ZREVRANGE)用于降序,以及 BYSCORE 或 BYLEX 变体用于按分数或字典范围查询。

命令描述
ZADD key [NX|XX] [GT|LT] [CH] [INCR] score member [score member …]向有序集合添加一个或多个成员,如果成员已存在则更新其分数。现代版本包括强大的条件更新选项。
ZCARD key获取有序集合中的成员数量。
ZSCORE key member获取有序集合中给定成员关联的分数。
ZRANK key member确定成员的基于 0 的索引(排名),按分数从低到高排序。
ZREVRANK key member确定成员的基于 0 的索引(排名),按分数从高到低排序。
ZREM key member [member …]从有序集合中移除一个或多个成员。
ZINCRBY key increment member增加有序集合中成员的分数。
ZRANGE key start stop [WITHSCORES]按排名(索引)返回一个成员范围,按分数从低到高排序。
ZREVRANGE key start stop [WITHSCORES]按排名返回一个成员范围,按分数从高到低排序。
ZRANGEBYSCORE key min max [WITHSCORES]按分数返回一个成员范围。
ZCOUNT key min max计算有序集合中分数在给定值范围内的成员数量。