*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 对 |
注意:
GT、LT和NX三者互斥,不能同时使用。
*score 有效值范围
Redis 使用 64 位双精度浮点数表示 score。可精确表示的整数范围是 -(2^53) 到 +(2^53)(即 -9007199254740992 到 9007199254740992)。更大的整数将以指数形式近似表示。
*返回值
- Integer:默认返回被新添加的成员数量(不包含已存在但被更新
score的成员)。 - 如果使用了
CH选项,返回发生变更的成员总数(新增 +score被更新的成员)。 - 如果使用了 INCR 选项,返回该成员更新后的
score值(字符串形式的双精度浮点数);若因XX或NX条件未执行则返回nil。
*时间复杂度
- O(log(N)) 每添加一个成员,其中
N是有序集合中的成员总数。
*版本兼容性
| Redis 版本 | 变更说明 |
|---|---|
| >= 1.2.0 | 初始支持 |
| >= 2.4.0 | 支持一次添加多个成员 |
| >= 3.0.2 | 增加 XX、NX、CH、INCR 选项 |
| >= 6.2.0 | 增加 GT 和 LT 选项 |
*示例
*示例 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"