探索 Redis Set:命令、编码与应用实践

news2024/11/15 1:41:41

set 类型

    • 一 . 常见命令
      • 1.1 sadd、smembers
      • 1.2 sismember
      • 1.3 spop、srandmember
      • 1.4 smove
      • 1.5 srem
      • 1.6 集合间操作
        • 交集 : sinter、sinterstore
        • 并集 : sunion、sunionstore
        • 差集 : sdiff、sdiffstore
      • 小结
    • 二 . 内部编码
    • 6.3 应用场景
      • 6.3.1 使用 Set 来保存用户的标签
      • 6.3.2 使用 Set 计算用户之间的共同好友
      • 6.3.3 统计 UV

Hello , 大家好 , 这个专栏给大家带来的是 Redis 系列 ! 本篇文章给大家讲解的是 Redis 中 set 类型的相关内容 , 我们依然会从常见命令、底层编码方式、应用场景三方面给大家介绍 .

在这里插入图片描述

本专栏旨在为初学者提供一个全面的 Redis 学习路径,从基础概念到实际应用,帮助读者快速掌握 Redis 的使用和管理技巧。通过本专栏的学习,能够构建坚实的 Redis 知识基础,并能够在实际学习以及工作中灵活运用 Redis 解决问题 .
专栏地址 : Redis 入门实践


正文开始

set 表示集合 , 就是将一些有关联的数据放到一起 , 那他与 list 还是有一定区别的

  1. 集合中的元素是无序的 , 也就是插入元素的顺序与实际存储的元素顺序不一致 , 但是集合是同一个集合

比如 :

  • 对于 list 来说 , [1 , 2 , 3] 和 [3 , 2 , 1] 是两个不同的 list
  • 对于 set 来说 , [1 , 2 , 3] 和 [3 , 2 , 1] 是两个相同的 set
  1. 集合中的元素是不能重复的 , 也就是元素必须唯一
  2. 和 list 相似 , 集合中的每个元素也需要是 string 类型 , 但是我们仍然可以使用 JSON 这样的格式来去存储一些数据到 string 中

一 . 常见命令

1.1 sadd、smembers

sadd 是将一个或者多个元素添加到集合中 , 要求添加的元素不能重复
语法 : sadd key member1 [member2 …]

与 hash 类型中将 value 叫做 field 类似 , set 中叫做 member

返回值 : 本次操作添加成功的元素的个数
时间复杂度 : O(N) , N 表示要添加的元素个数 . 如果元素个数不多 , 我们可以认为是 O(1)

smembers 可以获取到集合中所有的元素
语法 : smembers key
时间复杂度 : O(1) , N 表示集合中的元素个数 . 如果元素个数不多 , 我们可以认为是 O(1)

那我们就来看一下示例

127.0.0.1:6379> sadd key 1 2 3 4 # 向集合中添加不重复的元素
(integer) 4 # 返回值代表添加成功的个数
127.0.0.1:6379> type key # 获取 key 的类型
set # 此时显示 key 的类型是 set
127.0.0.1:6379> sadd key 5 5 5 5 5 # 向集合中添加重复元素
(integer) 1 # 只会添加成功一条数据 
127.0.0.1:6379> smembers key # 获取集合中的所有元素
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"

1.2 sismember

sismember 用来判断某个元素是否存在于 set 中
语法 : sismember key member

127.0.0.1:6379> smembers key
1) "1"
2) "2"
3) "3" # 3 存在于集合中
4) "4"
5) "5"
127.0.0.1:6379> sismember key 3 # 判断 3 是否存在于集合中
(integer) 1 # 返回值为 1 代表存在
127.0.0.1:6379> sismember key 999 # 判断 999 是否存在于集合中
(integer) 0 # 返回值为 0 代表不存在

1.3 spop、srandmember

pop 一般表示从末尾删除一个元素 , 但是集合中的元素是无序的 , 那就不知道末尾元素是谁 , 所以 spop 就只能随机删除一个元素
语法 : spop key [count]

count 不写的时候就表示随机删除一个

