Redis五大数据类型——Set集合

Redis Set 是一种用于存储无序且不重复元素的数据结构,常用于实现唯一性数据存储。Set 操作包括添加、删除、查询成员,以及进行交集、并集、差集等集合运算。这些操作在服务器端高效执行,减少网络IO。常用命令如 `sadd` 添加成员,`srem` 删除成员,`sinter` 计算交集,`sunion` 计算并集,`sdiff` 计算差集。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 Redis五大数据类型:String(字符串),Hash(哈希),List(列表),Set(集合)及Zset(sorted set:有序集合)。

 一、介绍

Set 集合用于存储无序不重复的元素。

列表可以存储重复元素,而集合只会存储非重复元素。如添加已存在的元素将被忽略

Set 重要的特性:即在服务器端完成多个Sets之间的聚合计算操作,如unions、intersections和differences。由于这些操作均在服务端完成,因此效率极高,而且也节省了大量的网络IO开销。

二、数据结构

底层使用两种数据结构存储:

  • inset     可理解为数组
  • hashtable  普通的哈希表(key为set的值,value为null)

使用intset存储必须满足下面两个条件,否则使用hashtable,条件如下:

  • 对象保存的所有元素都是整数值(int)
  • 对象保存的元素数量不超过512个

set-max-inset-entries 512

三、操作命令

命令功能语法描述
smembers查询Smembers key返回集合中所有元素
sadd添加Sadd key 成员1 ..向集合添加一个或多个成员
srem删除指定元素Srem key 成员1 ..删除集合中一个或多个成员
spop随机删除Spop key [count]删除并返回集合中的一个或多个随机元素
smove移动指定元素Smove [源集合] [目标集合] 成员

从源集合移动某个元素到目标集合中

scard获取长度Sadd key获取集合的成员数
sdiff差集 (不同)Sdiff key1 [key2..]返回指定的所有集合的差集
sinter交集 (相同)Sinter key1 [key2..]返回给定所有集合的交集
sunion并集 (合并)Sunion key1 [key2..]返回所有给定集合的并集
srandmember随机返回Srandmember key [count]返回集合中一个或多个随机数
sismember判断是否存在Sismemeber key [成员]判断集合中是否存在某成员
sinterstore交集存入新集合Sinterstore [新集合] key1 ...返回指定集合的交集,并存储到新集合
sdiffstore差集存入新集合Sdiffstore [新集合] key1 ...返回指定集合的差集,并存储到新集合
sunionstore合集存入新集合Sunionstore [新集合] key1 ...返回指定集合的合集,并存储到新集合

 1、Sadd   向集合添加一个或多个成员  (添加)

语法:Sadd key 成员1 [成员2 ...]

[127.0.0.1:6379> sadd set a b c c d  # 创建或往myset集合中添加“a、b、c、d“成员
(integer) 4
[127.0.0.1:6379> smembers set  # [smembers key] 查询myset中所有成员
1) "c"
2) "b"
3) "a"
4) "d"


2、Srem  移除一个或多个指定成员 (删除指定成员)

语法:Srem key 成员1 ..

# 原集合中所有成员
[127.0.0.1:6379> smembers myset
1) "b"
2) "a"
3) "d"
4) "c"

[127.0.0.1:6379> srem myset a b  # 删除myset集合中 “a"、"b" 两个成员
(integer) 2

[127.0.0.1:6379> smembers myset  # 查询集合中所有成员
1) "d"
2) "c"

3、Spop  移除并返回集合中的一个随机成员 (删除随机成员)

语法:Spop key [count]

# 原集合中所有成员
[127.0.0.1:6379> smembers myset  
1) "c"
2) "b"
3) "a"
4) "d"
5) "e"

# 1. 移除myset集合中随机2个成员
[127.0.0.1:6379> spop myset 2
1) "b"
2) "e"

# 原集合中所有成员
[127.0.0.1:6379> smembers myset
1) "a" 
2) "d"  # 成员“b、e"已被移除
3) "c"

# 2. 移除myset集合中随机1个成员
[127.0.0.1:6379> spop myset
"a"

# 原集合中所有成员
[127.0.0.1:6379> smembers myset
1) "d"
2) "c"

4、Smove  从源集合移动某个元素到目标集合中(移动成员)

语法:Smove [源集合] [目标集合] 成员

# 创建并添加成员到myset集合中(注意newset集合不存在)
[127.0.0.1:6379> sadd myset a b c d
(integer) 4

[127.0.0.1:6379> smove myset newset a  #1.移动源集合myset中“a"成员到目标集合newset
(integer) 1  # 返回成功移动了1个

# 查看newset新集合的所有成员
[127.0.0.1:6379> smembers myset
1) "c"
2) "b"
3) "d"

