Redis(六) -- Redis数据类型(三) -- Set

1. 简介

Set对外提供的功能与list类似,是一个列表的功能。特殊之处在于set是可以自动排重的,当你需要存储一个列表数据,又不希望出现重复数据时,set是一个很好的选择,并且set提供了判断某个成员是否在一个set集合内的重要接口,这是list所不能提供的。

Set是String类型的无序集合底层其实是一个value为null的hash表,所以添加删除查询的复杂度都是O(1)

2. 数据结构

set的数据结构是dict字典,字典是用哈希表实现的

Java中的HashSet的内部实现使用的是HashMap,只不过所有的value都指向同一个对象。
Redis的set结构也是一样,它的内部也使用hash结构,所有的value都指向同一个内部值

3. 操作

1.sadd 添加member到给定的key中

  • 格式sadd key member [member...]
  • member 如果已经在集合key中存在则忽略.如果集合key 不存在,则新建集合key,并添加member元素到集合key中.
  • 如果key 的类型不是集合则返回错误
  • 返回值:返回新成功添加到集合里元素的数量,不包括已经存在于集合中的元素
  • 复杂度:O(N) where N is the number of members to be added
redis> SADD myset "Hello"
(integer) 1
redis> SADD myset "World"
(integer) 1
redis> SADD myset "World"
(integer) 0
redis> SMEMBERS myset
1) "World"
2) "Hello"

2.scard:返回集合存储的key的基数 (集合元素的数量)

  • 格式scard key
  • 返回值:集合的基数(元素的数量),如果key不存在,则返回 0
  • 复杂度:O(1)
redis> SADD myset "Hello"
(integer) 1
redis> SADD myset "World"
(integer) 1
redis> SCARD myset
(integer) 2

3.sdiff:返回一个集合与给定集合的差集的元素

  • 格式sdiff key1 [key2 key3... ]
  • 返回值:结果集的元素
  • 不存在的key认为是空集
  • 举例:(返回在key1中,而不再其他set中的元素)
key1 = {a,b,c,d}
key2 = {c}
key3 = {a,c,e}
SDIFF key1 key2 key3 = {b,d}
  • 复杂度:O(N) where N is the total number of elements in all given sets
redis> SADD key1 "a"
(integer) 1
redis> SADD key1 "b"
(integer) 1
redis> SADD key1 "c"
(integer) 1
redis> SADD key2 "c"
(integer) 1
redis> SADD key2 "d"
(integer) 1
redis> SADD key2 "e"
(integer) 1
redis> SDIFF key1 key2
1) "a"
2) "b"

4.sdiffstore:比较一个set和其他set的差集,并保存到destination中

  • 格式sdiffstore destination key1 [key2 key3 ...]
  • 如果destination已经存在, 则将其覆盖重写.
  • 返回值:结果集元素的个数
  • 复杂度:O(N) where N is the total number of elements in all given sets.
redis> SADD key1 "a"
(integer) 1
redis> SADD key1 "b"
(integer) 1
redis> SADD key1 "c"
(integer) 1
redis> SADD key2 "c"
(integer) 1
redis> SADD key2 "d"
(integer) 1
redis> SADD key2 "e"
(integer) 1
redis> SDIFFSTORE key key1 key2
(integer) 2
redis> SMEMBERS key
1) "b"
2) "a"

5.sinter:获取所有集合的交集

  • 格式sinter key1 [key2 key3 ...]
  • 例:
key1 = {a,b,c,d}
key2 = {c}
key3 = {a,c,e}
SINTER key1 key2 key3 = {c}
  • 返回值:结果集成员的列表, 如果key不存在则被认为是一个空的集合,当给定的集合为空的时候,结果也为空.(一个集合为空,结果一直为空)
  • 复杂度:O(N*M) worst case where N is the cardinality of the smallest set and M is the number of sets
redis> SADD key1 "a"
(integer) 1
redis> SADD key1 "b"
(integer) 1
redis> SADD key1 "c"
(integer) 1
redis> SADD key2 "c"
(integer) 1
redis> SADD key2 "d"
(integer) 1
redis> SADD key2 "e"
(integer) 1
redis> SINTER key1 key2
1) "c"

