Redis set 类型操作及常用命令

时间:2022-07-22
本文章向大家介绍Redis set 类型操作及常用命令,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

七个原则

  1. Redis 是一个操作数据结构的语言工具,它提供基于 TCP 的协议以操作丰富的数据结构。在 Redis 中,数据结构这个词的意义不仅表示在某种数据结构上的操作,更包括了结构本身及这些操作的时间空间复杂度。
  2. Redis 定位于一个内存数据库,正是由于内存的快速访问特性,才使得 Redis 能够有如此高的性能,才使得 Redis 能够轻松处理大量复杂的数据结构, Redis 会尝试其它的存储方面的选择,但是永远不会改变它是一个内存数据库的角色。
  3. Redis 使用基础的 API 操作基础的数据结构, Redis 的 API 与数据结构一样,都是一些最基础的元素,你几乎可以将任何信息交互使用此 API 格式表示。作者调侃说,如果有其它非人类的智能生物存在,他们也能理解 Redis 的 API。因为它是如此的基础。
  4. Redis 有着诗一般优美的代码,经常有一些不太了解 Redis 有的人会建议 Redis 采用一些其它人的代码,以实现一些 Redis 未实现的功能,但这对我们来说就像是非要给《红楼梦》接上后四十回一样。
  5. Redis 始终避免复杂化,我们认为设计一个系统的本质,就是与复杂化作战。我们不会为了一个小功能而往源码里添加上千行代码,解决复杂问题的方法就是让复杂问题永远不要提复杂的问题。
  6. Redis 支持两个层成的 API,第一个层面包含部分操作 API,但它支持用于分布式环境下的 Redis。第二个层面的 API 支持更复杂的 multi-key 操作。它们各有所长,但是我们不会推出两者都支持的 API,但我们希望能够提供实例间数据迁移的命令,并执行 multi-key 操作。
  7. 我们以优化代码为乐,我们相信编码是一件辛苦的工作,唯一对得起这辛苦的就是去享受它。如果我们在编码中失去了乐趣,那最好的解决办法就是停下来。我们决不会选择让 Redis 不好玩的开发模式。

sets 类型及操作

set 是集合,和我们数学中的集合概念相似,对集合的操作有添加删除元素,有对多个集合求交并差等操作, 操作中 key 理解为集合的名字。

set 的是通过 hash table 实现的,所以添加、删除和查找的复杂度都是 O(1)。 hash table 会随着添加或者删除自动的调整大小。需要注意的是调整 hash table 大小时候需要同步(获取写锁)会阻塞其他读写操作,可能不久后就会改用跳表(skip list)来实现,跳表已经在 sortedset 中使用了。关于 set 集合类型除了基本的添加删除操作,其他有用的操作还包含集合的取并集(union),交集(intersection),差集(difference)。通过这些操作可以很容易的实现 sns 中的好友推荐和 blog 的 tag 功能。

常用命令

sadd

向名称为 key 的 set 中添加元素。

127.0.0.1:6379> sadd myset Jacob
(integer) 1
127.0.0.1:6379> sadd myset Jacob2
(integer) 1
127.0.0.1:6379> sadd myset Jacob
(integer) 0
127.0.0.1:6379> smembers myset
1) "Jacob2"
2) "Jacob"

我们向 myset 中添加了三个元素,但由于第三个元素跟第二个元素是相同的,所以第三个元素没有添加成功,最后我们用 smembers 来查看 myset 中的所有元素。

srem

删除名称为 key 的 set 中的元素。

127.0.0.1:6379> smembers myset
1) "Jacob2"
2) "Jacob"
127.0.0.1:6379> srem myset Jacob
(integer) 1
127.0.0.1:6379> srem myset Jacob
(integer) 0

调用 srem 来删除 Jacob,前面操作删除成功,但由于 Jacob 已经被删除了,所以此条 srem 命令执行失败。

spop

随机返回并删除名称为 key 的 set 中一个元素

127.0.0.1:6379> smembers myset
1) "Jacob3"
2) "Jacob4"
3) "Jacob2"
4) "Jacob5"
127.0.0.1:6379> spop myset
"Jacob5"
127.0.0.1:6379> spop myset
"Jacob3"

