ZADD:添加或更新成员

通过使用 ZADD 命令,用户可以向有序集合添加一个或多个新成员:

ZADD sorted_set score member [score member ...]

在默认情况下,ZADD 命令将返回成功添加的新成员数量作为返回值。

举个例子,如果我们对不存在的键 salary 执行以下命令:

redis> ZADD salary 3500 "peter" 4000 "jack" 2000 "tom" 5500 "mary"
(integer) 4 -- 这个命令向有序集合新添加了4个成员

那么命令将创建出一个包含 4 个成员的有序集合,如图 6-3 所示。

image 2025 01 03 19 04 12 276
Figure 1. 图6-3 通过执行ZADD命令创建出的有序集合

更新已有成员的分值

ZADD 命令除了可以向有序集合添加新成员之外,还可以对有序集合中已存在成员的分值进行更新:在默认情况下,如果用户在执行 ZADD 命令时,给定成员已经存在于有序集合中,并且给定的分值和成员现有的分值并不相同,那么 ZADD 命令将使用给定的新分值去覆盖现有的旧分值。

举个例子,对于图 6-3 所示的有序集合来说,如果我们执行以下命令:

redis> ZADD salary 5000 "tom"
(integer) 0 -- 因为这是一次更新操作,没有添加任何新成员,所以命令返回0

那么 "tom" 成员的分值将从原来的 2000 变为 5000,更新后的有序集合如图 6-4 所示。

image 2025 01 03 19 06 39 998
Figure 2. 图6-4 更新之后的有序集合

指定要执行的操作

从 Redis 3.0.2 版本开始,Redis 允许用户在执行 ZADD 命令时,通过使用可选的 XX 选项或者 NX 选项来显式地指示命令只执行更新操作或者只执行添加操作:

ZADD sorted_set [XX|NX] score member [score member ...]

这两个选项的功能如下:

  • 在给定 XX 选项的情况下,ZADD 命令只会对给定成员当中已经存在于有序集合的成员进行更新,而那些不存在于有序集合的给定成员则会被忽略。换句话说,带有 XX 选项的 ZADD 命令只会对有序集合已有的成员进行更新,而不会向有序集合添加任何新成员。

  • 在给定 NX 选项的情况下,ZADD 命令只会把给定成员当中不存在于有序集合的成员添加到有序集合里面,而那些已经存在于有序集合中的给定成员则会被忽略。换句话说,带有 NX 选项的 ZADD 命令只会向有序集合添加新成员,而不会对已有的成员进行任何更新。

举个例子,对于图6-4 所示的有序集合来说,执行以下命令只会将已有成员 "jack" 的分值从原来的 4000 改为 4500,而命令中出现的新成员 "bob" 则不会被添加到有序集合中:

redis> ZADD salary XX 4500 "jack" 3800 "bob"
(integer) 0

图6-5展示了命令执行之后的 salary 。

image 2025 01 03 19 09 58 771
Figure 3. 图6-5 对成员 jack 的分值进行更新之后的有序集合

有序集合,注意 "bob" 并没有被添加到有序集合当中。

如果我们对图6-5所示的有序集合执行以下命令:

redis> ZADD salary NX 1800 "jack" 3800 "bob"
(integer) 1

那么 ZADD 命令将把新成员 "bob" 添加到有序集合里面,但并不会改变已有成员 "jack" 的分值,命令执行后的 salary 有序集合如图6-6 所示。

image 2025 01 03 19 11 19 977
Figure 4. 图6-6 添加bob成员之后的salary有序集合

返回被修改成员的数量

在默认情况下,ZADD 命令会返回新添加成员的数量作为返回值,但是从 Redis 3.0.2 版本开始,用户可以通过给定 CH 选项,让 ZADD 命令返回被修改(changed)成员的数量作为返回值:

ZADD sorted_set [CH] score member [score member ...]

“被修改成员” 指的是新添加到有序集合的成员,以及分值被更新了的成员。

举个例子,对于图6-6所示的有序集合来说,执行以下命令将得到返回值 2,表示这个命令修改了两个成员:

redis> ZADD salary CH 3500 "peter" 4000 "bob" 9000 "david"
(integer) 2

被修改的成员分别为 "bob" 和 "david",前者的分值从原来的 3800 改成了 4000,而后者则被添加到了有序集合中。与此相反,因为成员 "peter" 已经存在于有序集合当中,并且它的分值已经是 3500,所以命令没有对它做任何修改。图6-7展示了这条命令执行之后的 salary 有序集合。

image 2025 01 03 19 13 42 069
Figure 5. 图6-7 添加david成员并修改bob成员分值之后的salary有序集合

其它信息

  • 复杂度:O(M*log(N)),其中 M 为给定成员的数量,而 N 则为有序集合包含的成员数量。

  • 版本要求:不带任何选项的 ZADD 命令从 Redis 1.2.0 版本开始可用,带有 NX、XX、CH 等选项的 ZADD 命令从 Redis 3.0.2 版本开始可用。Redis 2.4 版本以前的 ZADD 命令只允许用户给定一个成员,而 Redis 2.4 及以上版本的 ZADD 命令则允许用户给定一个或多个成员。