6.sinterstore:获取多个set的交集,并将结果保存到destination集合中

  • 格式sinterstore destination key1 [key2 key3...]
  • 如果destination 集合存在, 则会被重写
  • 返回值:结果集中成员的个数
  • 复杂度:O(N*M) worst case where N is the cardinality of the smallest set and M is the number of sets
redis> SADD key1 "a"
(integer) 1
redis> SADD key1 "b"
(integer) 1
redis> SADD key1 "c"
(integer) 1
redis> SADD key2 "c"
(integer) 1
redis> SADD key2 "d"
(integer) 1
redis> SADD key2 "e"
(integer) 1
redis> SINTERSTORE key key1 key2
(integer) 1
redis> SMEMBERS key
1) "c"

7.sunion:获取多个集合的并集

  • 格式sunion key1 [key2 key3...]
  • 不存在的key可以认为是空的集合
  • 例:(不存在的key可以认为是空的集合)
  • 复杂度:O(N) where N is the total number of elements in all given sets.
key1 = {a,b,c,d}
key2 = {c}
key3 = {a,c,e}
SUNION key1 key2 key3 = {a,b,c,d,e}
  • 返回值:并集的成员列表
redis> SADD key1 "a"
(integer) 1
redis> SADD key1 "b"
(integer) 1
redis> SADD key1 "c"
(integer) 1
redis> SADD key2 "c"
(integer) 1
redis> SADD key2 "d"
(integer) 1
redis> SADD key2 "e"
(integer) 1
redis> SUNION key1 key2
1) "a"
2) "b"
3) "c"
4) "d"
5) "e"

8.sunionstore:获取多个集合的并集,并将结果保存到destination

  • 格式sunionstore destination key1 [key2 key3...]
  • 如果destination 已经存在,则将其覆盖.
  • 返回值:结果集中元素的个数
  • 复杂度:O(N) where N is the total number of elements in all given sets.
redis> SADD key1 "a"
(integer) 1
redis> SADD key1 "b"
(integer) 1
redis> SADD key1 "c"
(integer) 1
redis> SADD key2 "c"
(integer) 1
redis> SADD key2 "d"
(integer) 1
redis> SADD key2 "e"
(integer) 1
redis> SUNIONSTORE key key1 key2
(integer) 5
redis> SMEMBERS key
1) "c"
2) "e"
3) "b"
4) "a"
5) "d"

9.sismember:判断member是否是set中的一个元素

  • 格式sismember key member
  • 返回值
    • 如果member元素是集合key的成员,则返回1
    • 如果member元素不是key的成员,或者集合key不存在,则返回0
  • 复杂度:时间复杂度:O(1)
redis> SADD myset "one"
(integer) 1
redis> SISMEMBER myset "one"
(integer) 1
redis> SISMEMBER myset "two"
(integer) 0

10.smembers:返回集合中的所有元素

  • 格式smembers key
  • 该命令的作用与使用一个参数的SINTER 命令作用相同
  • 返回值:集合中的所有元素
  • 复杂度:O(N) where N is the set cardinality
redis> SADD myset "Hello"
(integer) 1
redis> SADD myset "World"
(integer) 1
redis> SMEMBERS myset
1) "World"
2) "Hello"

11.smove:将元素从一个集合移动到另一个集合

  • 格式smove source destination member
  • 如果source 集合不存在或者不包含指定的元素,这smove命令不执行任何操作并且返回0.否则对象将会从source集合中移除,并添加到destination集合中去,如果destination集合已经存在该元素,则smove命令仅将该元素充source集合中移除. 如果source 和destination不是集合类型,则返回错误
  • 返回值
    • 如果该元素成功移除,返回1
    • 如果该元素不是 source集合成员,无任何操作,则返回0
  • 复杂度:O(1)
redis> SADD myset "one"
(integer) 1
redis> SADD myset "two"
(integer) 1
redis> SADD myotherset "three"
(integer) 1
redis> SMOVE myset myotherset "two"
(integer) 1
redis> SMEMBERS myset
1) "one"
redis> SMEMBERS myotherset
1) "three"
2) "two"