调用 spop 来删除元素,可以看到每次删除都是随机的。

sdiff

返回所有给定 key 与第一个 key 的差集

127.0.0.1:6379> smembers myset
1) "Jacob4"
2) "Jacob2"
127.0.0.1:6379> smembers myset2
1) "Jacob2"
2) "Jacob"
127.0.0.1:6379> sdiff myset myset2
1) "Jacob4"

可以看到 myset 中的的元素与 myset2 中不同的只有 Jacob4。

sdiffstore

返回所有给定 key 与第一个 key 的差集,并将结果存为另一个 key。

127.0.0.1:6379> smembers myset
1) "Jacob3"
2) "Jacob2"
127.0.0.1:6379> smembers myset2
1) "Jacob2"
2) "Jacob"
127.0.0.1:6379> smembers myset3
1) "Jacob3"
2) "Jacob4"
127.0.0.1:6379> sdiffstore myset4 myset myset2 myset3
(integer) 0
127.0.0.1:6379> sdiffstore myset myset2 myset3 
(integer) 2
127.0.0.1:6379> smembers myset
1) "Jacob"
2) "Jacob2"
127.0.0.1:6379> smembers myset2
1) "Jacob2"
2) "Jacob"
127.0.0.1:6379> smembers myset3
1) "Jacob3"
2) "Jacob4"
sinter

返回所有给定 key 的交集。

127.0.0.1:6379> smembers myset
1) "Jacob"
2) "Jacob2"
127.0.0.1:6379> smembers myset2
1) "Jacob2"
2) "Jacob"
127.0.0.1:6379> sinter myset myset2
1) "Jacob"
2) "Jacob2"
sinterstore

返回所有给定 key 的交集,并将结果存为另一个 key。

127.0.0.1:6379> smembers myset
1) "Jacob"
2) "Jacob2"
127.0.0.1:6379> smembers myset2
1) "Jacob2"
2) "Jacob"
127.0.0.1:6379> sinterstore myset4 myset myset2
(integer) 2
127.0.0.1:6379> smembers myset4
1) "Jacob2"
2) "Jacob"
sunion

返回所有给定 key 的并集。

127.0.0.1:6379> smembers myset2
1) "Jacob2"
2) "Jacob"
127.0.0.1:6379> smembers myset3
1) "Jacob3"
2) "Jacob4"
127.0.0.1:6379> sunion myset2 myset3
1) "Jacob3"
2) "Jacob4"
3) "Jacob"
4) "Jacob2"
sunionstore

返回所有给定 key 的并集,并将结果存为另一个 key。

127.0.0.1:6379> smembers myset2
1) "Jacob2"
2) "Jacob"
127.0.0.1:6379> smembers myset3
1) "Jacob3"
2) "Jacob4"
127.0.0.1:6379> sunionstore myset6 myset3 myset3
(integer) 2
127.0.0.1:6379> smembers myset6
1) "Jacob3"
2) "Jacob4"
smove

从第一个 key 对应的 set 中移除 member 并添加到第二个对应 set 中。

127.0.0.1:6379> smembers myset2
1) "Jacob2"
2) "Jacob"
127.0.0.1:6379> smove myset2 myset7 Jacob
(integer) 1
127.0.0.1:6379> smembers myset7
1) "Jacob"
scard

返回名称为 key 的 set 的元素个数。

127.0.0.1:6379> scard myset
(integer) 2

myset 的成员数量为 1。

sismember

测试 member 是否是名称为 key 的 set 的元素。

127.0.0.1:6379> smembers myset
1) "Jacob"
2) "Jacob2"
127.0.0.1:6379> sismember myset Jacob
(integer) 1
127.0.0.1:6379> sismember myset Jacob3
(integer) 0
srandmember

随机返回名称为 key 的 set 的一个元素,但是不删除元素。

127.0.0.1:6379> smembers myset
1) "Jacob"
2) "Jacob2"
127.0.0.1:6379> srandmember myset
"Jacob"
127.0.0.1:6379> srandmember myset
"Jacob"
127.0.0.1:6379> srandmember myset
"Jacob2"