set 是集合,和我们数学中的集合概念相似,对集合的操作有添加删除元素,有对多个集合求交并差等操作, 操作中 key 理解为集合的名字。
set 的是通过 hash table 实现的,所以添加、删除和查找的复杂度都是 O(1)。 hash table 会随着添加或者删除自动的调整大小。需要注意的是调整 hash table 大小时候需要同步(获取写锁)会阻塞其他读写操作,可能不久后就会改用跳表(skip list)来实现,跳表已经在 sortedset 中使用了。关于 set 集合类型除了基本的添加删除操作,其他有用的操作还包含集合的取并集(union),交集(intersection),差集(difference)。通过这些操作可以很容易的实现 sns 中的好友推荐和 blog 的 tag 功能。
向名称为 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 中的所有元素。
删除名称为 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 命令执行失败。
随机返回并删除名称为 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 来删除元素,可以看到每次删除都是随机的。
返回所有给定 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。
返回所有给定 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"
返回所有给定 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"
返回所有给定 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"
返回所有给定 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"
返回所有给定 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"
从第一个 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"
返回名称为 key 的 set 的元素个数。
127.0.0.1:6379> scard myset
(integer) 2
myset 的成员数量为 1。
测试 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
随机返回名称为 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"