首页 > 数据库 >图解Redis 04 | Set数据类型的原理及应用场景

图解Redis 04 | Set数据类型的原理及应用场景

时间:2024-10-10 23:20:16浏览次数:10  
标签:Set 04 0.1 数据类型 6379 127.0 集合 smembers

介绍

Redis 的 Set 类型是一个不允许重复元素的集合,元素存储的顺序不按照插入的顺序,因此属于无序集合。一个 Set 最多可以存储 2^32 - 1 个元素,这与数学中的集合概念类似。Set 类型不仅支持增、删、改、查等操作,还支持多个Set之间的交集、并集和差集运算。

内部实现

Set 类型的底层数据结构可以通过哈希表或intset实现:

  • 如果集合中的所有元素都是整数,并且元素个数小于 512(默认值,可通过属性 set-maxintset-entries 配置),Redis 会使用intset作为 Set 类型的底层数据结构。
  • 如果集合中的元素不符合上述条件,Redis 会使用哈希表作为 Set 类型的底层数据结构。

常用命令

添加一个或多个元素。
sadd key member [member …]

> sadd myset v1 v2 v3
(integer) 3integer) 3
查询集合中的所有元素。
smembers key

127.0.0.1:6379> smembers myset 
1)“v1” 
2)“v3” 
3)“v2”
查询集合中成员的数量。
scard key

> scard myset
(integer) 3integer) 3

命令:scard key

查询集合中是否包含某个元素。
sismember key member

> sismember myset v1
(integer) 1integer) 1
> sismember myset v4
(integer) 0
将元素从一个集合移动到另一个集合。
smove source destination member

> sadd myset2 v1 v8
(integer) 2integer) 2
> smembers myset2
1) "v1"
2) "v8"
> smove myset myset2 v3
(integer) 1
> smembers myset2
1) "v3"
2) "v1"
3) "v8"
> smembers myset
1) "v1"
2) "v2"
删除集合中的一个或多个元素。
srem key member [member …]

> smembers myset2
1) "v3"
2) "v1"
3) "v8"
127.0.0.1:6379> srem myset2 v1
(integer) 1
> smembers myset2
1) "v3"
2) "v8"

注意:使用srem指令时,不存在的元素将被忽略。

返回一个或多个集合的交集。
sinter key [key …]

> sadd myset3 v1 v2 v3
(integer) 33
> smembers myset3
1) "v3"
2) "v1"
3) "v2"
127.0.0.1:6379> smembers myset2
1) "v3"
2) "v8"
127.0.0.1:6379> sinter myset myset2
1) "v3"

更多操作命令,详见文章末尾部分。

应用场景

Set数据结构凭借其无序、不可重复的特性,以及支持并集、交集、差集等丰富操作,在多个场景中展现出卓越的价值。特别是在数据去重保证数据唯一性方面,Set 类型表现优异,除此之外,Set还适合用于统计多个集合之间的交集、并集和差集等关系。

当需要存储的数据不要求保持特定顺序,并且要求数据项唯一、不能重复时,Set 类型无疑是一个理想的选择。

然而,需要注意的是,虽然 Set 提供了强大的集合操作功能,但在处理大规模数据时,直接进行差集、并集、交集等操作的计算复杂度可能会比较高,从而可能导致 Redis 实例在处理过程中出现性能瓶颈或阻塞现象。

在主从集群架构中,为了避免主库因执行这些集合操作而导致的阻塞问题,建议采用以下策略之一

  1. 可以选择一个从库专门用于执行这些聚合计算任务,从而减轻主库的负担;
  2. 可以将原始数据返回给客户端,让客户端负责相关的聚合统计计算。

这两种方式都可以有效避免主库因计算复杂度高而带来的性能问题。

关于主从集群架构的更多细节,我会在后续的文章中进行介绍,这里先留个印象就好了。

场景一:文章点赞

以下是一个示例场景:假设我们有一个文章 ID 为 article:1 的文章。为了记录用户对这篇文章的点赞情况,使用 Set 类型,key为文章 ID article:1,而 Set 中的每个元素代表一个用户 ID。

Set 类型其元素的不可重复性可以确保一个用户只能对某篇文章点赞一次。因此Set 中有多少个元素就代表了有多少个用户对文章点赞了。

