【Redis】set 类型

set

  • 一. set 类型介绍
  • 二. set 命令
    • sadd、smembers、sismember
    • scard、spop、srandmember
    • smove、srem
    • 集合间操作
      • 交集:sinter、sinterstore
      • 并集:sunion、sunionstore
      • 差集:sdiff、sdiffstore
  • 三. set 命令小结
  • 四. set 内部编码方式
  • 五. set 使用场景
    • 用户标签
    • 共同好友
    • 统计 UV

一. set 类型介绍

  • 集合就是把一些有关联的数据放到一起,保存多个字符串类型的元素的 (可以使用 JSON 这样的格式,让 string 存储结构化数据),但和列表类型不同的是:
    • 元素之间是无序的。
      • 此处说的无序和之前 list 说的有序是对应的。
      • 有序:顺序很重要,变换一下顺序,就是不同的列表。
      • 无序:顺序不重要,变换一下顺序,还是那个集合。
      • list:[1, 2, 3] 和 [2, 1, 3] 是不同的 list
      • set:[1, 2, 3] 和 [2, 1, 3] 是相同的 set
    • 元素不允许重复。
    • 一个集合中最多可以存储 2^32 - 1 个元素。
  • Redis 除了支持集合内的增删查改操作,同时还支持多个集合取交集、并集、差集,合理地使用好集合类型,能在实际开发中解决很多问题。

集合类型:

在这里插入图片描述

二. set 命令

在 set 中的元素叫做 member,就像在 hash 中的元素叫做 field、value 类似。

sadd、smembers、sismember

  • sadd:添加⼀/多个元素到 set 中。注意:重复的元素无法添加到集合中。
  • 语法:sadd key member [member ...]
  • 时间复杂度:添加一个元素是 O(1),添加 N 个元素是 O(N)
  • 返回值:本次添加成功的元素个数。

在这里插入图片描述

  • smembers:获取一个 set 中的所有元素。注意:元素间的顺序是无序的。
  • 语法:smembers key
  • 时间复杂度:O(N),N 是集合中元素的个数。
  • 返回值:所有元素的列表。

在这里插入图片描述

  • sismember:判断一个元素在不在 set 中。
  • 语法:sismember key member
  • 时间复杂度:O(1)
  • 返回值:元素在 set 中,返回 1;元素不在 set 中或者 key 不存在,返回 0

在这里插入图片描述

scard、spop、srandmember

  • scard:获取一个 set 的基数 (cardinality),即 set 中的元素个数。
  • 语法:scard key
  • 时间复杂度:O(1)
  • 返回值:set 内的元素个数。

在这里插入图片描述

  • spop:从 set 中删除并返回一个或者多个元素。注意:由于 set 内的元素是无序的,所以取出哪个元素实际是未定义行为,即可以看作随机的。
  • 语法:spop key [count]
  • 时间复杂度:O(N),N 是 count 的个数。
  • 返回值:取出的元素。

在这里插入图片描述

  • srandmember:从 set 中返回一个或者多个随机的元素。
  • 语法:srandmember key [count]
  • 时间复杂度:O(N),N 是 count 的个数。
  • 返回值:取出的元素。

在这里插入图片描述

在 Redis 源码中,针对 spop 实现的时候,就采取了 “生成随机数” srandmember 的方式。

smove、srem

  • smove:将一个元素从源 set 取出并放入目标 set 中。
  • 语法:smove source destination member
  • 时间复杂度:O(1)
  • 返回值:移动成功时,返回 1;移动失败时,返回 0

在这里插入图片描述

如果我给 key1 里再添加一个 1,再次把这个 1 移动给 key2,此时 smove 不会视为出错,也会按照 删除-插入 进行执行。

在这里插入图片描述

  • srem:将指定的元素从 set 中删除
  • 语法:srem key member [member ...]
  • 时间复杂度:O(N),N 是要删除的元素个数。
  • 返回值:删除成功的元素个数。

在这里插入图片描述

不同操作的返回值,含义差别还是挺大的,需要用的时候,多翻文档即可。

集合间操作

  • 交集 (inter):最终结果同时出现在两个集合中。
  • 并集 (union):把多个集合中的数据都集中放在一起,如果元素有重复,也最终只保留一份。
  • 差集 (diff):A 和 B 做差集,就是找出 A 中存在,但是 B 中不存在的元素。

在这里插入图片描述

