*Redis ZADD 命令 向有序集合添加成员或更新分数

*语法

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

*说明

ZADD 用于将一个或多个 member(成员)及其对应的 score(分数)添加到指定的有序集合(Sorted Set)key 中。

  • 如果 key 不存在,会创建一个空的有序集合并执行 ZADD 操作。
  • 如果 key 存在但不是有序集合类型,返回错误。
  • 如果 member 已经是有序集合的成员,则更新其 score 值,并重新排序到正确位置。
  • score 值可以是整数或双精度浮点数(64 位 IEEE 754),可为正数或负数。

Redis 有序集合按照 score 值以升序排列。当多个成员 score 相同时,按成员字符串的字典序(lexicographical order)进行排序。

*可选参数

参数位于 key 和第一个 score 之间:

参数 说明
NX 仅添加新成员,不更新已存在的成员
XX 仅更新已存在的成员,不添加新成员
GT 仅当新 score 大于当前 score 时才更新;成员不存在则新增
LT 仅当新 score 小于当前 score 时才更新;成员不存在则新增
CH 返回发生变更的成员数量(新增 + score 更新),而非仅新增数量
INCR 对指定成员的 score 执行增量操作,效果等同于 ZINCRBY。一次只能操作一个 score-member

注意: GTLTNX 三者互斥,不能同时使用。

*score 有效值范围

Redis 使用 64 位双精度浮点数表示 score。可精确表示的整数范围是 -(2^53)+(2^53)(即 -9007199254740992 到 9007199254740992)。更大的整数将以指数形式近似表示。

*返回值

  • Integer:默认返回被新添加的成员数量(不包含已存在但被更新 score 的成员)。
  • 如果使用了 CH 选项,返回发生变更的成员总数(新增 + score 被更新的成员)。
  • 如果使用了 INCR 选项,返回该成员更新后的 score 值(字符串形式的双精度浮点数);若因 XXNX 条件未执行则返回 nil

*时间复杂度

  • O(log(N)) 每添加一个成员,其中 N 是有序集合中的成员总数。

*版本兼容性

Redis 版本 变更说明
>= 1.2.0 初始支持
>= 2.4.0 支持一次添加多个成员
>= 3.0.2 增加 XXNXCHINCR 选项
>= 6.2.0 增加 GTLT 选项

*示例

*示例 1:添加单个成员

# 清空已有 key
DEL page_rank

# 添加单个成员
ZADD page_rank 10 google.com
# 返回:(integer) 1

*示例 2:一次添加多个成员

# 批量添加多个网站及其排名分数
ZADD page_rank 9 baidu.com 8 redis.com.cn 7 github.com
# 返回:(integer) 3

# 查看有序集合内容(带分数)
ZRANGE page_rank 0 -1 WITHSCORES
# 返回:
# 1) "github.com"
# 2) "7"
# 3) "redis.com.cn"
# 4) "8"
# 5) "baidu.com"
# 6) "9"
# 7) "google.com"
# 8) "10"

*示例 3:更新已存在成员的 score

# 先创建有序集合
ZADD scores 85 alice 90 bob 78 carol

# 尝试添加已存在的成员且 score 不变
ZADD scores 85 alice
# 返回:(integer) 0

# 更新已存在成员的 score
ZADD scores 92 alice
# 返回:(integer) 0  (alice 已存在,score 被更新)

# 查看更新后的结果
ZRANGE scores 0 -1 WITHSCORES
# 返回:
# 1) "carol"
# 2) "78"
# 3) "bob"
# 4) "90"
# 5) "alice"
# 6) "92"

*示例 4:使用 NX 选项(仅添加新成员)

ZADD products:price NX 100 "keyboard" 200 "monitor" 50 "mouse"
# 返回:(integer) 3

# 再次执行,所有成员已存在
ZADD products:price NX 150 "keyboard"
# 返回:(integer) 0  (NX 模式下不更新已存在的 keyboard)

# keyboard 的 score 仍然是 100
ZSCORE products:price keyboard
# 返回:"100"

*示例 5:使用 XX 选项(仅更新已存在成员)

# XX 模式下只更新已存在成员,不添加新成员
ZADD products:price XX 150 "keyboard" 999 "new-product"
# 返回:(integer) 0  (只更新了 keyboard,new-product 未添加)

# 验证
ZSCORE products:price keyboard
# 返回:"150"

ZSCORE products:price "new-product"
# 返回:(nil)

*示例 6:使用 CH 选项返回变更数量

DEL myzset
ZADD myzset 1 "one" 2 "two"
# 返回:(integer) 2

# 默认模式下更新已有成员的 score
ZADD myzset 3 "one" 4 "three"
# 返回:(integer) 1  (仅 three 是新增的)

# 使用 CH 选项
ZADD myzset CH 5 "one" 6 "four"
# 返回:(integer) 2  (one 的 score 被更新 + four 是新增的)

*示例 7:使用 INCR 增量更新 score

DEL counter
ZADD counter 100 "user:123"
# 返回:(integer) 1

# 为 user:123 的 score 增加 50
ZADD counter INCR 50 "user:123"
# 返回:"150"

# 再增加 25
ZADD counter INCR 25 "user:123"
# 返回:"175"

*相关命令

  • ZINCRBY — 为有序集合成员的 score 加上指定增量
  • ZSCORE — 返回成员的 score 值
  • ZRANGE — 返回指定排名范围内的成员
  • ZREM — 从有序集合中移除成员