# 查看newset新集合的所有成员
[127.0.0.1:6379> smembers newset
1) "a"

[127.0.0.1:6379> smove myset newset a  # 2.移动不存在的成员,返回 0
(integer) 0

5、Scard  获取某个集合中所有成员个数  (获取成员个数)

语法:Sadd key

[127.0.0.1:6379> smembers set  # [smembers key] 查询myset中所有成员
1) "c"
2) "b"
3) "a"
4) "d"
[127.0.0.1:6379> scard myset  # 获取myset集合成员个数
(integer) 4

6、Sdiff  返回给定集合中的差集  (差集)

语法:Sdiff key1 [key2..]

# 创建myset、myset2集合,并往集合中添加成员
[127.0.0.1:6379> sadd myset a b c d
(integer) 4
127.0.0.1:6379> sadd myset2 b c k m
(integer) 4

# 查询myset的差集
[127.0.0.1:6379> sdiff myset
1) "a"
2) "b"
3) "c"
4) "d"

# 查询myset集合基于myset2集合中的差集
[127.0.0.1:6379> sdiff myset myset2 
1) "a"
2) "d" # myset集合中的元素在myset2中,少了"a"、"d"

# 查询myset2集合基于myset集合中的差集
[127.0.0.1:6379> sdiff myset2 myset
1) "k"
2) "m"  # myset2集合中的元素在myset中,少了"k"、"m"

  

7、Sinter 返回给定集合中的交集  (交集)

语法:Sinter key1 [key2..]

# 创建myset、myset2集合,并往集合中添加成员
[127.0.0.1:6379> sadd myset a b c d
(integer) 4
127.0.0.1:6379> sadd myset2 b c k m
(integer) 4

[127.0.0.1:6379> sinter myset myset2  # 查询myset、myset2集合中相同的成员
1) "c"
2) "b"

8、Sunion 返回给定集合中的并集  (并集)

语法:Sunion key1 [key2..]

# 创建myset、myset2集合,并往集合中添加成员
[127.0.0.1:6379> sadd myset a b c d
(integer) 4
127.0.0.1:6379> sadd myset2 b c k m
(integer) 4

[127.0.0.1:6379> sunion myset myset2   # 查询myset、myset2集合中的所有成员
1) "b"
2) "a"
3) "k"
4) "d"
5) "c"
6) "m"

9、Srandmember  返回集合中一个或多个随机数  (随机返回)

语法:Srandmember key [count]

# 创建myset集合,并往集合中添加成员
[127.0.0.1:6379> sadd myset a b c d 
(integer) 4

# 随机返回集合中2个成员
[127.0.0.1:6379> srandmember myset 2
1) "a"
2) "c"

# 查询myset集合中所有成员
[127.0.0.1:6379> smembers myset
1) "c"
2) "b"
3) "a"
4) "d"

10、Sismember  判断集合中是否存在某成员  (判断是否存在)

语法:Srandmember key [count]

# 查询myset集合中所有成员
[127.0.0.1:6379> smembers myset
1) "c"
2) "b"
3) "a"
4) "d"

[127.0.0.1:6379> sismember myset k   # 判断myset集合中是否存在"k"
(integer) 0

[127.0.0.1:6379> sismember myset a  # 判断myset集合中是否存在"a"
(integer) 1 # 存在,返回1

返回给定所有集合的交集并存储在 destination 中

11、Sinterstore  获取指定集合的交集并存入到新集合  (获取交集并存入新集合)

语法:Sinterstore [新集合] key1 ...

# 创建myset1、myset2集合,并添加成员到集合中
[127.0.0.1:6379> sadd myset1 a b c
(integer) 3
[127.0.0.1:6379> sadd myset2 b m k
(integer) 3

# 1. 获取myset1与myset2集合中的相同成员,并存入myset3集合中
[127.0.0.1:6379> sinterstore myset3 myset1 myset2
(integer) 1

# 查询 myset1集合
[127.0.0.1:6379> smembers myset1
1) "c"
2) "b"
3) "a"

# 查询 myset2集合
[127.0.0.1:6379> smembers myset2
1) "b"
2) "k"
3) "m"

# 查询 myset3集合
[127.0.0.1:6379> smembers myset3
1) "b"

 12、Sdiffstore  获取指定集合的差集并存入到新集合  (获取差集并存入新集合)

语法:Sdiffstore [新集合] key1 ...

# 创建myset1、myset2集合,并添加成员到集合中
[127.0.0.1:6379> sadd myset1 a b c
(integer) 3
[127.0.0.1:6379> sadd myset2 b m k
(integer) 3

# 1. 获取myset1 在 myset2集合中的不存在的成员,并存入myset3集合中
[127.0.0.1:6379> sdiffstore myset3 myset1 myset2
(integer) 1

# 查询 myset1集合
[127.0.0.1:6379> smembers myset1
1) "c"
2) "b"
3) "a"

# 查询 myset2集合
[127.0.0.1:6379> smembers myset2
1) "b"
2) "k"
3) "m"

