Redis里那个Set到底是咋回事,原理和用法其实没那么复杂
- 问答
- 2026-01-11 17:37:20
- 3
(Redis作者antirez的博客“Redis宣言”里提到,设计目标之一就是“代码简单直接”,所以Set的设计也遵循这个思路)Redis里的Set,你可以把它理解成一个不能有重复元素的集合,就跟我们数学上学过的集合概念一模一样,或者更接地气地说,它就像一个没有排练过的班级大合唱队伍——谁都想站进来,但同一个位置绝不能站两个人。
它底层是怎么做到又快又稳的呢?主要靠两种数据结构在背后撑腰,根据情况自动切换,非常聪明。(原理部分参考《Redis设计与实现》这本书的讲解)当Set里的元素全是整数,并且数量不多的时候,Redis会使用一种叫“整数集合(intset)”的紧凑结构,它就像军训时教官让所有人按身高排成一条紧密的直线,所有数据一个挨一个地存储在连续的内存里,这样做的好处是查找速度快得像闪电,而且特别节省内存空间,因为没有任何额外的开销,一旦你往这个队伍里塞进一个非整数成员(比如一个字符串"apple"),或者整数数量超过了某个设定值(默认是512),这个整齐的“整数方阵”就会立刻“解散重组”,变身成一个叫“哈希表(hash table)”的结构。
哈希表这玩意儿,你可以想象成图书馆里有好多带编号的书架(在Redis里这些“书架”叫哈希桶),当你存一个元素时,Redis会用一个特定的算法(哈希函数)算出这个元素应该放在几号书架上,然后把它放进去,查找的时候也一样,直接算一下就知道该去哪个书架找,所以速度也非常快,基本上是一步到位,虽然它比整数集合稍微多占一点内存,但好处是超级灵活,什么类型的数据都能装得下,这种“看人下菜碟”的自动转换机制,是Redis在速度和内存之间做出的非常精妙的平衡。
知道了它大概是怎么工作的,我们再看看它具体能干啥,用起来简直像玩一样简单。(用法部分综合自Redis官方命令文档)最常用的几个命令,你试几次就能记住:
-
塞东西进去:
SADD key member [member ...]这就像你往一个空袋子(Set)里扔东西,你想记录一个叫“fruits”的水果集合,就执行SADD fruits apple banana orange,如果你不小心又扔了一个"apple"进去,没关系,Set的“去重”特性保证了袋子里永远只有一个"apple"。 -
看看里面有啥:
SMEMBERS key这就是把袋子里的东西全倒出来看看,执行SMEMBERS fruits,刚才放进去的苹果、香蕉、橘子就都显示出来了(顺序是随机的,Set不保证顺序)。 -
查查某个东西在不在:
SISMEMBER key member你想快速知道袋子里有没有“榴莲”这种神奇的水果?用SISMEMBER fruits durian,Redis会马上告诉你:1(表示有)或者0(表示没有),这个操作是O(1)时间复杂度,意思是无论你袋子里有10个元素还是100万个元素,检查速度都是一样快,这是Set最大的优势之一。 -
随便抽一个出来:
SPOP key这个命令很有趣,它从袋子里随机抓一个东西出来,并且把它从袋子里移除,适合用来做抽奖系统——把所有参与抽奖的用户ID塞进一个Set,每次SPOP就相当于抽走一位幸运儿。 -
求交集、并集、差集:
SINTER key [key ...]/SUNION key [key ...]/SDIFF key [key ...]这就是Set最体现数学魅力的地方了,比如你有两个Set,一个叫“my_friends”(我的朋友),一个叫“her_friends”(她的朋友)。SINTER my_friends her_friends能立刻找出我们俩的共同好友。SUNION my_friends her_friends能列出我们俩所有的朋友(自动去重)。SDIFF my_friends her_friends能找出“我有的朋友但她没有”的那些人。 这些集合运算在处理标签系统、共同关注等场景时非常强大。
-
把结果存到新集合:
SINTERSTORE destination key [key ...]比如你算出了共同好友,不想只是看看,还想把这个结果存成一个叫“our_common_friends”的新集合,那就用SINTERSTORE命令,一步到位。
你看,Redis的Set用起来是不是一点都不复杂?它就是一个帮你高效管理不重复元素,并且能进行高速集合运算的工具,无论是用来做黑白名单过滤、随机推荐、标签系统,还是用户画像中的兴趣点去重,Set都能大显身手,你只需要记住它的核心特点——元素唯一、无序但查询极快、支持集合运算,就能在合适的场景里轻松地用上它了。

本文由歧云亭于2026-01-11发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:http://waw.haoid.cn/wenda/78820.html
