Redis Set数据类型:从青铜到王者的全方位指南

Redis Set数据类型:从青铜到王者的全方位指南


一、介绍:这货到底是个啥?

Redis的Set是一种无序、唯一 的字符串集合,底层基于哈希表或整数集合实现。它的核心特点就俩字:快 (O(1)时间复杂度)和独 (元素不重复)。你可以把它想象成一个"社交恐惧症患者"------绝不接受重复数据,但能轻松帮你处理交集、并集、差集等社交关系。

底层编码:

  • Intset(整数集合):当元素全是整数且数量≤512时,变身"内存抠门精"。
  • Hashtable(哈希表):其他情况下,老老实实用哈希表,字典键存元素,值全为NULL(参考Java的HashSet)。

二、用法:Set的十八般武艺

基础操作(单身狗模式)
  • SADD:添加元素(重复?不存在的!)
  • SMEMBERS:查看所有成员(但顺序随机,强迫症慎用)
  • SISMEMBER:查户口(判断元素是否存在)
  • SPOP:随机踢人(抽奖神器)。
高阶操作(社交达人模式)
  • 交集 (SINTER):找共同好友?秒出结果!
  • 并集 (SUNION):合并多个粉丝列表,一键搞定!
  • 差集 (SDIFF):发现"他关注了谁,而你没关注"。

三、案例:Set的职场生存记

1. 社交App的共同好友

刘备的好友集合:SADD user:刘备 赵子龙 张飞 关羽 貂蝉

曹操的好友集合:SADD user:曹操 貂蝉 夏侯惇 典韦

共同好友?一条命令搞定:

bash 复制代码
SINTERSTORE user:曹刘好友 user:刘备 user:曹操  

结果:貂蝉(原来两位大佬都喜欢美女!)。

2. 点赞系统
  • 用户A点赞文章:SADD article:1 uid:A
  • 取消点赞:SREM article:1 uid:A
  • 查看谁点了赞:SMEMBERS article:1。
3. 抽奖活动
  • 参与用户:SADD lucky_draw user1 user2 user3
  • 抽3个不重复的幸运儿:SPOP lucky_draw 3
  • 抽3个可重复的(比如锦鲤转发):SRANDMEMBER lucky_draw 3。

四、原理:Set的"内功心法"

1. Intset的升级机制

当插入一个"大整数"(比如65535)导致原有int16数组装不下时,Redis会默默将intset升级为int32或int64,像搬家一样把旧数据扩容。但只升级不降级------一旦用了大房子,绝不搬回小单间(内存浪费?不存在的!)。

2. Hashtable的字典结构

每个元素作为哈希表的键,值为NULL。简单粗暴,但查找速度堪比闪电侠。


五、对比:Set vs 其他数据结构

特性 Set List Sorted Set
元素唯一性 ✅ ❌ ✅(但分值可重复)
顺序 无序 有序(插入顺序) 有序(按分值排序)
应用场景 去重、集合运算 消息队列、时间线 排行榜、范围查询

六、避坑指南:Set的"七伤拳"

  1. 大集合的交集操作 :直接对海量数据做SINTER可能导致Redis阻塞,建议在从库或客户端处理。
  2. 内存爆炸 :一次性插入百万元素?Redis可能原地崩溃!建议分批插入或使用pipeline。
  3. 误用排序 :Set本身无序,若需要排序,请召唤Sorted Set。
  4. 过期策略:依赖惰性删除+定期删除,别指望Redis会主动清理所有过期数据。

七、最佳实践:让Set更"6"

  1. 合理选择编码:尽量让集合元素为整数且数量≤512,触发intset省内存。
  2. 慎用SMEMBERS :大集合直接获取所有元素可能拖垮网络,改用SSCAN分批迭代。
  3. 分布式锁的陷阱 :用SETNX时记得加过期时间,避免死锁(血泪教训!)。

八、面试考点:征服面试官的弹药库

  1. Q:Set的底层实现?

    A:Intset或Hashtable,取决于元素类型和数量。

  2. Q:如何实现共同关注?

    A:用SINTER取交集,时间复杂度O(N*M),大数据量慎用。

  3. Q:Set和List的区别?

    A:Set无序+唯一,List有序+可重复。

  4. Q:Set的集合运算复杂度?

    A:交集O(N*M),并集O(N),差集O(N),N为最小集合大小。


九、总结:Set的哲学

Redis的Set就像一把瑞士军刀------简单却强大。无论是社交关系、数据去重,还是随机抽奖,它都能轻松应对。但记住:能力越大,责任越大,合理使用才能避免性能"翻车"。

最后送上一句程序员箴言:

"人生苦短,我用Set;代码易写,内存别炸!"

相关推荐
没有气的汽水30 分钟前
一次生产 Redis 内存打满的排查、清理和复盘
redis
hey you~1 小时前
云呼叫中心坐席自动分配实战:ACD 策略、Redis+Lua 实现与排查清单
数据库·redis·lua·云呼叫中心·acd·坐席分配·坐席状态机
我不会起名字3223 小时前
Redis pipeline 用了反而更慢:3 类误用与正确的批量姿势
redis·pipeline·lua·rtt·批量
Tsuki_tl3 小时前
【总结】Redis五大数据类型应用场景及基本命令
数据库·redis·后端·缓存·缓存中间件·redis命令·redis 五大数据类型
代码丰18 小时前
大 JSON 放进 Redis 之后,如何用 Stream 解耦耗时任务?
redis·后端·系统架构
枫子有风21 小时前
卡码网盘项目深挖
java·redis·jwt·es·pgvector
福大大架构师每日一题1 天前
redis 8.10.3正式发布:聚焦集群总线超大消息传播场景的安全修复,8.10.3 Latest更新解读
数据库·redis·安全
江屿风1 天前
【Plain Language Large Model】【从麦当劳点餐到Redis接入:MCP如何让AI工具集成变简单】流食般投喂
人工智能·redis·笔记·语言模型·llm·mcp
码智社1 天前
Redis 哨兵模式详解:从原理到生产实践
java·redis
与数据交流的路上1 天前
一次 redis 幽灵内存的分析
数据库·redis·缓存