Redis 7.x 系列【9】数据类型之自动排重集合(Set)
有道无术,术尚可求,有术无道,止于术。
本系列Redis 版本 7.2.5
源码地址:https://gitee.com/pearl-organization/study-redis-demo
文章目录
- 1. 前言
- 2. 常用命令
- 2.1 SADD
- 2.2 SCARD
- 2.3 SISMEMBER
- 2.4 SREM
- 2.5 SSCAN
- 2.6 SDIFF
- 2.7 SUNION
- 2.8 SINTER
- 2.10 SRANDMEMBER
 
- 3. 应用场景
- 3.1 随机抽奖
- 3.2 共同关注
- 3.3 可能认识的人
- 3.4 点赞
 
 
1. 前言
Redis Set 数据类型是一种无序集合,它不允许重复的元素,可以类比 Java 中的 HashSet。
2. 常用命令
Set 相关所有命令:
| 命名 | 描述 | 
|---|---|
| SADD | 向集合添加一个或多个成员 | 
| SCARD | 获取集合的成员数 | 
| SDIFF | 返回给定所有集合的差集 | 
| SDIFFSTORE | 返回给定所有集合的差集并存储在 destination中 | 
| SINTER | 返回给定所有集合的交集 | 
| SINTERCARD | 类似于 SINTER,但它不返回结果集,而是只返回结果的基数。返回集合的基数,该基数将由所有给定集合的交集产生 | 
| SINTERSTORE | 返回给定所有集合的交集并存储在 destination中 | 
| SISMEMBER | 判断 member元素是否是集合key的成员 | 
| SMEMBERS | 获取一个集合的所有成员 | 
| SMISMEMBER | 从存储在 key处的集合值中返回一个随机元素 | 
| SMOVE | 将 member元素从source集合移动到destination集合 | 
| SPOP | 移除并返回集合中的一个随机元素 | 
| SRANDMEMBER | 返回集合中一个或多个随机数 | 
| SREM | 移除集合中一个或多个成员 | 
| SSCAN | 迭代集合中的元素 | 
| SUNION | 返回所有给定集合的并集 | 
| SUNIONSTORE | 所有给定集合的并集存储在 destination集合中 | 
2.1 SADD
SADD 命令将一个或多个成员元素加入到集合中,已经存在于集合的成员元素将被忽略。返回新成功添加到集合里元素的数量,不包括已经存在于集合中的元素。
注意事项:
- 假如集合 key不存在,则创建一个只包含被添加的元素作为成员的集合。
- 当集合 key不是集合类型时,返回一个错误。
- 在 Redis 2.4版本以前, 只接受单个成员值。
基本语法:
SADD key member [member ...]
示例:
redis> SADD myset "Hello"
(integer) 1
redis> SADD myset "World"
(integer) 1
redis> SADD myset "World"
(integer) 0
redis> SMEMBERS myset
1) "Hello"
2) "World"
2.2 SCARD
SCARD 命令返回集合中元素的数量,当集合 key 不存在时,返回 0 。
基本语法:
SCARD key
示例:
redis> SADD myset "Hello"
(integer) 1
redis> SADD myset "World"
(integer) 1
redis> SCARD myset
(integer) 2
2.3 SISMEMBER
SISMEMBER 命令返回存储在 key 中的集合的所有的成员。
注意事项:
- 不存在的集合被视为空集合
- 与运行带有一个参数 key的SINTER有同样的效果。
基本语法:
SMEMBERS key
示例:
redis> SADD myset "Hello"
(integer) 1
redis> SADD myset "World"
(integer) 1
redis> SMEMBERS myset
1) "Hello"
2) "World"
2.4 SREM
SREM 用于在集合中删除指定的元素,返回值为被删除元素个数,不含不存在的元素。
注意事项:
- 如果指定的元素不是集合成员则被忽略。
- 如果集合 key不存在则被视为一个空的集合,该命令返回0。
- 如果key的类型不是一个 Set,则返回ERR WRONGTYPE Operation against a key holding the wrong kind of value错误。
基本语法:
SREM key member [member ...]
示例:
redis> SADD myset "one"
(integer) 1
redis> SADD myset "two"
(integer) 1
redis> SADD myset "three"
(integer) 1
redis> SREM myset "one"
(integer) 1
redis> SREM myset "four"
(integer) 0
redis> SMEMBERS myset
1) "two"
2) "three"
2.5 SSCAN
SSCAN 命令用于遍历集合中键的元素,继承自 SCAN。
基本语法:
SSCAN key cursor [MATCH pattern] [COUNT count]
命令参数:
- cursor:游标。
- pattern:匹配的模式。
- count:指定从数据集里返回多少元素,默认值为- 10。
示例:
> SADD myset1 "Google"
(integer) 1
> SADD myset1 "Redis"
(integer) 1
> SADD myset1 "Taobao"
(integer) 1
> SSCAN myset1 0 match R*
1) "0"
2) 1) "Redis"
2.6 SDIFF
SDIFF 命令返回第一个集合与其他集合之间的差异,也可以认为说第一个集合中独有的元素。不存在的集合 key 将视为空集。
基本语法:
SDIFF key [key ...]
示例:
redis> SADD key1 "a"
(integer) 1
redis> SADD key1 "b"
(integer) 1
redis> SADD key1 "c"
(integer) 1
redis> SADD key2 "c"
(integer) 1
redis> SADD key2 "d"
(integer) 1
redis> SADD key2 "e"
(integer) 1
redis> SDIFF key1 key2
1) "a"
2) "b"
2.7 SUNION
SUNION 命令用于返回所有给定集合的并集。
基本语法:
SUNION key [key ...]
示例:
redis> SADD key1 "a"
(integer) 1
redis> SADD key1 "b"
(integer) 1
redis> SADD key1 "c"
(integer) 1
redis> SADD key2 "c"
(integer) 1
redis> SADD key2 "d"
(integer) 1
redis> SADD key2 "e"
(integer) 1
redis> SUNION key1 key2
1) "b"
2) "c"
3) "a"
4) "d"
5) "e"
2.8 SINTER
SINTER 返回所有给定集合的成员交集。
基本语法:
SINTER key [key ...]
示例:
redis> SADD key1 "a"
(integer) 1
redis> SADD key1 "b"
(integer) 1
redis> SADD key1 "c"
(integer) 1
redis> SADD key2 "c"
(integer) 1
redis> SADD key2 "d"
(integer) 1
redis> SADD key2 "e"
(integer) 1
redis> SINTER key1 key2
1) "c"
2.10 SRANDMEMBER
SRANDMEMBER 命令随机返回集合 key 中的一个或多个随机元素。
注意事项:
- 如果 key不存在则返回nil。
- 使用 count参数,则返回一个随机的元素数组,如果key不存在则返回一个空的数组。
基本语法:
SRANDMEMBER key [count]
示例:
redis> SADD myset one two three
(integer) 3
redis> SRANDMEMBER myset
"two"
redis> SRANDMEMBER myset 2
1) "two"
2) "three"
redis> SRANDMEMBER myset -5
1) "one"
2) "three"
3) "two"
4) "one"
5) "two"
3. 应用场景
Set 数据类型除了普通的存储功能外,还提供了交集、并集、差集操作,可用于以下场景:
- 抽奖系统、随机点名
- 共同关注、共同粉丝、共同喜好、共同好友等
- 数据不能重复的场景,例如点赞
- 可能认识的人
3.1 随机抽奖