127.0.0.1:6379> sadd key 1 2 3 4 # 向集合中添加不重复的元素
(integer) 4
127.0.0.1:6379> spop key # 随机删除一个元素
"3" # 返回值代表被删除的元素
127.0.0.1:6379> spop key
"2"
127.0.0.1:6379> spop key
"4"
127.0.0.1:6379> spop key
"1"
# 构造一样的集合, 然后重新删除
127.0.0.1:6379> sadd key 1 2 3 4
(integer) 4
127.0.0.1:6379> spop key # 这次先删除的就是 "1" 了
"1"
127.0.0.1:6379> spop key
"2"
127.0.0.1:6379> spop key
"3"
127.0.0.1:6379> spop key
"4"
127.0.0.1:6379> spop key 2 # 随机删除两个元素
1) "1"
2) "2"

那在官方文档中 , 官方也特意声明了 , 弹出的元素就是随机的

https://redis.io/commands/spop/

image.png
然后还提到了一段话
image.png
这段话的意思就是 spop 类似于 srandmember , srandmember 的作用是随机返回一个元素而不删除

我们可以类似 pop() 和 peek() 来理解
pop() <-> spop() , peek() <-> srandmember

那我们也来看一下 srandmember 的用法
语法 : srandmember key [count]

127.0.0.1:6379> smembers key
1) "1"
2) "2"
3) "3"
4) "4"
127.0.0.1:6379> srandmember key # 随机获取一个元素但不删除
"1"
127.0.0.1:6379> srandmember key
"3"
127.0.0.1:6379> srandmember key 3 # 随机获取 count 个元素但不删除
1) "4"
2) "2"
3) "1"

1.4 smove

smove 的作用就是将一个元素从源 set 中取出来存储到目标 set 中
语法 : smove source destination member

也就是把 member 从 source 上删除 , 再插入到 destination 中

时间复杂度 : O(1)

127.0.0.1:6379> sadd key1 1 2 3 4 # 向集合中添加 1 2 3 4
(integer) 4
127.0.0.1:6379> sadd key2 5 6 7 8 # 向集合中添加 5 6 7 8
(integer) 4
127.0.0.1:6379> smove key1 key2 1 # 将 key1 中的 1 移动到 key2 中
(integer) 1
127.0.0.1:6379> smembers key1 # 此时 key1 中的 1 就不见了
1) "2"
2) "3"
3) "4"
127.0.0.1:6379> smembers key2
1) "1" # 原来是 key1 中的 1 移动到 key2 中了
2) "5"
3) "6"
4) "7"
5) "8"

那如果我给 key1 里面再添加一个 1 , 然后移动到 key2 中 , 会是什么样的效果呢 ?

127.0.0.1:6379> sadd key1 1 # 重新向 key1 中添加 1 
(integer) 1
127.0.0.1:6379> smove key1 key2 1 # 将 1 重新从 key1 中移动到 key2
(integer) 1 # 返回值表示插入成功
127.0.0.1:6379> smembers key1 # 此时 key1 中的 1 又不见了
1) "2"
2) "3"
3) "4"
127.0.0.1:6379> smembers key2
1) "1" # 1 就被移动到了 key2 中
2) "5"
3) "6"
4) "7"
5) "8"

那针对上面的这种情况 , smove 并不会认为这会出错 , 他还是会按照 “先删除 , 再插入” 的策略来执行

那如果我们要移动的元素在 source 中不存在呢 ?

127.0.0.1:6379> smove key1 key2 999 # key1 中并不存在 999
(integer) 0 # 0 表示移动失败

1.5 srem

srem 的作用是用来删除集合中指定的一个或者多个元素
语法 : srem key member1 [member2 …]
返回值 : 删除成功的元素个数

127.0.0.1:6379> sadd key 1 2 3 4 # 向集合中添加不重复的元素
(integer) 4
127.0.0.1:6379> srem key 1 # 删除集合中的 1
(integer) 1 # 返回值代表删除成功的个数
127.0.0.1:6379> srem key 2 3  # 删除集合中的多个元素
(integer) 2

1.6 集合间操作

集合间操作指的就是交集、并集、差集
交集 (inter) : 两个集合共有的元素
并集 (union) : 把多个集合中的数据都集中放在一起 , 如果元素有重复 , 也最终只保留一份
差集 (diff) : A 和 B 做差集 , 就是找出哪些元素 , 在 A 中存在 , 在 B 中不存在
举个例子 : A = [1 , 2 , 3 , 4] , B = [3 , 4 , 5 , 6]
交集 : [3 , 4]
并集 : [1 , 2 , 3 , 4 , 5 , 6]
差集 : A 和 B 做差集 -> [1 , 2] , B 和 A 做差集 -> [5 , 6]

交集 : sinter、sinterstore