例如,用户 uid:1、uid:2 分别对文章 article:1 进行了点赞。这时,article:1 对应的 Set 中将包含这2位用户的 ID:

> SADD article:1 uid:100001
(integer) 1

> SADD article:1 uid:100002
(integer) 1
获取喜欢article:1文章的用户数:
> SCARD article:1
(integer) 2
获取所有喜欢article:1文章的用户。
> SMEMBERS article:1
1) "uid:100002"
2) "uid:100001"
判断用户是否uid: 100002喜欢该篇文章.
> SISMEMBER article:1 uid:100002
(integer) 1  
用户uid:100001取消对article:1文章点赞
> SREM article:1 uid:100001
(integer) 1

场景二:共同关注的好友

Set 类型支持交集运算,因此可以用来计算多个用户关注的共同对象,例如共同关注的好友或博主。

假设我们有两个用户和他们关注的博主账号信息:

  • 用户 uid:1 关注了账号 ID 为 7、8、9。
  • 用户 uid:2 关注了账号 ID 为 8、9、10。
> SADD uid:1 7 8 9
(integer) 3

> SADD uid:2 8 9 10
(integer) 3
uid:1uid:2共同关注的博主集合
> SINTER uid:1 uid:2
1) "8"
2) "9"

Set类型与List类型的区别

最后,我们来看看 Set 类型和 List 类型的一些主要区别:

Set 类型:

  • 元素无序且不重复:Set 中的元素不按照任何特定顺序存储,并且每个元素在集合中是唯一的,不允许重复。
  • 主要用途:适用于快速判断集合中某个元素是否存在,计算集合的交集、并集、差集等操作。
  • 适用场景:适合存储具有唯一标识符且不关心顺序的元素集,例如标签集或用户的唯一 ID 列表。

List 类型:

  • 元素有序可以重复:List 中的元素按照插入的顺序存储,可以通过索引访问每个元素。
  • 支持操作:支持在头部或尾部添加、删除元素等操作。
  • 常见用途:常用于实现队列、栈等数据结构,按顺序存储一系列相关元素,例如消息队列或任务列表。

更多集合操作命令

移除并返回集合中的一个随机元素。
spop key [count]

> smembers myset
1) "v1"
2) "v2"
> spop myset 1
1) "v1"
> smembers myset
1) "v2"
随机返回集合中指定数量的元素列表。
srandmember key [count]

> sadd myset v2 v3 v4
(integer) 3
> srandmember myset 2
1) "v2"
2) "v4"
将集合的交集复制到新集合。
sinterstore destination key [key …]

127.0.0.1:6379> smembers myset
1) "v3"
2) "v4"
3) "v2"
127.0.0.1:6379> smembers myset2
1) "v3"
2) "v8"
127.0.0.1:6379> sinterstore myset4 myset myset2
(integer) 1
127.0.0.1:6379> smembers myset4
1) "v3"

需要注意的是将集合 myset 和集合 myset2 的并集元素(如 v3)复制到了新集合 myset4 中。而v3 等元素依然保留在原始集合中,不会被删除。

查询一个或多个集合的并集。
sunion key [key …]

127.0.0.1:6379> smembers group1
1) "java"
127.0.0.1:6379> smembers group2
1) "golang"
127.0.0.1:6379> sunion group1 group2
1) "java"
2) "golang"
将一个或多个集合的并集复制到一个新集合。
sunionstore destination key [key …]

127.0.0.1:6379> smembers group1
1) "java"
127.0.0.1:6379> smembers group2
1) "golang"
127.0.0.1:6379> sunionstore group3 group1 group2
(integer) 2
127.0.0.1:6379> smembers group3
1) "java"
2) "golang"

需要注意的是该命令只会多个集合的并集元素复制到一个新集合,被复制的元素不会从原始集合中删除。

查询多个集合的差异集。
sdiff key [key …]

127.0.0.1:6379> smembers group1
1) "java"
2) "golang"
127.0.0.1:6379> smembers group2
1) "golang"
127.0.0.1:6379> sdiff group1 group2
1) "java"
将多个集合的差异集复制到一个新集合。
sdiffstore destination key [key …]

127.0.0.1:6379> smembers group1
1) "java"
2) "golang"
127.0.0.1:6379> smembers group2
1) "golang"
127.0.0.1:6379> sdiffstore group3 group1 group2
(integer) 1
127.0.0.1:6379> smembers group3
1) "java"