12.spop:从set中随机移除并返回一个或多个元素

  • 格式spop key [count]
  • 此操作与SRANDMEMBER类似,它从一个集合中返回一个或多个随机元素,但不删除元素;(spop删除)
  • 返回值:被删除的元素,当key不存在时nil
  • 传递count时的行为规范:如果count大于集合内部的元素数量,此命令将会返回整个集合,不会有额外的元素
  • 返回元素的分布:请注意,当你需要保证均匀分布返回的元素时,此命令不适用
  • 复杂度:O(1)
SADD myset "one"
SADD myset "two"
SADD myset "three"
SPOP myset
SMEMBERS myset
SADD myset "four"
SADD myset "five"
SPOP myset 3
SMEMBERS myset

13.srandmember:随机返回集合中一个或多个元素

  • 格式srandmember key [count]
  • Redis 2.6开始,可以接受 count 参数,如果count是整数且小于元素的个数,返回含有 count 个不同的元素的数组,如果count是个整数且大于集合中元素的个数时,仅返回整个集合的所有元素,当count是负数,则会返回一个包含count的绝对值的个数元素的数组,如果count的绝对值大于元素的个数,则返回的结果集里会出现一个元素出现多次的情况.
  • 仅提供key参数时,该命令作用类似于SPOP命令,不同的是SPOP命令会将被选择的随机元素从集合中移除,而SRANDMEMBER仅仅是返回该随记元素,而不做任何操作
  • 返回值
    • 不使用count 参数的情况下该命令返回随机的元素,如果key不存在则返回nil
    • 使用count参数,则返回一个随机的元素数组,如果key不存在则返回一个空的数组
  • 复杂度:Without the count argument O(1), otherwise O(N) where N is the absolute value of the passed count.
redis> SADD myset one two three
(integer) 3
redis> SRANDMEMBER myset
"one"
redis> SRANDMEMBER myset 2
1) "three"
2) "one"
redis> SRANDMEMBER myset -5
1) "one"
2) "one"
3) "one"
4) "one"
5) "one"
13.1 传递count参数时的行为规范(没看懂)

当传递了一个值为正数的count参数,返回的元素就好像从集合中移除了每个选中的元素一样(就像在宾果游戏中提取数字一样)。但是元素不会从集合中移除。所以基本上:

  • 会返回重复的元素。
  • 如果count参数的值大于集合内的元素数量,此命令将会仅返回整个集合,没有额外的元素。

相反,当count参数的值为负数时,此命令的行为将发生改变,并且提取操作就像在每次提取后,重新将取出的元素放回包里一样,因此,可能返回重复的元素,以及总是会返回我们请求的数量的元素,因为我们可以一次又一次地重复相同的元素,除了当集合为空(或者不存在key)的时候,将总是会返回一个空数组。

13.2 返回元素的分布

当集合中的元素数量很少时,返回元素分布远不够完美,这是因为我们使用了一个近似随机元素函数,它并不能保证良好的分布。

所使用的算法(在dict.c中实现)对哈希表桶进行采样以找到非空桶。一旦找到非空桶,由于我们在哈希表的实现中使用了链接法,因此会检查桶中的元素数量,并且选出一个随机元素。

这意味着,如果你在整个哈希表中有两个非空桶,其中一个有三个元素,另一个只有一个元素,那么其桶中单独存在的元素将以更高的概率返回。

14.srem:删除集合中的元素

  • 格式srem key member1 [m2 m3...]
  • 如果指定的元素不是key集合中的元素则忽略 如果key集合不存在则被视为一个空的集合,该命令返回0.
  • 如果key的类型不是一个集合,则返回错误
  • 返回值:从集合中移除元素的个数,不包括不存在的成员
  • 复杂度:O(N) where N is the number of members to be removed
redis> SADD myset "one"
(integer) 1
redis> SADD myset "two"
(integer) 1
redis> SADD myset "three"
(integer) 1
redis> SREM myset "one"
(integer) 1
redis> SREM myset "four"
(integer) 0
redis> SMEMBERS myset
1) "three"
2) "two"
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值