如何管理 Redis 中的 Sets 集合

源地址:https://www.digitalocean.com/community/cheatsheets/how-to-manage-sets-in-redis
作者:Mark Drake

简介

Redis 是一个开源的、运行在内存中的键值数据库。Redis 中的 Sets 集合是存储在一个给定键上的字符串的集合。当存储在一个集合中时,一个单独的记录值被称为一个成员。与列表不同,集合是不允许重复值的无序结果。

本教程解释了如何创建集合,检索和删除成员,以及比较不同集合的成员。

如何使用这个教程

这个教程是以小抄(Cheat Sheet)的形式写的,有对应的例子。我们鼓励你直接跳转到和你要完成的任务相关的章节进行阅读。

这个教程中的命令在 Ubuntu 18.04 中的 Redis 4.0.9 版本完成测试。如果你需要建设一个同样的环境,可以参考我们的 如何在 Ubuntu 18.04 上安装并加固 Redis 中的 Step 1 来安装 Redis。我们将通过 Redis 命令行界面redis-cli运行这些命令,来演示这些命令的行为。请注意,如果你使用不同的 Redis 工具--例如Redli —— 某些命令的实际输出可能有所不同。

此外,你还可以使用一个代管的 Redis 数据库实例来测试这些命令。但需要注意的是,根据你的数据库服务提供商的限制,这个教程中的某些命令可能运行效果和教程不一致。如果想要使用 DigitalOcean 提供的代管数据库,可以查看我们的代管数据库产品文档。使用代管 Redis 数据库实例时,你必须安装 Redli设置 TLS 隧道 来通过 TLS 链接到代管数据库。

创建集合

sadd 命令允许您创建一个集合并向其中添加一个或多个成员。以下示例将在名为 key_horror 的键上创建一个集合,其中包含成员 "Frankenstein" 和 "Godzilla":

127.0.0.1:6379>  sadd key_horror "Frankenstein" "Godzilla"

sadd 如果成功,将返回一个整数,显示它添加到集合中的成员数:

输出

(integer) 2

如果您尝试将集合的成员添加到已经包含非集合值的键,它将返回错误。此块中的第一个命令创建一个名为 key_actionlist,其中包含一个元素 "Shaft"。下一个命令尝试将集合成员 Shane 添加到列表中,但由于数据类型冲突,这会产生错误:

127.0.0.1:6379>  rpush key_action "Shaft"
127.0.0.1:6379>  sadd key_action "Shane"

输出

 (error) WRONGTYPE Operation against a key holding the wrong kind of value

请注意,集合不允许同一成员多次出现:

127.0.0.1:6379>  sadd key_comedy "It's" "A" "Mad" "Mad" "Mad" "Mad" "Mad" "World"

输出

 (integer) 4

即使这个 sadd 命令指定了 8 个成员,它也会丢弃 4 个重复的 "Mad" 成员,从而导致设置大小为 4。

从集合中提取成员

在本节中,我们将介绍一些 Redis 命令,这些命令返回有关集合中保存的成员的信息。要练习此处概述的命令,请运行以下命令,该命令将创建一个名为 key_stooges 的包含六个成员的集合:

127.0.0.1:6379>  sadd key_stooges "Moe" "Larry" "Curly" "Shemp" "Joe" "Curly Joe"

要返回集合中的每个成员,请运行smencer命令,后跟要检查的键:

127.0.0.1:6379>  smembers key_stooges

输出

1) "Curly"
2) "Moe"
3) "Larry"
4) "Shemp"
5) "Curly Joe"
6) "Joe"

要检查特定值是否是集合的成员,请使用 sismember 命令:

127.0.0.1:6379>  sismember key_stooges "Harpo"

如果元素 "Harpo"key_stooges 集合的成员,则 sismember 将返回 1。否则,它将返回 0

输出

 (integer) 0

希望查看给定集合中有多少成员(要查找给定集合的_cardinality_),请运行scard

127.0.0.1:6379>  scard key_stooges

输出

 (integer) 6

希望从集合中获取一个随机元素,可以使用 srandmember 命令:

127.0.0.1:6379>  srandmember key_stooges

输出

 "Larry"

要从集合中返回多个随机的、不同的元素,您可以在 srandmember 命令之后使用要获取的元素数量:

127.0.0.1:6379>  srandmember key_stooges 3

输出

1) "Larry"
2) "Moe"
3) "Curly Joe"