交集:sinter、sinterstore

  • sinter:获取给定 set 的交集中的元素。
  • 语法:sinter key [key ...]
  • 时间复杂度:O(N * M),N 是最小的集合元素个数,M 是最大的集合元素个数。
  • 返回值:交集的元素。

在这里插入图片描述

  • sinterstore:获取给定 set 的交集中的元素并保存到目标 set 中。
  • 语法:sinterstore destination key [key ...]
  • 时间复杂度:O(N * M),N 是最小的集合元素个数,M 是最大的集合元素个数。
  • 返回值:交集的元素个数。

在这里插入图片描述

并集:sunion、sunionstore

  • sunion:获取给定 set 的并集中的元素。
  • 语法:sunion key [key ...]
  • 时间复杂度:O(N),N 是给定的所有集合的总的元素个数。
  • 返回值:并集的元素。

在这里插入图片描述

  • sunionstore:获取给定 set 的并集中的元素并保存到目标 set 中。
  • 语法:sunionstore destination key [key ...]
  • 时间复杂度:O(N),N 是给定的所有集合的总的元素个数。
  • 返回值:并集的元素个数。

在这里插入图片描述

差集:sdiff、sdiffstore

  • sdiff:获取给定 set 的差集中的元素。
  • 语法:sdiff key [key ...]
  • 时间复杂度:O(N),N 是给定的所有集合的总的元素个数。
  • 返回值:差集的元素。

在这里插入图片描述

  • sdiffstore:获取给定 set 的差集中的元素并保存到目标 set 中。
  • 语法:sdiffstore destination key [key ...]
  • 时间复杂度:O(N),N 是给定的所有集合的总的元素个数。
  • 返回值:差集的元素个数。

在这里插入图片描述

三. set 命令小结

命令执行效果时间复杂度
sadd key member [member …]向集合中添加元素O(K),K 是元素的个数
smembers key求集合中的元素O(K),K 是元素的个数
sismember key member判断元素是否在集合中O(1)
scard key获取集合中元素的个数O(1)
spop key [count]随机删除 count 个元素O(N),N 是 count
srandmember key [count]随机删除 count 个元素O(N),N 是 count
smove source destination member移动源集合中的一个元素到目标集合O(1)
srem key member [member …]删除集合中的元素O(K),K 是元素的个数
sinter key [key …]获取集合的交集O(N * M),N 是最小的集合元素个数,M 是最大的集合元素个数
sinterstore destination key [key …]存储集合的交集到目标集合中O(N * M),N 是最小的集合元素个数,M 是最大的集合元素个数
sunion key [key …]获取集合的并集O(N),N 是所有集合的元素个数
sunionstore destination key [key …]存储集合的并集到目标集合中O(N),N 是所有集合的元素个数
sdiff key [key …]获取集合的差集O(N),N 是所有集合的元素个数
sdiffstore destination key [key …]存储集合的差集到目标集合中O(N),N 是所有集合的元素个数

四. set 内部编码方式

集合类型的内部编码有两种:

  • intset (整数集合):当集合中的元素都是整数并且元素的个数小于 set-max-intset-entries 配置 (默认 512 个) 时,Redis 会选用 intset 来作为集合的内部实现,从而减少内存的使用。
    • Redis 是内存数据库,当元素均为整数,并且元素的个数不是很多的时候,为了节省空间,做出的特点优化。
  • hashtable (哈希表):当集合类型无法满足 intset 的条件时,Redis 会使用 hashtable 作为集合的内部实现。

使用 object encoding key 可以查看集合内部的编码方式,如下:

在这里插入图片描述

五. set 使用场景

用户标签

集合类型比较典型的使用场景是标签 (tag),使用 set 来保存用户的 “标签”

  • 例如 A 用户对娱乐、体育板块比较感兴趣,B 用户对历史、新闻比较感兴趣,这些兴趣点可以被抽象为标签。例如一个电子商务网站会对不同标签的用户做不同的产品推荐。
  • 有了这些数据就可以得到喜欢同一个标签的人,以及用户的共同喜好的标签,这些数据对于增强用户体验和用户黏度都非常有帮助。分析出你这个人的一些特征,分析清楚之后,再投其所好。
  • 上述用户数据,很多公司都在共享。
    • 两个程序,两个账号,如何知道这两个账号是一个人?
    • 现在的程序登入,主要就是两个入口,手机号、微信。
  • 通过上述过程,搜集到的用户特征,就会转换成 “标签” (简短的字符串),此时就可以把标签保存到 Redis 的 set 中。
    • 用户画像,这种事情其实是挺复杂的事情,一般一个大厂都会有专门的团队做这样工作。
    • 上述玩法,抖音玩的是最好的,其它互联网大厂一看这么搞真好,于是纷纷效仿。
    • 但是存在 “信息茧房” 问题:你看到的内容始终就是一个小圈子,看不到其它圈子中的事物。
    • 当你很认真的看了一个视频之后,人家的服务器就判定你,非常爱看这种类型的视频,接下来就给你疯狂推送。