# 查询 myset3集合
[127.0.0.1:6379> smembers myset3
1) "a"  # "a"、"c"元素不存在myset2种
2) "c"

13、Sunionstore  获取指定集合的合集并存入到新集合  (获取合集并存入新集合)

语法:Sunionstore [新集合] key1 ...

# 创建myset1、myset2集合,并添加成员到集合中
[127.0.0.1:6379> sadd myset1 a b c
(integer) 3
[127.0.0.1:6379> sadd myset2 b m k
(integer) 3

# 1. 获取myset1与myset2集合中的所有成员,并存入myset3集合中
[127.0.0.1:6379> sunionstore myset3 myset1 myset2
(integer) 1

# 查询 myset3集合
[127.0.0.1:6379> smembers myset3
1) "a"
2) "b"
3) "c"
4) "k"
5) "m"

四、应用范围

  • 文章浏览统计;利用set保存唯一性数据;同一个IP地址访问当前页面不断刷新只记录一次有效浏览数,仅需在每次访问该文章时将访问者的IP存入Redis中
  • 好友推荐;可以通过Set类型的数据,做交集、并集、差集等方式,得到好友之间的共同关注

### Redis 支持的五种数据结构 #### String 类型 String 是最简单的类型,可以看作是一个字符串或者二进制安全的字节序列。除了存储简单字符串外,还可以用于计数器等场景。 ```python SET key value # 设置指定 key 的值 GET key # 获取指定 key 的值 INCR key # 将 key 中储存的数字值增一 DECR key # 将 key 中储存的数字值减一 ``` 对于对象类数据而言,在有频繁更新需求的情况下,直接使用 string 存储整个 JSON 或者其他形式的对象串确实不够灵活[^1]。 #### Hash 类型 Hash 数据类型允许对一系列字段进行分组管理,适合用来表示对象属性。内部通过 field-value 形式的键值对来组织数据,其中 field 和 value 都是字符串类型的。 ```python HSET user:1 name "Alice" # 向哈希表 user:1 中设置域 name 的值为 Alice HMSET user:2 age 28 city Beijing # 同时向多个字段赋值 HGETALL user:1 # 获取哈希表中所有的字段和值 ``` 这种设计使得 hash 成为了处理复杂对象的理想选择之一。 #### List 类型 List 表现为双向链表的形式,意味着可以从两端高效地插入或移除元素。适用于消息队列之类的场合。 ```python LPUSH mylist "world" # 在列表头部添加元素 RPUSH mylist "hello" # 在列表尾部添加元素 LRANGE mylist 0 -1 # 输出整个列表的内容 LPOP mylist # 移除并返回列表的第一个元素 RPOP mylist # 移除并返回列表最后一个元素 ``` 不过需要注意的是,当需要确保唯一性的时候,则应该考虑采用 set 来代替 list[^2]。 #### Set 类型 Set 实际上是一群独一无二的字符组成的集合,不允许重复项的存在。由于其特性非常适合做去重工作,并提供了丰富的集合运算指令如交集、并集、差集等操作。 ```python SADD unique_set item1 # 添加新成员到集合里 SMEMBERS unique_set # 列举出所有成员 SCARD unique_set # 查看集合大小 SISMEMBER unique_set member # 测试某元素是否属于该集合 SINTER setA setB # 计算两个集合之间的交集 ``` 这些功能让 set 特别适合作为代表社交网络关系模型中的好友圈或者其他关联群体的关系表达工具[^4]。 #### Sorted Set (Zset) 类型 Sorted Set 不仅具备 set 的特点——即不会出现相同的分数对应不同的成员的情况;而还能按照 score 排序,这使其能够轻松构建排行榜之类的应用程序逻辑。 ```python ZADD leaderboard 95.5 player1 # 给定分数给玩家排名 ZRANK leaderboard player1 # 查询特定用户的排名位置 ZSCORE leaderboard player1 # 得知具体得分情况 ZRANGEBYSCORE leaderboard min max # 根据分数范围获取区间内的用户名单 ``` 综上所述,每一种数据结构都有各自的优势领域,合理选用才能发挥最大效能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值