sinter 用来获取给定集合中共有的元素
语法 : sinter key1 [key2 …]

此处 , 每个 key 都对应一个集合

返回值 : 共有的元素
时间复杂度 : O(N * M) , N 指的是最小的集合元素个数 , M 指的是最大的集合元素个数

127.0.0.1:6379> sadd key1 1 2 3 4
(integer) 4
127.0.0.1:6379> sadd key2 3 4 5 6
(integer) 4
127.0.0.1:6379> sinter key1 key2 # 获取重复元素
1) "3"
2) "4"

那 Redis 还提供了一个命令 , 也是用来求交集的 , 叫做 sinterstore
语法 : sinterstore destination key1 [key2 …]
它的作用不是直接返回交集 , 而是直接将交集保存到 destination 中
返回值代表交集的个数 , 那要想获取到交集的内容 , 我们就可以直接去查看 destination 里面的内容

127.0.0.1:6379> sinterstore key3 key1 key2 # 将 key1 和 key2 的交集保存到 key3 中
(integer) 2
127.0.0.1:6379> smembers key3 # 想要查询交集是什么就需要通过 smembers 单独查看
1) "3"
2) "4"

并集 : sunion、sunionstore

语法 : sunion key1 [key2 …]
返回值 : 并集的结果数据
时间复杂度 : O(N) , N 指的就是总的元素个数

127.0.0.1:6379> sunion key1 key2 # 求 key1 和 key2 的并集
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
6) "6"

那并集同样给出了另一个命令 , 叫做 sunionstore
语法 : sunionstore destination key1 [key2 …]
它的作用就是将并集的结果存储到 destination 这个集合中
返回值 : 并集的元素个数

127.0.0.1:6379> sunionstore key4 key1 key2 # 将 key1 key2 的并集保存到 key4 中
(integer) 6
127.0.0.1:6379> smembers key4
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
6) "6"

差集 : sdiff、sdiffstore

语法 : sdiff key1 [key2 …]
返回值 : 差集的结果
时间复杂度 : O(N) , N 指的是所有所有元素的长度

127.0.0.1:6379> sdiff key1 key2 # 求 key1 中存在的, 而在 key2 不存在的
1) "1"
2) "2"
127.0.0.1:6379> sdiff key2 key1 # 求 key2 中存在的, 而在 key1 不存在的
1) "5"
2) "6"

同样 , 他也提供了一个额外的版本 : sdiffstore , 他也是将差集保存到 destination 集合中
语法 : sdiffstore destination key1 [key2 …]

127.0.0.1:6379> sdiffstore key5 key1 key2 # 将 key1 中存在的而 key2 中不存在的元素保存到 key5 中
(integer) 2
127.0.0.1:6379> smembers key5
1) "1"
2) "2"
127.0.0.1:6379> sdiffstore key6 key2 key1 # 将 key2 中存在的而 key1 中不存在的元素保存到 key6 中
(integer) 2
127.0.0.1:6379> smembers key6
1) "5"
2) "6"

小结

在这里插入图片描述

二 . 内部编码

集合中的内部编码有两种 :

  • intset (整数集合)
  • hashtable (哈希表)

其中 , intset 也是为了节省空间 , 做出的特定优化 . 当集合中的元素均为整数并且元素个数也不是很多的时候 , 内部就使用 intset 来去存储 .

127.0.0.1:6379> sadd key 1 2 3 4 # 集合元素都为整数 && 元素个数比较少 -> intset
(integer) 4
127.0.0.1:6379> object encoding key
"intset"
127.0.0.1:6379> sadd key HelloWorld # 向集合中添加一个字符串 , 数据类型就变为了 hashtable
(integer) 1
127.0.0.1:6379> object encoding key
"hashtable"

6.3 应用场景

6.3.1 使用 Set 来保存用户的标签

什么叫做标签呢 ?
现在许多产品都有自己的用户画像 , 他们通过一些手段来去分析出你的特征以及喜好 , 再去投其所好 . (也就是大家所说的大数据推送)
那这个用户画像就是我们所谓的标签 .
那这些标签就是一些简短的字符串 , 我们就可以把这些标签添加到 Redis 的 Set 中
那使用 Set 来去存储标签 , 依靠的是 Set 的唯一性和无序性 , 更重要的因素是 Set 非常方便计算交集 , 很方便的就可以找到两个用户的公共标签 . 那基于一些公共标签就可以衍生出一些用户群体 , 方便进行用户之间的交互 .

