Redis之Set和SortedSet类型常用命令详解
除了String、Hash和List外,Redis还提供了Set(集合)和SortedSet(有序集合)两种基本数据类型,它们在处理去重、排序、交集/并集等场景中表现出色。
一、Set类型详解
Set类型是一个无序的字符串集合,具有自动去重特性,类似于数学中的集合概念。它底层采用哈希表实现,因此添加、删除和查找元素的时间复杂度都是O(1)。
1. Set类型的特点
- 无序性:元素存储顺序与插入顺序无关
- 唯一性:自动去除重复元素,每个元素在集合中唯一存在
- 支持集合运算:可进行交集、并集、差集等操作
- 高效操作:添加、删除、查找元素性能优异
2. 常用命令及示例
以存储用户标签为例,使用user:100:tags
作为Set的键。
(1)添加与删除元素
SADD key member1 member2 …:向集合中添加一个或多个元素,返回添加成功的元素数量(忽略已存在元素)
127.0.0.1:6379> SADD user:100:tags "技术" "音乐" "旅行" "技术" (integer) 3 # 仅添加了3个新元素,"技术"被去重
SREM key member1 member2 …:从集合中删除一个或多个元素,返回删除成功的元素数量
127.0.0.1:6379> SREM user:100:tags "音乐" (integer) 1
(2)查询元素
SMEMBERS key:返回集合中所有元素
127.0.0.1:6379> SMEMBERS user:100:tags 1) "旅行" 2) "技术" # 无序性体现,与插入顺序不同
SISMEMBER key member:判断元素是否在集合中,存在返回1,否则返回0
127.0.0.1:6379> SISMEMBER user:100:tags "旅行" (integer) 1
SCARD key:返回集合中元素的数量
127.0.0.1:6379> SCARD user:100:tags (integer) 2
(3)集合运算
SINTER key1 key2 …:返回多个集合的交集(同时存在于所有集合中的元素)
127.0.0.1:6379> SADD user:200:tags "技术" "阅读" "运动" (integer) 3 127.0.0.1:6379> SINTER user:100:tags user:200:tags 1) "技术" # 两个用户共同的标签
SUNION key1 key2 …:返回多个集合的并集(所有集合中的元素,去重)
127.0.0.1:6379> SUNION user:100:tags user:200:tags 1) "旅行" 2) "技术" 3) "阅读" 4) "运动"
SDIFF key1 key2 …:返回集合的差集(存在于第一个集合但不存在于其他集合的元素)
127.0.0.1:6379> SDIFF user:100:tags user:200:tags 1) "旅行" # 仅user:100有,user:200没有的标签
(4)其他常用命令
SRANDMEMBER key [count]:随机返回集合中的count个元素(默认1个),不会删除元素
127.0.0.1:6379> SRANDMEMBER user:200:tags 2 1) "运动" 2) "阅读"
SPOP key [count]:随机删除并返回集合中的count个元素
127.0.0.1:6379> SPOP user:200:tags 1 1) "阅读"
3. 应用场景
- 标签系统:存储用户兴趣标签、文章分类标签等,利用集合去重特性
- 好友关系:存储用户的好友列表,通过SINTER计算共同好友
- 去重统计:如网站独立访客(UV)统计,避免重复计数
- 抽奖系统:使用SRANDMEMBER或SPOP实现随机抽奖功能
- 黑名单/白名单:存储禁止访问或允许访问的IP/用户ID
二、SortedSet类型详解
SortedSet(有序集合)是Set的增强版,每个元素除了值(member)外,还关联一个分数(score),并按照分数从小到大排序。它底层采用“跳跃表”+“哈希表”实现,既保证了排序性能,又能快速查找元素。
1. SortedSet类型的特点
- 有序性:通过分数自动排序,支持按分数范围查询
- 唯一性:元素值(member)唯一,但分数(score)可重复
- 灵活排序:可按分数升序或降序获取元素
- 高效操作:添加、删除、按范围查询的性能优异
2. 常用命令及示例
以存储商品销量排行榜为例,使用goods:sales:rank
作为SortedSet的键,member为商品ID,score为销量。
(1)添加与更新元素
- ZADD key score1 member1 score2 member2 …:向有序集合中添加元素,若元素已存在则更新分数,返回添加/更新的元素数量
127.0.0.1:6379> ZADD goods:sales:rank 100 1001 200 1002 150 1003 (integer) 3 # 添加3个商品的销量数据
(2)查询元素
ZSCORE key member:返回指定元素的分数
127.0.0.1:6379> ZSCORE goods:sales:rank 1002 "200"
ZRANK key member:返回元素按分数升序排列的排名(从0开始)
127.0.0.1:6379> ZRANK goods:sales:rank 1002 (integer) 2 # 升序排名第3(0、1、2)
ZREVRANK key member:返回元素按分数降序排列的排名(从0开始)
127.0.0.1:6379> ZREVRANK goods:sales:rank 1002 (integer) 0 # 降序排名第1
ZRANGE key start stop [WITHSCORES]:按分数升序返回指定排名范围的元素,WITHSCORES表示同时返回分数
127.0.0.1:6379> ZRANGE goods:sales:rank 0 -1 WITHSCORES 1) "1001" 2) "100" 3) "1003" 4) "150" 5) "1002" 6) "200"
ZREVRANGE key start stop [WITHSCORES]:按分数降序返回指定排名范围的元素
127.0.0.1:6379> ZREVRANGE goods:sales:rank 0 1 WITHSCORES # 返回销量前2的商品 1) "1002" 2) "200" 3) "1003" 4) "150"
(3)分数范围查询
ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]:返回分数在[min, max]范围内的元素(升序)
127.0.0.1:6379> ZRANGEBYSCORE goods:sales:rank 120 200 WITHSCORES 1) "1003" 2) "150" 3) "1002" 4) "200"
ZCOUNT key min max:返回分数在[min, max]范围内的元素数量
127.0.0.1:6379> ZCOUNT goods:sales:rank 120 200 (integer) 2
(4)修改与删除
ZINCRBY key increment member:为指定元素的分数增加增量(可负数)
127.0.0.1:6379> ZINCRBY goods:sales:rank 50 1001 # 商品1001销量增加50 "150"
ZREM key member1 member2 …:删除有序集合中的元素
127.0.0.1:6379> ZREM goods:sales:rank 1003 (integer) 1
ZREMRANGEBYSCORE key min max:删除分数在[min, max]范围内的元素
127.0.0.1:6379> ZREMRANGEBYSCORE goods:sales:rank 0 120 (integer) 0 # 没有符合条件的元素被删除
3. 应用场景
- 排行榜:如商品销量榜、用户积分榜、游戏得分榜等,支持实时更新和排名查询
- 延迟队列:将任务的执行时间作为score,通过ZRANGEBYSCORE获取到期任务
- 范围统计:如统计分数在某个区间的用户数量、商品数量等
- 带权重的集合:如根据权重推荐内容,权重作为score
- 时间序列数据:存储带时间戳的数据(时间戳作为score),便于按时间范围查询
总结:Set与SortedSet的对比及选用原则
特性 | Set | SortedSet |
---|---|---|
排序 | 无序 | 按score有序 |
去重 | 支持 | 支持(member唯一) |
分数 | 无 | 有(score) |
适用场景 | 去重、交集/并集运算 | 排序、排名、范围查询 |
选用原则:
- 仅需去重且无需排序时,优先使用Set,内存占用更低
- 需要排序、排名或按范围查询时,使用SortedSet
- 涉及集合间运算(如共同好友)时,使用Set的SINTER/SUNION等命令
- 需实现排行榜、延迟队列等功能时,使用SortedSet
若这篇内容帮到你,动动手指支持下!关注不迷路,干货持续输出!
ヾ(´∀ ˋ)ノヾ(´∀ ˋ)ノヾ(´∀ ˋ)ノヾ(´∀ ˋ)ノヾ(´∀ ˋ)ノ