登录
推荐 文章 Go 技术 课程 下载 专题 AI
首页 >  数据库 >  Redis

Redis Sorted Set 怎样删除指定排名范围

来源:17golang原创

时间:2026-11-07 21:38:20 170浏览 收藏

如果你要清理 Redis Sorted Set 中“排名第几到第几”的成员,直接使用 ZREMRANGEBYRANK key start stop。这里的排名从 0 开始,start 和 stop 都包含在删除范围内;也可以用负数从最高分一侧倒数,例如 -1 表示最高分成员。

官方地址:https://redis.io/docs/latest/commands/zremrangebyrank/

例如,ZREMRANGEBYRANK leaderboard 0 1 会删除最低分侧的前两项,ZREMRANGEBYRANK leaderboard -2 -1 会删除最高分侧的两项。命令返回实际删除的成员数量;若范围为空或没有匹配成员,返回值就是 0。

先把 Sorted Set 看成一条排名坐标

Sorted Set 的 member 按 score 升序排列,排名不是从 1 开始,而是从 0 开始。下面这组数据中,alpha 的排名是 0,delta 的排名是 3;同分时 Redis 还会按 member 的字典序排列,所以不要只凭 score 猜排名。

# 写入一组示例成员;score 越小,正向排名越靠前。
redis-cli ZADD leaderboard 10 alpha 20 beta 30 gamma 40 delta

# 读取成员和 score,先确认当前的排名坐标。
redis-cli ZRANGE leaderboard 0 -1 WITHSCORES
Redis Sorted Set 从零开始的排名坐标与待删除闭区间说明图
图1:Sorted Set 的 score 顺序、正向排名和 ZREMRANGEBYRANK 删除闭区间关系说明图;这是静态结构图,不是 Redis 控制台截图或运行证据。

用 ZREMRANGEBYRANK 删除正向排名区间

命令的固定形式是 ZREMRANGEBYRANK key start stop。其中 start 和 stop 都是零基、闭区间索引;因此删除排名 1 到 2 时,实际会删除两名成员。

# 删除排名 1 和 2,两个端点都包含在内。
redis-cli ZREMRANGEBYRANK leaderboard 1 2

# 返回删除数量后,再读取集合确认剩余成员。
redis-cli ZRANGE leaderboard 0 -1 WITHSCORES

如果集合原本是 alpha、beta、gamma、delta,这条命令会删除 beta 和 gamma,保留两端的 alpha 与 delta。不要把 stop 当成排他边界,否则很容易少删一个成员。

清理最高分或保留头部时使用负排名

负排名从最高分端开始计算:-1 是最高分,-2 是第二高分。这样做的好处是集合长度变化后,清理“最后几名”仍然不需要先计算总数。

# 删除最高分侧的两名成员,-2 和 -1 都包含。
redis-cli ZREMRANGEBYRANK leaderboard -2 -1

# 只保留最低分侧的前 100 名,排名 100 以后全部清理。
redis-cli ZREMRANGEBYRANK leaderboard 100 -1

第二条命令的含义是删除排名 100 到末尾的所有成员,因此执行后最多保留排名 0 到 99 的 100 项。若集合不足 101 项,命令可能返回 0,因为没有成员落在这个范围内。

Redis Sorted Set 正负排名删除路径与 ZRANGE 结果复核关系说明图
图2:正向排名、负向排名、删除成员数和 ZRANGE 复核路径关系说明图;图中表达的是静态对象关系,不是运行结果。

按排名删除和按 score 删除不要混用

ZREMRANGEBYRANK 依据的是位置,ZREMRANGEBYSCORE 依据的是 score 数值。比如“删除最低的 20 名”适合按 rank;“删除 score 小于 100 的成员”则应按 score。两种条件看起来相近,但在并列分数或集合不断变化时结果不同。

目标命令边界语义
删除排名区间ZREMRANGEBYRANK零基、按位置、两端包含
删除最高分侧末尾几项ZREMRANGEBYRANK key -n -1负排名从最高分倒数
删除 score 区间ZREMRANGEBYSCORE按数值范围判断
删除指定 memberZREM按成员名精确删除

当需求是固定容量排行榜时,常见做法是写入新成员后用 ZREMRANGEBYRANK key 0 -101 清理低分侧,让集合保留最高 100 名。这个范围是否正确取决于你的排序方向和“保留多少项”的定义,发布到生产前应先用一组小数据画出排名坐标。

用返回值和读取结果确认清理边界

这个命令的返回值是删除的成员数,不是删除后的集合长度。要判断边界是否符合预期,先记录命令返回值,再用 ZRANGE key 0 -1 WITHSCORES 读取剩余成员。整个操作的复杂度是 O(log(N)+M),其中 N 是集合大小,M 是删除数量。

# 删除排名 0 到 9,并把返回的删除数量交给调用方记录。
redis-cli ZREMRANGEBYRANK leaderboard 0 9

# 读取剩余成员;空结果表示集合已没有成员。
redis-cli ZRANGE leaderboard 0 -1 WITHSCORES

# 读取集合数量,用于和业务保留数量做对照。
redis-cli ZCARD leaderboard

如果整组成员都被删掉,Redis 会删除这个 Sorted Set key。批量清理数量很大时,应该把删除任务纳入业务低峰和慢命令监控;如果只需要弹出少量最高或最低成员,也可以比较 ZPOPMAX 或 ZPOPMIN 是否更符合“读取并删除”的语义。

常见问题

start 和 stop 是从 1 还是从 0 开始?

从 0 开始,并且 stop 也包含。删除第 1 个到第 3 个成员时,应写成 0 2,而不是 1 3。

为什么 -1 代表最高分?

负排名从集合末尾倒数,-1 是最高分一项,-2 是第二高分。它适合描述“最后几项”,不需要先调用 ZCARD 计算正向下标。

按排名删除会不会删除同分成员的一部分?

会。排名先由 score 决定,同分时再按 member 字典序决定位置;命令最终删除的是落在索引区间内的成员,不会把相同 score 自动视为一个整体。

返回 0 是否说明 key 一定不存在?

不一定。key 不存在、范围没有命中成员,或者起止范围与当前集合不相交,都可能返回 0。若业务需要区分这些情况,应在执行前结合 EXISTS、ZCARD 或读取结果判断。

参考入口:https://redis.io/docs/latest/commands/zremrangebyrank/;Sorted Set 数据结构说明:https://redis.io/docs/latest/develop/data-types/sorted-sets/。

声明:本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>