redis数据类型lists详解

Sets

Redis set对外提供的功能与list类似是一个列表的功能,特殊之处在于set是可以自动排重的,当你需要存储一个列表数据,又不希望出现重复数据时,set是一个很好的选择,并且set提供了判断某个成员是否在一个set集合内的重要接口,这个也是list所不能提供的。
Redis的Set是string类型的无序集合。它底层其实是一个value为null的hash表,所以添加,删除,查找的复杂度都是O(1)。
一个算法,随着数据的增加,执行时间的长短,如果是O(1),数据增加,查找数据的时间不变。

  • 添加一个或多个指定的member元素到集合的 key中
sadd key member1 member2......

指定的一个或者多个元素member 如果已经在集合key中存在则忽略.如果集合key 不存在,则新建集合key,并添加member元素到集合key中.如果key 的类型不是集合则返回错误.

  • 获取集合元素的数量
scard key

如果key不存在,则返回 0.

  • 取出该集合的所有值。
smembers key
  • 判断集合 key 是否为含有该 value 值
sismember key value

如果member元素是集合key的成员,则返回1,如果member元素不是key的成员,或者集合key不存在,则返回0

  • 删除集合中的某个元素。
srem key member
#2.4及之后版本可以接收同时删除多个member
srem key member1 member2......

如果指定的元素不是key集合中的元素则忽略 如果key集合不存在则被视为一个空的集合,该命令返回0.如果key的类型不是一个集合,则返回错误.

  • 随机从该集合中移除并返回N个值。
    注意,参数N在一些低版本中不可用
spop key N

被删除的元素,或者当key不存在时返回nil,不加个数默认1个,多于集合元素个数,移除并返回全部元素,销毁集合

  • 与spop相似的还有srandmember,也可以随机返回n个member
    参数n在2.6及以上才可用
srandmember key n

spop 指令和srandmember指令具有相似的功能,当时spop会移除指定的member而srandmember不会

  • 把集合中的member从集合key1移动到集合key2
smove key1 key2 member

如果source 集合不存在或者不包含指定的元素,这smove命令不执行任何操作并且返回0.否则对象将会从source集合中移除,并添加到destination集合中去,如果destination集合已经存在该元素,则smove命令仅将该元素充source集合中移除. 如果source 和destination不是集合类型,则返回错误.

  • 获取两个集合的交集元素。
sinter key1 key2

如果key不存在则被认为是一个空的集合,当给定的集合为空的时候,结果也为空.(一个集合为空,结果一直为空).

  • 获取两个集合的并集元素。
sunion key1 key2
  • 获取两个集合的差集元素
sdiff key1 key2 key3......

返回key1中有,而key2、key3…中没有的元素

  • 与sdiff相似的一个指令sdiffstore
sdiffstore destination key1 key2 key3...

与sdiff不同之处在于这条指令并不会返回差集,而是将结果存放在destination集合中.如果destination已经存在, 则将其覆盖重写(完全覆盖,即使是不重复元素).

演示

#往myset集合中添加多个元素
127.0.0.1:6379> sadd myset 1 2 3
#返回添加元素个数
(integer) 3
#查看当前集合元素个数
127.0.0.1:6379> scard myset
(integer) 3
#获取全部元素
127.0.0.1:6379> smembers myset
1) "1"
2) "2"
3) "3"
#删除指定元素1
127.0.0.1:6379> srem myset 1
#返回删除的个数
(integer) 1
127.0.0.1:6379> smembers myset
1) "2"
2) "3"
#删除集合中多个元素
127.0.0.1:6379> srem myset 2 3
(integer) 2
#删除完元素后集合会销毁
127.0.0.1:6379> smembers myset
(empty array)
127.0.0.1:6379> sadd myset 1 2
(integer) 2
#随机移除并返回一个元素
127.0.0.1:6379> spop myset 1
1) "2"
127.0.0.1:6379> smembers myset
1) "1"
127.0.0.1:6379> sadd myset2 a
(integer) 1
#随机返回一个元素
127.0.0.1:6379> srandmember myset
"1"
127.0.0.1:6379> sadd myset2 a
(integer) 0
127.0.0.1:6379> smembers myset
1) "1"
127.0.0.1:6379> smembers myset2
1) "a"
127.0.0.1:6379> sadd myset b
(integer) 1
127.0.0.1:6379> smembers myset
1) "b"
2) "1"
# 把myset集合中的b移到myset2中
127.0.0.1:6379> smove myset myset2 b
(integer) 1
127.0.0.1:6379> smembers myset
1) "1"
127.0.0.1:6379> smembers myset2
1) "b"
2) "a"
127.0.0.1:6379> sadd myset a
(integer) 1
# 获取myset集合与myset2集合的交集
127.0.0.1:6379> sinter myset myset2
1) "a"
# 获取myset集合与myset2集合的并集
127.0.0.1:6379> sunion myset myset2
1) "b"
2) "1"
3) "a"
# 获取myset集合与myset2集合的差集
127.0.0.1:6379> sdiff myset myset2
1) "1"
127.0.0.1:6379> sdiff myset2 myset
1) "b"
# 把myset集合与myset2集合的差集存到集合myset3中
127.0.0.1:6379> sdiffstore myset3 myset2 myset
(integer) 1
127.0.0.1:6379> smembers myset3
1) "b"

数据结构

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