标签:Set,04,0.1,数据类型,6379,127.0,集合,smembers
From: https://blog.csdn.net/weixin_42627385/article/details/142834138

相关文章

  • 浙江大学数据结构04-树7 二叉搜索树的操作集
    题目本题要求实现给定二叉搜索树的5种常用操作。函数接口定义:BinTreeInsert(BinTreeBST,ElementTypeX);BinTreeDelete(BinTreeBST,ElementTypeX);PositionFind(BinTreeBST,ElementTypeX);PositionFindMin(BinTreeBST);PositionFindMax(BinTr......
  • 20222304 2024-2025-1 《网络与系统攻防技术》实验一实验报告
    1.实验内容1.1本周学习内容1)反汇编反汇编是指将计算机程序的机器代码转换回其相应的汇编代码的过程。在计算机编程和逆向工程领域中,反汇编是一种常见的技术,用于理解和分析二进制程序的功能和内部结构。通常情况下,程序员编写的源代码会被编译器转换成机器码,这是计算机可以直接......
  • 42 C 语言 typedef:为基本数据类型、数组、指针、结构体、共用体起别名
    目录1 typedef介绍2 为某个基本类型起别名2.1为int类型起别名Integer2.2为unsignedchar类型起别名Byte2.3为基本类型一次起多个别名3 为结构体、共用体起别名3.1为结构体起别名3.1.1分开定义结构体和别名3.1.2与结构体定义一起使用typedef3.1.3为......
  • linux-vm-tools/ubuntu/24.04 /install.sh
    一、#!/bin/bash##ThisscriptisforUbuntu22.04JammyJellyfishtodownloadandinstallXRDP+XORGXRDPvia#source.##Majorthanksto:http://c-nergy.be/blog/?p=11336forthetips.#################################################################......
  • Open X-Embodiment: Robotic Learning Datasets and RT-X Models
    OpenX-Embodiment:RoboticLearningDatasetsandRT-XModels启发:在不同数据集上训练大规模、高容量模型以处理下游应用方面取得显著成功。是否能将所有数据整合在高容量机器人操作模型上使其有效适应新的机器人、任务、环境?贡献:提供了标准化数据格式和模型的数据集,收......
  • Windows-WMI 事件 ID 10或0x80041003——解决过程
    2024年10月8日国庆节后,第一天上班,实验室里一台PC机出现故障,Windows7系统,可以正常启动进入安全模式,但是正常启动无法加载桌面,可以看见鼠标,Ctrl+Alt+Del无法调出任务管理器。开始处理,进入安全模式,查看系统日志。发现一个错误如下(截取自[https://www.cnblogs.com/longware/p/78231......
  • [赛记] 多校A层冲刺NOIP2024模拟赛04
    这场ACCODERS忘交,结果最后想起来匆匆只交了T1,然后文件名还没改,所以爆零了。。。02表示法100pts高精度,不说了;点击查看代码#include<iostream>#include<cstdio>#include<string>#include<cmath>#include<algorithm>usingnamespacestd;stringp[605];stringan......
  • 算法训练营第十天|232.用栈实现队列 ,225. 用队列实现栈,20. 有效的括号,1047. 删除字符
    前置知识栈和队列都是以deque为缺省底部结构,实际上可以自己指定vector,deque,list都可以栈和队列都被归类为containeradapter(容器适配器)使用栈实现队列的操作:push(x)--将一个元素放入队列的尾部。pop()--从队列首部移除元素。peek()--返回队列首部的元素。empty()......
  • Redis 5大数据类型
    这里说的数据类型是value的数据类型,key的类型都是字符串。5种数据类型:redis字符串(String)redis列表(List)redis集合(Set)redis哈希表(Hash)redis有序集合(Zset)哪里去获取redis常用数据类型操作命令:http://redis.cn/commands.html2.1、redis键(key)keys*:查看当前库所有的keyexis......
  • Set 新增的实用方法
    有哪些新的Set方法呢?总共有7个新的方法,分别是:intersection() 计算两个Set的 交集union() 计算两个Set的 并集difference() 计算两个Set的 差集symmetricDifference() 取两个Set的 差集 的 并集isSubsetOf() 判断Set是否是另一个Set的 超集isD......