用户点击参与抽奖时,添加到抽奖集合中:
localhost:0>SADD join_user_set 1
"1"
localhost:0>SADD join_user_set 2
"1"
localhost:0>SADD join_user_set 3
"1"
查看抽奖总参与人数:
localhost:0>SCARD join_user_set
"3"
随机抽取两人(不删除元素):
localhost:0>SRANDMEMBER key 2
随机抽取两人(删除元素):
localhost:0>SRANDMEMBER join_user_set 2
3.2 共同关注

 我的关注:
localhost:0>SADD my_follow_set u1 u2 u3 
"3"
贾乃亮的关注:
localhost:0>SADD jianailiang_follow_set u2 u3 u4
"3"
查看共同关注:
localhost:0>SINTER my_follow_set  jianailiang_follow_set1)  "u2"2)  "u3"
3.3 可能认识的人
在社交平台中,添加好友时,系统会推荐可能认识的人,例如抖音:

 例如快手:
 
一般有以下规则:
- 手机号匹配:社交平台都要求使用手机号注册,在读取你的通讯录后,会根据通讯录手机号查询用户
- 附近的人:通过定位权限获取定理位置,并筛选出附近的人
- 好友差集:计算用户之间的共同好友,如果共同好友超过一定数量,说明两个人是同一个圈子的人,例如同一个班级,两个学生之间的共同好友肯定很多。然后通过计算两人好友之间的差集,进行推荐
- 标签:例如通过相同的兴趣爱好进行推荐
例如,当前我的好友列表:
localhost:0>SADD my_friend_set u1 u2 u3 u5 
"4"
我的好友 u1 的好友列表:
localhost:0>SADD u1_frieng_set  u1 u2 u3 u6
"4"
我和 u1 的共同好友:
localhost:0>SINTER my_friend_set u1_frieng_set1)  "u1"2)  "u2"3)  "u3"
将我有但是 u1 没有的好友推荐给 u1 :
localhost:0>SDIFF u1_frieng_set my_friend_set1)  "u5"
将 u1 有但是我没有的好友推荐给我:
localhost:0>SDIFF  my_friend_set u1_frieng_set1)  "u6"
3.4 点赞

 新增点赞用户:
localhost:0>SADD msg_1 u1 u2
"2"
取消点赞:
localhost:0>SREM msg_1 u1
"1"
查看所有点赞用户:
localhost:0>SMEMBERS msg_11)  "u2"
查看点赞总数:
localhost:0>SCARD msg_1
"1"
相关文章:
 
Redis 7.x 系列【9】数据类型之自动排重集合(Set)
有道无术,术尚可求,有术无道,止于术。 本系列Redis 版本 7.2.5 源码地址:https://gitee.com/pearl-organization/study-redis-demo 文章目录 1. 前言2. 常用命令2.1 SADD2.2 SCARD2.3 SISMEMBER2.4 SREM2.5 SSCAN2.6 SDIFF2.7 SU…...
【LeetCode】每日一题:反转链表
题解思路 循环的方法需要注意prev应该是None开始,然后到结束的时候prev是tail,递归的思路很难绕过弯来,主要在于很难想清楚为什么可以返回尾节点,需要多做递归题,以及递归过程中,可以不使用尾节点来找当前…...
使用Spring Boot创建自定义Starter
使用Spring Boot创建自定义Starter 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿!今天我们将探讨如何使用Spring Boot创建自定义Starter,来简化项目…...
cmd设置编码为utf8
文章目录 临时设置永久设置(通过注册表) cmd命令乱码,解决方案比较简单。 输入chcp, 如果返回的是936,通常是GBK或CP936。 如果返回的是65001,表示是UTF-8。 临时设置 chcp 65001 # 设置 chcp # 查看 永久设置(通过注册表) 打…...
 