6.3.2 使用 Set 计算用户之间的共同好友

也是基于集合求交集这样的操作来去计算用户之间的共同好友 .
比如 : QQ 中的共同好友
那还可以根据交集来去进行一些好友推荐 .
比如 : 抖音就会推送你的好友之间共同关注的博主

6.3.3 统计 UV

那什么是 UV 呢 ?
在互联网大厂中 , 主要通过 PV 和 UV 来去衡量用户量或者用户规模

  1. PV (page view) : 每次打开一个页面 (每次访问服务器) 都会产生一个 PV
  2. UV (user view) : 每个用户打开一个页面 (每次访问服务器) 都会产生一个 UV . 但是如果同一个用户多次访问 , UV 就不会增加

那 UV 就需要按照用户来进行去重 , 就可以通过 set 中进行去重


今天的文章就到此为止啦 , 有帮助的话还请一键三连~
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2109108.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

android kotlin基础复习 enum

1、kotlin中&#xff0c;关键字enum来定义枚举类型。枚举类型可以包含多个枚举常量&#xff0c;并且每个枚举常量可以有自己的属性和方法。 2、测试代码&#xff1a; enum class Color{RED,YELLOW,BLACK,GOLD,BLUE,GREEN,WHITE }inline fun <reified T : Enum<T>>…

Qt工程实践_06_Qt MSVC2O17编译器下的程序添加VS2017生成的动态链接库方法

文章目录 1. 利用VS2017生成动态链接库1.1 创建C++空项目1.2 添加.h和.cpp内容:添加了一个减法运算1.3 设置动态链接库目标计算机类型1.4 设置项目属性为动态库1.5 生成项目,复制需要的文件2. Qt程序使用VS2017生成的动态链接库方法2.1 创建Widget程序2.2 链接动态库文件2.2.…

蚂蚁SEO|AI养站程序是什么|蚂蚁蜘蛛池

《AI 养站程序&#xff1a;开启网站运营新未来》 在当今数字化时代&#xff0c;网站运营的重要性日益凸显。而 AI 养站程序的出现&#xff0c;为网站运营者带来了全新的机遇与挑战。 一、什么是 AI 养站程序 AI 养站程序是利用人工智能技术&#xff0c;对网站进行自动化管理和优…

MacBook air pro验机流程

由于苹果电脑价格相对较高&#xff0c;用户在网上购置之后&#xff0c;最好对机器要进行一下验机&#xff0c;以确保自己所购置的机器为原厂正品一手机。此外&#xff0c;在网上购置时&#xff0c;注意开相应的发票&#xff0c;方便后续的保修和换机等其他流程。 本文主要是介绍…

中小学生学籍照片(390×480蓝底)手机拍照制作流程说明

近期各地中小学陆续开学&#xff0c;幼升小及小升初一年级新生一般要在十月份之前完成学籍档案采集&#xff0c;其中就包括了新生学籍证件照的采集&#xff08;即学籍照片&#xff09;&#xff0c;部分中部省份使用的学籍照片像素尺寸为390&#xff08;宽&#xff09;480&#…

