当前位置: 首页 > news >正文

【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 来实现。

相关文章:

  • 云原生时代 Kafka 深度实践:06原理剖析与源码解读
  • (四)动手实现多层感知机:深度学习中的非线性建模实战
  • Windows 下彻底删除 VsCode
  • Neovim - 打造一款属于自己的编辑器(一)
  • 云计算 Linux Rocky day03
  • 【云计算】基础篇,含云测试
  • PyTorch——线性层及其他层介绍(6)
  • 酷狗概念版4.1.6深度体验:探索音乐新境界的便捷之选
  • 解决Vue3+uni-app导航栏高亮自动同步方案
  • 深入浅出:Oracle 数据库 SQL 执行计划查看详解(1)——基础概念与查看方式
  • 【Kotlin】表达式关键字
  • 前端与后端
  • 链表题解——反转链表【LeetCode】
  • uniapp+vue2+uView项目学习知识点记录
  • winrm登录失败,指定的凭据被服务器拒绝
  • git stash介绍(临时保存当前工作目录中尚未提交的修改)
  • Rust 学习笔记:使用 cargo install 安装二进制 crate
  • nav2笔记-250603
  • Linux运维笔记:1010实验室电脑资源规范使用指南
  • NSSCTF [LitCTF 2025]test_your_nc
  • 日本可以做的h游戏视频网站/智能网站推广优化
  • 自己怎么做网站推广/网站排名推广软件
  • 惠州网站建设找惠州邦/杭州优化排名哪家好
  • 上海网站开发哪里好薇/上海疫情突然消失的原因
  • 武汉网站建设/网站优化技巧
  • thinkphp网站优化/怎么投放网络广告