如果给 srandmember 传负数作为参数,则允许该命令多次返回相同的元素:

127.0.0.1:6379>  srandmember key_stooges -3

输出

1) "Shemp"
2) "Curly Joe"
3) "Curly Joe"

虽然 srandmember 在大型数据集中的性能更好,但 srandmember 中使用的随机元素函数并不是完全随机的。有关详细信息,请参阅 该命令的官方文档

从集合中移除成员

Redis 带有三个用于从集合中删除成员的命令:spopsremsmove

spop 从集合中随机选择指定数量的成员并返回它们,类似于 srandmember,但同时会将它们从集合中删除。它接受集合的键名和要从集合中删除的成员数作为参数。如果您不指定数字,spop 将默认返回并删除单个值。

以下示例命令将从上一节中创建的 key_stooges 集中删除并返回两个随机选择的元素:

127.0.0.1:6379>  spop key_stooges 2

输出

1) "Shemp"
2) "Larry"

srem 允许您从集合中删除一个或多个特定成员,而不是随机的:

127.0.0.1:6379>  srem key_stooges "Joe" "Curly Joe"

srem 不是返回从集合中删除的成员,而是返回一个整数,显示删除了多少成员:

输出

 (integer) 2

使用 smove 将成员从一个集合移动到另一个集合。此命令按顺序接受源集、目标集和要移动的成员作为参数。请注意,smove 一次只允许您移动一个成员:

127.0.0.1:6379>  smove key_stooges key_jambands "Moe"

如果命令成功移动成员,它将返回 (integer) 1

输出

 (integer) 1

如果 smove 失败,它将改为返回 (integer) 0。请注意,如果目标键不存在,smove 将创建后再移动成员。

对比集合

Redis 还提供了许多命令来查找集合之间的差异和相似之处。为了演示这些命令是如何工作的,本节将使用三个名为“presidents”、“kings”和“beatles”的集合。如果您想自己尝试本节中的命令,请使用如下 sadd 命令来创建。

127.0.0.1:6379>  sadd presidents "George" "John" "Thomas" "James"
127.0.0.1:6379>  sadd kings "Edward" "Henry" "John" "James" "George"
127.0.0.1:6379>  sadd beatles "John" "George" "Paul" "Ringo"

sinter 比较不同的集合并返回集合的交集,或出现在每个集合中的值:

127.0.0.1:6379>  sinter presidents kings beatles

输出

1) "John"
2) "George"

sinterstore 执行类似的功能,但不是返回相交的成员,而是在指定的目的地创建一个包含这些相交成员的新集合。请注意,如果目的地已经存在,sinterstore 将覆盖其内容:

127.0.0.1:6379>  sinterstore new_set presidents kings beatles
127.0.0.1:6379>  smembers new_set

输出

1) "John"
2) "George"

sdiff 返回 差异的集合 — 由以下每个集合与第一个指定集合的差异产生的成员:

127.0.0.1:6379>  sdiff presidents kings beatles

输出

 1) "Thomas"

换句话说,sdiff 查看第一个集合中的每个成员,然后将它们与每个后续集合中的成员进行比较。第一个集合中出现也在后续集合中出现的任何成员都将被删除,并且 sdiff 返回剩余的成员,将其视为从第一个集合中删除后续集合的成员。

sdiffstore 执行类似于 sdiff 的功能,但不是返回集合差异,而是在给定目的地创建一个包含了差异成员的新集合:

127.0.0.1:6379>  sdiffstore new_set beatles kings presidents
127.0.0.1:6379>  smembers new_set

输出

1) "Paul"
2) "Ringo"

sinterstore 一样,sdiffstore 将覆盖已存在的目标键。

sunion 返回 复合集合,或着说包含指定的每个集合的每个成员的新集合:

127.0.0.1:6379>  sunion presidents kings beatles

输出

1) "Thomas"
2) "George"
3) "Paul"
4) "Henry"
5) "James"
6) "Edward"
7) "John"
8) "Ringo"

sunion 将结果视为一个新集合,因为它只允许任何给定成员出现一次。

sunionstore 执行类似的功能,但在给定目的地创建一个包含集合并集的新集合,而不是仅返回结果:

127.0.0.1:6379>  sunionstore new_set presidents kings beatles

输出

 (integer) 8

sinterstoresdiffstore 一样,sunionstore 将覆盖已经存在的集合。

总结

本指南详细介绍了一些用于在 Redis 中创建和管理集合的命令。