下面的演示通过集合类型来实现标签的若干功能。

  • 给用户添加标签
sadd user:1:tags tag1 tag2 tag5
sadd user:2:tags tag2 tag3 tag5
...
sadd user:k:tags tag1 tag2 tag4
  • 给标签添加用户
sadd tag1:users user:1 user:3
sadd tag2:users user:1 user:2 user:3
...
sadd tagk:users user:1 user:4 user:9 user:28
  • 删除用户下的标签
srem user:1:tags tag1 tag5
...
  • 删除标签下的用户
srem tag1:users user:1
srem tag5:users user:1
...
  • 计算用户的共同兴趣标签
sinter user:1:tags user:2:tags

共同好友

使用 set 来计算用户之间的公共好友,基于 “集合求交集”

  • 例如:QQ,我这边加了很多好友,你那边也加了很多好友。
  • 基于上述还可以做一些好友推荐:A 和 B 是好友,A 和 C 是好友,B 和 C 和 D 都是好友,此时系统就会把 D 推荐给 A

统计 UV

一个互联网产品,如何衡量用户量,用户规模?主要的指标,是两方面:

  • PV (page view):用户每次访问该服务器,都会产生一个 PV
  • UV (user view):每个用户访问该服务器,都会产生一个 UV,但是同一个用户多次访问,不会增加 UV 的个数。
    • UV 需要按照用户进行去重,上述的去重功能,就可以使用 set 来实现。

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

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

相关文章

02-Redis常见命令

02-Redis常见命令 Redis数据结构介绍 Redis是一个key-value的数据库,key一般是String类型,不过value的类型多种多样: 贴心小建议:命令不要死记,学会查询就好啦 Redis为了方便学习,将操作不同数据类型的命…

Rk3568驱动开发_GPIO点亮LED_12

