*Redis ZADD 命令

向 Sorted Set 中添加一个或多个成员,或更新已有成员的 score。


*语法

ZADD key [NX | XX] [GT | LT] [CH] [INCR] score member [score member ...]

*参数说明

参数 类型 必填 说明
key String Sorted Set 的键名
score Double 排序分数,可包含小数
member String 成员值
NX 标志 仅新增,不更新已有 member(Redis 3.0.2+)
XX 标志 仅更新已有 member,不新增
GT 标志 仅当新 score > 当前 score 时更新(Redis 6.2+)
LT 标志 仅当新 score < 当前 score 时更新(Redis 6.2+)
CH 标志 返回修改的 member 数量(默认只返回新增)
INCR 标志 对 score 做增量添加(类似 ZINCRBY)

*返回值

条件 返回值
默认 新增 member 数量
带 CH 新增 + 修改 score 的 member 总数
带 INCR 返回更新后的 score(String)

*时间复杂度

O(log(N))(单个 member),N 为 Sorted Set 成员数量。


*示例

# 基本用法
> ZADD leaderboard 100 "player1"
(integer) 1

> ZADD leaderboard 200 "player2" 150 "player3"
(integer) 2

# 更新 score
> ZADD leaderboard 250 "player1"
(integer) 0

# CH 返回修改数
> ZADD leaderboard CH 300 "player1" 400 "player4"
(integer) 2

# INCR 增量
> ZADD leaderboard INCR 50 "player1"
"350"

*常见错误

  1. score 不是数字:返回错误。
  2. 参数不成对:ZADD 的 score 和 member 必须成对出现。

*最佳实践

  1. 排行榜/热点排序:score 为时间戳、分数、热度值,member 为 ID。
  2. 时间序列:score 为 Unix 时间戳,member 为事件数据,实现按时间排序。
  3. 范围查询:用 ZRANGEBYSCORE 按 score 范围查询,比 List 的 LRANGE 更灵活。
  4. 分页ZREVRANGE key start stop 支持按排名分页。

*FAQ

Q: ZADD 和 SADD 有什么区别? A: SADD 是无序 Set,去重;ZADD 是 Sorted Set,每个 member 带 score,按 score 排序,member 唯一但 score 可重复。

Q: score 相同怎么排序? A: score 相同时按 member 的字典序排序。

Q: 如何实现滑动窗口排行榜? A: 用时间戳做 score,只保留近期数据:先 ZREMRANGEBYSCORE key 0 (now-window) 清理旧数据,再 ZADD 新数据。