一次关于k8s的node节点NotReady的故障排查
master现象 分析 kubectl get nodes -A 看了下pod的状态,好多CrashLoopBackOff kubectl get nodes -o wide 定位到那个具体node的IP地址,登录对应的IP去查看为什么会这样 node节点 journalctl -xe -f -u kubelet 查看此节点的 kubelet 服务ÿ…...
Java变量与标识符
一、关键字(Keyboard) 定义:被Java语言赋予了特殊含义,用做专门用途的字符串(或单词) 特点:全部关键字都是小写字母 官方地址: https://docs.oracle.com/javase/tutorial/java/nut…...
AWS无服务器 应用程序开发—第十七章 AWS用户池案例
在AWS Cognito用户池中,用户属性可以根据应用程序的需求进行配置和管理。以下是一般情况下用户属性的一些常见设置: 必须的属性: 用户名(Username):通常用作用户的唯一标识符。 密码(Password…...
 
java中的枚举
第1部分:引言 枚举在Java中的重要性 枚举在Java中扮演着至关重要的角色,它不仅提高了代码的可读性和可维护性,还增强了类型安全。枚举的使用可以避免使用魔法数字或散列常量,这些在代码中通常难以理解和维护。通过枚举ÿ…...
各种开发语言运行时占用内存情况比较
随着科技的发展,编程语言种类繁多,不同的编程语言在运行时的内存占用情况各不相同。了解这些差异对于开发者选择合适的编程语言尤为重要。本文将讨论几种主流编程语言在运行时的内存占用情况,包括C、C、Java、Python和Go等。 1. C语言 内存…...
【基础知识10】label与input标签
label标签说明 HTML元素表示用户界面中某个元素的说明 将一个和一个元素相关联主要有这些优点: 标签文本不仅与其相应的文本输入元素在视觉上相关联,程序中也是如此。这意味着,当用户聚焦到这个表单输入元素时,屏幕阅读器可以读…...
【SDV让汽车架构“和而不同”】
昔日以“排气管数量”和“发动机动力”为骄傲的荣耀已然成为过往。在这个崭新的时代,特斯拉、理想、蔚来、小鹏、零跑等新兴的汽车制造商纷纷推出了搭载可交互大屏、实现万物互联、软件功能持续更新的新车型,它们被誉为“车轮上的智能手机”。同时&#…...
面试经验分享 | 驻场安全服务工程师面试
所面试的公司:某安全厂商 所在城市:浙江宁波 面试职位:驻场安全服务工程师 面试官的问题: 1、信息收集如何处理子域名爆破的泛解析问题? 泛域名解析是:*.域名解析到同一IP。域名解析是:子域…...
 
SpringBoot 学习笔记
文章目录 SpringBoot1 SpringBoot 的纯注解配置(了解)1.1 环境搭建1.1.1 jdbc配置1.1.2 mybatis配置1.1.3 transactional配置1.1.4 service配置1.1.5 springmvc配置1.1.6 servlet配置1.1.7 存在的问题 1.2 新注解说明1.2.1 Configuration1.2.2 Component…...
 
Android 13 为应用创建快捷方式
参考 developer.android.google.cn 创建快捷方式 来自官网的说明: 静态快捷方式 :最适合在用户与应用互动的整个生命周期内使用一致结构链接到内容的应用。由于大多数启动器一次仅显示四个快捷方式,因此静态快捷方式有助于以一致的方式执行…...
 
PTA—C语言期末复习(选择题)
1. 按照标识符的要求,(A)不能组成标识符。 A.连接符 B.下划线 C.大小写字母 D.数字字符 在大多数编程语言中,标识符通常由字母(包括大写和小写)、数字和下划线组成,但不能以数字开头,…...
 
基于STM32的智能家用空气净化系统
目录 引言环境准备智能家用空气净化系统基础代码实现:实现智能家用空气净化系统 4.1 数据采集模块4.2 数据处理与分析4.3 控制系统实现4.4 用户界面与数据可视化应用场景:空气净化管理与优化问题解决方案与优化收尾与总结 1. 引言 智能家用空气净化系…...
 
计算机图形学入门18:阴影映射
1.前言 前面几篇关于光栅化的文章中介绍了如何计算物体表面的光照,但是着色并不会进行阴影的计算,阴影需要单独进行处理,目前最常用的阴影计算技术之一就是Shadow Mapping技术,也就是俗称的阴影映射技术。 2.阴影映射 Shadow Map…...
电机应用相关名词介绍
1.电机转速 定义:电机转速指电机工作时旋转的速度,是衡量电机性能的重要指标之一。 单位: 每分钟转数(RPM):即Revolutions Per Minute,表示电机每分钟旋转的圈数。 每秒转数(RPS…...
 
哈尔滨等保测评解读
哈尔滨的信息系统安全等级保护测评(简称“等保测评”)是中国网络安全法规的一部分,旨在确保关键信息基础设施和其他重要信息系统的安全。下面是对哈尔滨等保测评的解读: 测评目的 等保测评的主要目的是评估信息系统是否满足国家规…...
python接口自动化的脚本
使用Requests库进行GET请求 Requests是Python中最常用的HTTP库,用于发送HTTP请求。下面是一个简单的GET请求示例,用于从API获取数据。 import requests url = "https://api.example.com/data" response = requests.get(url) if response.status_code == 200:prin…...
 
【Axure高保真原型】引导弹窗
今天和大家中分享引导弹窗的原型模板,载入页面后,会显示引导弹窗,适用于引导用户使用页面,点击完成后,会显示下一个引导弹窗,直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...
Linux链表操作全解析
Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表?1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...
C++:std::is_convertible
C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以? 在 Golang 的面试中,map 类型的使用是一个常见的考点,其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...
 
VB.net复制Ntag213卡写入UID
本示例使用的发卡器:https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...
 
【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器
一.自适应梯度算法Adagrad概述 Adagrad(Adaptive Gradient Algorithm)是一种自适应学习率的优化算法,由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率,适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…...
 
UE5 学习系列(三)创建和移动物体
这篇博客是该系列的第三篇,是在之前两篇博客的基础上展开,主要介绍如何在操作界面中创建和拖动物体,这篇博客跟随的视频链接如下: B 站视频:s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...
 
为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?
在建筑行业,项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升,传统的管理模式已经难以满足现代工程的需求。过去,许多企业依赖手工记录、口头沟通和分散的信息管理,导致效率低下、成本失控、风险频发。例如&#…...
 
【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)
🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...
Android第十三次面试总结(四大 组件基础)
Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成,用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机: onCreate() 调用时机:Activity 首次创建时调用。…...