需求: 用配置寄存器方式控制点灯非常原始,现在采用更方便的Linux提供的pctrl和gpio子系统编写字符驱动 1.设备树配置: 现将开发板中呼吸灯关闭掉防止占用到我需要使用的引脚 /* Narnat 2025-5-29 RK3568 GPIO 无需设置pinctrl*/gpioled{co…

阿里云ACP云计算备考笔记 (3)——云存储RDS

目录 第一章 云存储概览 1、云存储通用知识 ① 发展历史 ② 云存储的优势 2、云存储分类 3、文件存储业务场景 第二章 块存储 1、块存储分类 2、云盘的优势 3、创建云盘 4、管理数据盘 ① 格式化数据盘 ② 挂载数据盘 ③ 通过 API 挂载云盘 5、管理系统盘 ① 更…

亚矩阵云手机实测体验:稳定流畅背后的技术逻辑​

最近在测试一款云手机服务时,发现亚矩阵的表现出乎意料地稳定。作为一个经常需要多设备协作的开发者,我对云手机的性能、延迟和稳定性要求比较高。经过一段时间的体验,分享一下真实感受,避免大家踩坑。 ​​1. 云手机能解决什么问…

STM32H562----------ADC外设详解

1、ADC 简介 STM32H5xx 系列有 2 个 ADC,都可以独立工作,其中 ADC1 和 ADC2 还可以组成双模式(提高采样率)。每个 ADC 最多可以有 20 个复用通道。这些 ADC 外设与 AHB 总线相连。 STM32H5xx 的 ADC 模块主要有如下几个特性: 1、可配置 12 位、10 位、8 位、6 位分辨率,…

【Android】双指旋转手势

一,概述 本文参考android.view.ScaleGestureDetector,对双指旋转手势做了一层封装,采用了向量计算法简单实现,笔者在此分享下。 二,实例 如下,使用RotateGestureDetector即可委托,实现旋转手…

B站的视频怎么下载下来——Best Video下载器

B站(哔哩哔哩)作为国内最受欢迎的视频平台之一,聚集了无数优质内容:动漫番剧、游戏实况、学习课程、纪录片、Vlog、鬼畜剪辑……总有那么些视频让人想反复观看、离线观看,甚至剪辑创作。 但你是否遇到过这样的烦恼&am…

基于SFC的windows系统损坏修复程序

前言 在平时使用Windows操作系统时会遇到很多因为系统文件损坏而出现的错误 例如:系统应用无法打开 系统窗口(例如开始菜单)无法使用 电脑蓝屏或者卡死 是如果想要修复很多人只能想到重装系统。但其实Windows有一个内置的系统文件检查器可以修复此类错误。 原理 SFC命令…

智绅科技 —— 智慧养老 + 数字健康,构筑银发时代安全防护网

在老龄化率突破 21.3% 的当下,智绅科技以 "科技适老" 为核心理念,构建 "监测 - 预警 - 干预 - 照护" 的智慧养老闭环。 其自主研发的七彩喜智慧康养平台,通过物联网、AI 和边缘计算技术,实现对老年人健康与安…

用函数实现模块化程序设计(适合考研、专升本)

函数 定义:本质上是一段可以被连续调用、功能相对独立的程序段 c语言是通过“函数”实现模块化的。根据分类标准不同函数分为以下几类。 用户角度:库函数、自定义函数 函数形式:有参函数、无参函数 作用域:外部函数、内部函数 …

OpenCV 滑动条调整图像亮度

一、知识点 1、int createTrackbar(const String & trackbarname, const String & winname, int * value, int count, TrackbarCallback onChange 0, void * userdata 0); (1)、创建一个滑动条并将其附在指定窗口上。 (2)、参数说明: trackbarname: 创建的…

vcs仿真产生fsdb波形的两种方式

目录 方法一: 使用verilog自带的系统函数 方法二: 使用UCLI command 2.1 需要了解什么是vcs的ucli,怎么使用ucli? 2.2 使用ucli dump波形的方法 使用vcs仿真产生fsdb波形有两种方式,本文参考《vcs user guide 20…

【前端】每日一道面试题6:解释Promise.any和Promise.allSettled的使用场景及区别。

Promise.any() 和 Promise.allSettled() 是 JavaScript 中用于处理异步操作的两种不同策略的 Promise 组合器,它们的核心区别在于逻辑目标与结果处理方式: 1. Promise.any() 使用场景: 需要获取 首个成功结果(类似竞速成功优先&…

数据链路层__

文章目录 数据链路层基本概念(1)链路管理:面向连接的服务(2)帧同步:成帧1、字符计数法2、字符填充法(带填充的首尾界符法)3、带填充的首位标志法4、物理层编码违例法 (3&…

coze智能体后端接入问题:

是否一定要按照coze官方API文档格式调用? 不一定:以下面代码为例(给了注释) app.route(/compare_models, methods[POST]) def compare_models():print("收到 compare_models 请求!") #begin-这一部分代码作用:从前端接…

如何轻松、安全地管理密码(新手指南)

很多人会为所有账户使用相同、易记的密码,而且常常多年不换。虽然这样方便记忆,但安全性非常低。 您可能听说过一些大型网站的信息泄露事件,同样的风险也可能存在于您的WordPress网站中。如果有不法分子获取了访问权限,您的网站和…

宝塔think PHP8 安装使用FFmpeg 视频上传

宝塔think PHP8 安装使用FFmpeg 一、 安装think PHP8二、安装 FFmpeg1,登录到宝塔面板。2,进入“软件商店”。3,搜索“FFmpeg”。4,选择版本点击安装。5,检查 FFmpeg 是否安装成功6, 在 ThinkPHP 8 中使用 …

Android 轻松实现 增强版灵活的 滑动式表格视图

表格视图组件,支持: 1. 无标题模式:只有数据行也可以正常滑动 2. 两种滑动模式:固定第一列 或 全部滑动 3. 全面的样式自定义能力 4. 智能列宽计算 1. 无标题模式支持 设置无标题:调用 setHeaderData(null) 或 …

【Python进阶】元类编程

目录 🌟 前言🏗️ 技术背景与价值🩹 当前技术痛点🛠️ 解决方案概述👥 目标读者说明 🧠 一、技术原理剖析📊 核心概念图解💡 核心作用讲解🔧 关键技术模块说明⚖️ 技术选…

DeepSeek模型性能优化:从推理加速到资源调度的全栈实践

引言 在生产环境中部署DeepSeek模型时,性能优化直接关系到服务质量和运营成本。本文将深入探讨从芯片级优化到分布式调度的全栈性能提升方案,涵盖计算图优化、内存管理、批处理策略等关键技术,并分享在千万级QPS场景下的实战经验,帮助工程团队突破性能瓶颈,实现成本与效能…