[C#学习笔记]注释

官方文档&#xff1a;Documentation comments - C# language specification | Microsoft Learn 一、常用标记总结 1.1 将文本设置为代码风格的字体&#xff1a;<c> 1.2 源代码或程序输出:<code> 1.3 异常指示:<exception> 1.4 段落 <para> 1.5 换行&…

Vue+Element多套主题切换

Vue3.x Element Plus与Vue2.x Element ui多套主题的切换方案 demo地址 VueElement更换主题: Vue Element项目&#xff0c;更换几套主题的方案 思路很简单&#xff0c;就是写好每套样式&#xff0c;写个切换功能&#xff0c;切换主题即可 具体实现方案&#xff1a; 准备多…

物联网技术推动灌区智能化管理

物联网技术&#xff0c;作为信息技术革命的重要组成部分&#xff0c;正深刻地改变着传统行业的运作模式&#xff0c;其中在农业灌溉领域的应用尤为显著&#xff0c;为灌区的智能化管理开辟了新径。这一技术通过将传感器、智能网关、大数据分析与云平台紧密融合&#xff0c;实现…

What is Node.JS and its Pros and Cons

What is Node.JS and its Pros and Cons JavaScript is a client-side development tool. Node.js is a server-side development tool. And it’s only a runtime environment based on Chrome V8 so we don’t write some code in Node.js. Pros: JavaScript on a server …

TypeScript 在 Vue.js 中的应用指南

在前端开发中&#xff0c;TypeScript 和 Vue.js 的组合越来越受到青睐。TypeScript 的强类型系统和 Vue.js 的组件化架构相得益彰&#xff0c;可以帮助你编写更可靠和易维护的代码。如果你已经掌握了 TypeScript 的基本语法&#xff0c;但不太确定怎么将它与 Vue.js 配合使用&a…

opencv 实现两个图片的拼接去重功能

基础知识介绍 cv::Mat 是OpenCV库中用来表示图像和矩阵数据的核心类之一。它是一个多维数组&#xff0c;可以存储图像像素数据、矩阵数据以及其他类型的数据。以下是关于 cv::Mat 类的一些详细解释&#xff1a; 构造函数&#xff1a;cv::Mat 类有多个构造函数&#xff0c;可以用…

JavaWeb(后端)

Maven Apache Maven 是一个项目管理和构建工具&#xff0c;它基于项目对象模型(POM)的概念&#xff0c;通过一小段描述信息来管理项目的构建。 Maven的作用 依赖管理&#xff1a;方便快捷的管理项目依赖的资源(jar包)&#xff0c;避免版本冲突问题。 统一项目结构&#xff…

Leetcode22括号生成(java实现)

今天分享的题目是Leetcode22括号生成&#xff0c;具体的题目描述如下&#xff1a; 本道题我们使用的解法是回溯。 解题思路&#xff1a; 我们主要是对括号出现的可能性进行一个收集。 我们以n2举例子&#xff0c;如下图 如果想要合法&#xff0c;那么一定是左括号开始&#…

golang学习笔记05——golang协程池,怎么实现协程池?

推荐学习文档 golang实战大纲golang优秀开发常用开源库汇总golang学习笔记01——基本数据类型golang学习笔记02——gin框架及基本原理golang学习笔记03——gin框架的核心数据结构golang学习笔记04——如何真正写好Golang代码&#xff1f; 协程池是一种用于高效处理任务的机制&…

Claude的小白入门指南

要想快速上手Claude AI&#xff0c;其实并没有那么复杂。作为新一代的AI助手&#xff0c;Claude致力于为用户提供高效、无害、透明的交互体验。这篇入门指南将从Claude AI的特点、主要功能和如何实际操作等几个方面为大家做一个详细的介绍。 Claude AI是什么&#xff1f; Claud…

ssh之登录服务器后,自动进入目录(四十七)

简介&#xff1a; CSDN博客专家、《Android系统多媒体进阶实战》一书作者 新书发布&#xff1a;《Android系统多媒体进阶实战》&#x1f680; 优质专栏&#xff1a; Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a; 多媒体系统工程师系列【…

0成本实现.NET Web API 8.0项目内网映射

1.背景 最近在学习CICD&#xff0c;里面会有用到内网映射的使用场景。为了加深对内网映射实操的记忆。我实操了下基于.Net 8.0的内网映射&#xff0c;并支持互联网访问。本文主要介绍了在win11下安装路由侠&#xff0c;并将.net 8.0发布到win11&#xff0c;项目运行、路由侠配…

【MiniMax】中国文生视频模型再添一员大将!

千呼万唤始出来&#xff01; 一直以低调示人的 MiniMax 终于举办了他们从成立以来的第一次公开伙伴日活动。 本次伙伴日上&#xff0c;MiniMax发布了 视频模型abab-video-1、音乐模型abab-music-1&#xff0c;更新 语音模型abab-speech-1。此外&#xff0c;MiniMax将在未来数周…

Windows10彻底关闭自带的防病毒功能

第1步:右下角,点开“windows安全中心” 第2步:切换到“病毒和威胁防护”,打开“管理设置” 第3步:将“实时防护”、“云提供的防护”、“自动提交样本”和“篡改防护”四个选项开关关闭。 第4步:按下win键+R键->打开“运行”窗口->输入命令“gpedit.msc”->“确…

2024国赛数学建模-模拟火算法(MATLAB 实现)

模拟退火算法 1.1 算法原理 模拟退火算法的基本思想是从一给定解开始 ,从邻域 中随机产生另一个解 ,接受 Metropolis准则允许目标函数在 有限范围内变坏 ,它由一控制参数 t决定 ,其作用类似于物 理过程中的温度 T,对于控制参数的每一取值 ,算法持续进 行“产生 —判断 —接受…