Set-集合类型:S
集合类型:无序、不可重复
命令
增加元素 :SADD key member [member ...]
sadd 命令将一个或多个成员元素加入到集合中,已经存在于集合的成员元素将被忽略。
假如集合 key 不存在,则创建一个只包含添加的元素作成员的集合。
当集合 key 不是集合类型时,返回一个错误。
语法:SADD key member [member ...]
redis 127.0.0.1:6379> SADD myset "hello"
(integer) 1
redis 127.0.0.1:6379> SADD myset "foo"
(integer) 1
redis 127.0.0.1:6379> SADD myset "hello"
(integer) 0
删除元素SREM key member [member ...]
语法:SREM key member [member ...]
redis 127.0.0.1:6379> SADD myset1 "hello"
(integer) 1
redis 127.0.0.1:6379> SADD myset1 "world"
(integer) 1
redis 127.0.0.1:6379> SADD myset1 "bar"
(integer) 1
redis 127.0.0.1:6379> SREM myset1 "hello"
(integer) 1
redis 127.0.0.1:6379> SREM myset1 "foo"
(integer) 0
redis 127.0.0.1:6379> SMEMBERS myset1
1) "bar"
2) "world"
获得集合中的所有元素 SMEMBERS myset
返回集合中的所有的成员。 不存在的集合 key 被视为空集合。
redis 127.0.0.1:6379> SMEMBERS myset
1) "hello"
2) "foo"
判断元素是否在集合中 SISMEMBER key member
如果成员元素是集合的成员,返回 1 。 如果成员元素不是集合的成员,或 key 不存在,返回 0
redis 127.0.0.1:6379> SADD myset1 "hello"
(integer) 1
redis 127.0.0.1:6379> SISMEMBER myset1 "hello"
(integer) 1
redis 127.0.0.1:6379> SISMEMBER myset1 "world"
(integer) 0
获得集合中元素的数量:SCARD key
语法:SCARD key
127.0.0.1:6379> smembers setA
1) "1"
2) "2"
3) "3"
127.0.0.1:6379> scard setA
(integer) 3
从集合中弹出一个元素:SPOP key
注意:由于集合是无序的,所有SPOP命令会从集合中随机选择一个元素弹出
语法:SPOP key
127.0.0.1:6379> spop setA
"1“
运算命令
集合的差集运算:sdiff setA setB
属于A并且不属于B的元素构成的集合。
语法:SDIFF key [key ...]
127.0.0.1:6379> sadd setA 1 2 3
(integer) 3
127.0.0.1:6379> sadd setB 2 3 4
(integer) 3
获取A和B的差集
127.0.0.1:6379> sdiff setA setB
1) "1"
获取B和A的差集
127.0.0.1:6379> sdiff setB setA
1) "4"
集合的交集运算 A ∩ B:sinter setA setB
属于A且属于B的元素构成的集合。
语法:SINTER key [key ...]
127.0.0.1:6379> sinter setA setB
1) "2"
2) "3"
集合的并集运算A∪B:sunion setA setB
属于A或者属于B的元素构成的集合
语法:SUNION key [key ...]
127.0.0.1:6379> sunion setA setB
1) "1"
2) "2"
3) "3"
4) "4"
底层数据结构:intset和哈希表
redis的集合对象set的底层存储结构特别神奇,我估计一般人想象不到,底层使用了intset和hashtable两种数据结构存储的,intset我们可以理解为数组,hashtable就是普通的哈希表(key为set的值,value为null)。是不是觉得用hashtable存储set是一件很神奇的事情。
set的底层存储intset和hashtable是存在编码转换的,使用intset存储必须满足下面两个条件,否则使用hashtable,条件如下:
- 结合对象保存的所有元素都是整数值
- 集合对象保存的元素数量不超过512个
hashtable的数据结构应该在前面的hash的章节已经介绍过了,所以这里着重讲一下intset这个新的数据结构好了。
如果能够转成int的对象(isObjectRepresentableAsLongLong),那么就用intset保存。
如果用intset保存的时候,如果长度超过512(REDIS_SET_MAX_INTSET_ENTRIES)就转为hashtable编码。
其他情况统一用hashtable进行存储。