屏东县网站建设_网站建设公司_建站流程_seo优化
2026/1/7 6:46:15 网站建设 项目流程

Redis之Set:从无序唯一到智能存储,解锁用户画像/社交/统计全场景应用 - 实践


文章目录

  • 本篇摘要
  • Redis之Set(集合)
    • 常见指令
        • **1. 基础操作指令**
        • **2. 集合间操作指令**
        • **3. 随机与移动操作**
      • 小总结
    • set内部编码方式
      • 举个例子理解
    • **Redis的Set 应用场景**
        • **1. 用户标签画像(精准推荐)**
        • **2. 社交共同好友(关系链分析)**
        • **3. 独立访客统计(UV去重)**
  • 本篇小结

在这里插入图片描述

本篇摘要

本文围绕Redis集合(Set)展开,介绍其无序唯一、自动去重特性及核心指令(SADD/SREM/SMEMBERS等基础操作、集合运算指令、随机移动指令),解析intset/hashtable内部编码规则(整数且≤512用intset省内存,否则用hashtable),并给出用户标签、共同好友、UV统计等应用场景。

Redis之Set(集合)

在这里插入图片描述

常见指令

1. 基础操作指令
  1. SADD key member [member ...]
    • 功能:向集合添加一个或多个成员(自动去重)。
    • 示例
      SADD tags "redis" "db" "cache"
    • 返回值:成功添加的成员数量(重复成员不计)。
    • 时间复杂度:O(1)(每个成员)。

如:

在这里插入图片描述

发现是无序的。

  1. SREM key member [member ...]
    • 功能:移除集合中指定成员。
    • 示例
      SREM tags "db"
    • 返回值:实际移除的成员数量。
    • 时间复杂度:O(1)(每个成员)。

如:

在这里插入图片描述

当然这里也能移除很多。

  1. SMEMBERS key
    • 功能:返回集合所有成员(无序)。
    • 示例
      SMEMBERS tags
    • 注意:大集合可能阻塞,推荐用SSCAN分批获取。
    • 时间复杂度:O(N)(N为集合大小)。

如:

在这里插入图片描述

  1. SCARD key
    • 功能:获取集合成员数量。
    • 示例
      SCARD tags
    • 时间复杂度:O(1)。

如:

在这里插入图片描述

  1. SISMEMBER key member
    • 功能:检查成员是否在集合中。
    • 示例
      SISMEMBER tags "cache"
    • 返回值:1(存在)或 0(不存在)。
    • 时间复杂度:O(1)。

如:
在这里插入图片描述

  1. SSCAN key cursor [MATCH pattern] [COUNT count]
    • 功能:增量式迭代集合成员(解决SMEMBERS阻塞问题)。
    • 示例
      SSCAN tags 0 (或者sscan tags 0 match r* 10)
    • 返回值[新游标, [成员1, 成员2, ...]]
    • 时间复杂度:每次调用 O(1),完整迭代 O(N)。

如:

在这里插入图片描述

遍历完返回0,然后就是全部个数。

2. 集合间操作指令
  1. SUNION key [key ...]
    • 功能:返回多个集合的并集(不存储结果)。
    • 示例
      SUNION tags tag2
    • 时间复杂度:O(N)(N为所有集合成员总数)。

如:
在这里插入图片描述

  1. SUNIONSTORE destination key [key ...]
    • 功能:计算并集并存储到目标集合。
    • 示例
      SUNIONSTORE des tags tags2
    • 返回值:结果集合的成员数量。
    • 时间复杂度:O(N)。

如:

在这里插入图片描述

  1. SINTER key [key ...]
    • 功能:返回多个集合的交集。
    • 示例
      SINTER  ag2 des
    • 时间复杂度:O(N*M)(最差情况)。

如:

在这里插入图片描述

这里只有一种可能。

  1. SINTERSTORE destination key [key ...]
    • 功能:计算交集并存储到目标集合。
    • 示例
      sinterstore des1 tag2 des
    • 时间复杂度:O(N*M)。

如:

