4.redis数据结构之Set

2023年 8月 22日 87.4k 0

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进行存储。

相关文章

JavaScript2024新功能:Object.groupBy、正则表达式v标志
PHP trim 函数对多字节字符的使用和限制
新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
为React 19做准备:WordPress 6.6用户指南
如何删除WordPress中的所有评论

发布评论