Redis ZADD 命令将一个或多个 member 元素及其 score 值加入到有序集 key 当中。
如果某个 member 已经是有序集的成员,那么更新这个 member 的 score 值,并通过重新插入这个 member 元素,来保证该 member 在正确的位置上。score 值是一个双精度的浮点型数字字符串。如果 key 不存在,则创建一个空的有序集并执行 ZADD 操作。当 key 存在但不是有序集类型时,返回一个错误。
命令格式
ZADD key [NX|XX] [CH] [INCR] score member [score member ...]
可用版本:>=1.2.0
时间复杂度:O(M*log(N)),N 是有序集的基数,M 为成功添加的新成员的数量。
命令参数
ZADD 命令在 key 后面分数/成员(score/member)对前面支持一些参数,它们都是 3.0.2 版本及之后引入的。
- XX:仅仅更新存在的成员,不添加新成员。
- NX:不更新存在的成员。只添加新成员。
- CH:修改返回值为发生变化的成员总数,原始是返回新添加成员的总数(CH 是 changed 的意思)。更改的元素是新添加的成员或者已经存在的成员更新分数。所以在命令中指定的成员有相同的分数将不被计算在内。注:在通常情况下,ZADD 返回值只计算新添加成员的数量。
- INCR:当 ZADD 指定这个选项时,成员的操作就等同 ZINCRBY 命令,对成员的分数进行递增操作,该参数只支持一对分数/成员(score/member)。
命令返回值
- Integer reply(返回整数),添加到有序集合的成员数量,不包括已经存在更新分数的成员。
- Bulk string reply(返回批量字符串),如果指定 INCR 参数,返回成员的新分数(双精度的浮点型数字)字符串。
分数可以精确表示的整数的范围
Redis 有序集合的分数使用双精度64位浮点数。我们支持所有的架构,这表示为一个 IEEE 754 floating point number,它能包括的整数范围是-(2^53)到+(2^53)。或者说是-9007199254740992到 9007199254740992。更大的整数在内部用指数形式表示,所以,如果为分数设置一个非常大的整数,你得到的是一个近似的十进制数。
Sorted sets 101
有序集合按照分数以递增的方式进行排序。相同的成员(member)只存在一次,有序集合不允许存在重复的成员。分数可以通过 ZADD 命令进行更新或者也可以通过 ZINCRBY 命令递增来修改之前的值,相应的它们的排序位置也会随着分数变化而改变。获取一个成员当前的分数可以使用 ZSCORE 命令,也可以用它来验证成员是否存在。
相同分数的成员
有序集合里面的成员是不能重复的都是唯一的,但是,不同成员间有可能有相同的分数。当多个成员有相同的分数时,他们将是有序的字典(ordered lexicographically)(仍由分数作为第一排序条件,然后,相同分数的成员按照字典规则相对排序)。字典顺序排序用的是二进制,它比较的是字符串的字节数组。如果用户将所有元素设置相同分数(例如0),有序集合里面的所有元素将按照字典顺序进行排序,范围查询元素可以使用 ZRANGEBYLEX 命令(注:范围查询分数可以使用 ZRANGEBYSCORE 命令)。
版本历史
- <2.4,只能添加或者更新一个成员;
- >=2.4,可接受多个成员;
- >=3.0.2,增加了 [NX|XX] [CH] [INCR] 参数。
示例
redis> ZADD myzset 1 one
(integer) 1
redis> ZADD myzset 2 two 3 three
(integer) 2
redis> ZADD myzset NX 4 four #成员 four 不存在,添加成功,返回添加数1
(integer) 1
redis> ZADD myzset XX 2.2 two #成员 two 存在,更新分数值,但返回添加数0
(integer) 0
redis> ZADD myzset CH 4 four 5 five 6 six #添加成员 five 和 six,成员 four 分数和之前相同,返回更新数2
(integer) 2
redis> ZADD myzset INCR 0.1 one
"1.1000000000000001"
redis> ZRANGE myzset 0 -1 WITHSCORES
1) "one"
2) "1.1000000000000001"
3) "two"
4) "2.2000000000000002"
5) "three"
6) "3"
7) "four"
8) "4"
9) "five"
10) "5"
11) "six"
12) "6"