在这里插入图片描述

  1. SDIFF key [key ...]
    • 功能:返回第一个集合与其他集合的差集。
    • 示例
      SDIFF tag1 tag2 /sdiff tag2 tag1      ```
    • 时间复杂度:O(N)。

如:

在这里插入图片描述

这里先后顺序决定是否不一样。

  1. SDIFFSTORE destination key [key ...]
    • 功能:计算差集并存储到目标集合。
    • 示例
       SDIFF  t1 tag1 tag2 /sdiff t2 tag2 tag1
    • 时间复杂度:O(N)。

如:

在这里插入图片描述

3. 随机与移动操作
  1. SPOP key [count]
    • 功能随机移除并返回集合中一个或多个成员。
    • 示例
      SPOP tag1 2
    • 返回值:被移除的成员(数组形式)。
    • 时间复杂度:O(1)(单个成员)。

如:

在这里插入图片描述

  1. SMOVE source destination member
    • 功能:将成员从源集合移动到目标集合。
    • 示例
      SMOVE tag2 tag1 c++
    • 返回值:1(成功)或 0(成员不存在)。
    • 时间复杂度:O(1)。

如:

在这里插入图片描述

注:如果tag1有对应的元素,那么它只会从tag2中移除然后无法加入tag1。

小总结

指令类别指令功能简述时间复杂度关联内部编码备注
基础操作SADD key member...向集合添加一个或多个成员(自动去重)O(1) 每个成员INTSET(小整数集合)
HT(大集合/非整数)
整数且数量少时用 INTSET,否则转 HT
SREM key member...移除集合中指定成员O(1) 每个成员HT
SMEMBERS key返回集合所有成员(无序,大集合可能阻塞)O(N)(N为集合大小)HT大集合建议改用 SSCAN 分批获取
SCARD key获取集合成员数量O(1)HT/INTSET 均直接统计
SISMEMBER key member检查成员是否在集合中O(1)HT(哈希表快速查找)
INTSET
SSCAN key cursor [MATCH pattern] [COUNT count]增量式迭代集合成员(解决 SMEMBERS 阻塞问题)每次调用 O(1),完整遍历 O(N)HT通过游标分批获取,避免全量阻塞
集合间运算SUNION key [key...]返回多个集合的并集(不存储结果)O(N)(N为所有集合成员总数)HT遍历所有集合成员计算并集
SUNIONSTORE dest key [key...]计算并集并存储到目标集合O(N)HT结果存入 dest,返回成员数
SINTER key [key...]返回多个集合的交集O(N*M)(最差情况,依赖集合大小)HT需遍历多个集合的公共成员
SINTERSTORE dest key [key...]计算交集并存储到目标集合O(N*M)HT结果存入 dest
SDIFF key [key...]返回第一个集合与其他集合的差集(顺序影响结果)O(N)HTSDIFF A B 是 A 有但 B 没有的成员
SDIFFSTORE dest key [key...]计算差集并存储到目标集合O(N)HT结果存入 dest
随机与移动操作SPOP key [count]随机移除并返回集合中一个或多个成员O(1)(单个成员)HT从集合中随机弹出元素
SMOVE source dest member将成员从源集合移动到目标集合(原子操作)O(1)HT若成员不存在于源集合则失败,目标集合自动创建

set内部编码方式

Redis里的集合(set)存数据时,内部有两种“存储方式”,具体用哪种,取决于集合里存的是啥、有多少数据:

  1. intset(整数集合,类似于整数数组)

  2. hashtable(哈希表)

如下:

在这里插入图片描述

举个例子理解

  • 例子1:满足intset条件 → 用intset存
    往集合setkey里加4个整数(1、2、3、4),因为元素少(≤512)且全是整数,所以用object encoding setkey查存储方式,结果是"intset"

如:

在这里插入图片描述

  • 例子2:元素超过512个 → 用hashtable存
    往集合setkey里加513个整数(超过512了),这时候不满足intset条件,查存储方式结果是"hashtable"

这里太多就不演示了。

  • 例子3:有非整数元素 → 用hashtable存
    往集合setkey里加一个字符串"a"(不是整数),查存储方式结果也是"hashtable"

如:

在这里插入图片描述

一句话概括:Redis集合存数据时,优先选省内存的intset;但只要数据不满足“全是小整数且数量少”,就会自动切换成更通用的hashtable来存。

Redis的Set 应用场景

1. 用户标签画像(精准推荐)
  • 功能:存储用户特征标签(如性别、兴趣、行为),实现“千人千面”推荐,还有就是根据用户常访问的加入set中,最后根据set元素分析用户兴趣,实现这种推送功能。
  • 核心操作
    • SADD user:1:tags "sports"(添加标签)
    • SINTER user:1:tags user:2:tags(计算共同兴趣)
  • 优势:自动去重,快速交集运算。
2. 社交共同好友(关系链分析)
  • 功能:通过集合交集计算用户共同好友(如QQ/微信)。
  • 核心操作
    • SINTER friends:Alice friends:Bob(返回Alice和Bob的共同好友)
3. 独立访客统计(UV去重)
  • 功能:统计网站唯一访问用户数(同一用户多次访问仅计1次)。
  • 核心操作
    • SADD uv:20230820 "192.168.1.1"(记录IP)
    • SCARD uv:20230820(获取UV数)
  • 优势:利用Set唯一性天然去重,比数据库统计高效。

本篇小结

Redis集合是高效存储唯一元素的工具,支持丰富操作与集合运算,内部通过intset/hashtable智能编码省内存,广泛应用于标签、社交、统计等场景,是开发中实用的数据结构。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询