Redis 集合对象
2023-3-24
| 2023-8-2
0  |  阅读时长 0 分钟
type
status
date
slug
summary
tags
category
icon
password
Property

Set 类型和 List 类型的区别如下:
  • List 可以存储重复元素,Set 只能存储非重复元素;
  • List 是按照元素的先后顺序存储元素的,而 Set 则是无序方式存储元素的。
 
集合对象的编码可以是 intset 或者 hashtable 。
intset 编码的集合对象使用整数集合作为底层实现, 集合对象包含的所有元素都被保存在整数集合里面。
创建一个intset编码集合对象:
notion image
另一方面, hashtable编码的集合对象使用字典作为底层实现, 字典的每个键都是一个字符串对象, 每个字符串对象包含了一个集合元素, 而字典的值则全部被设置为 NULL 。
以下代码将创建一个hashtable 编码集合对象:
notion image
 

编码的转换

当集合对象可以同时满足以下两个条件时, 对象使用 intset 编码:
  1. 集合对象保存的所有元素都是整数值
  1. 集合对象保存的元素数量不超过 512 个
不能满足这两个条件的集合对象需要使用 hashtable 编码。
 
第二个条件的上限值是可以修改的, 具体请看配置文件中关于 set-max-intset-entries 选项的说明。
对于使用 intset 编码的集合对象来说, 当使用 intset 编码所需的两个条件的任意一个不能被满足时, 对象的编码转换操作就会被执行: 原本保存在整数集合中的所有元素都会被转移并保存到字典里面, 并且对象的编码也会从 intset 变为 hashtable 。
 
 

Redis集合命令

notion image
  • SADD:向集合添加一个或多个成员
  • SCARD:获取集合的成员数
  • SDIFF:返回给定所有集合的差集
  • SDIFFSTORE:返回给定所有集合的差集并存储在 destination 中
  • SINTER:返回给定所有集合的交集
  • SINTERSTORE:返回给定所有集合的交集并存储在 destination 中
  • SISMEMBER:判断 member 元素是否是集合 key 的成员
  • SMEMBERS:返回集合中的所有成员
  • SMOVE:将 member 元素从 source 集合移动到 destination 集合
  • SPOP:移除并返回集合中的一个随机元素
  • SRANDMEMBER:返回集合中一个或多个随机数
  • SREM:移除集合中一个或多个成员
  • SUNION:返回所有给定集合的并集
  • SUNIONSTORE:所有给定集合的并集存储在 destination 集合中
  • SSCAN:迭代集合中的元素
 

应用场景

集合的主要几个特性,无序、不可重复、支持并交差等操作。
因此 Set 类型比较适合用来数据去重和保障数据的唯一性,还可以用来统计多个集合的交集、错集和并集等,当存储的数据是无序并且需要去重的情况下,比较适合使用集合类型进行存储。
但是这里有一个潜在的风险。Set 的差集、并集和交集的计算复杂度较高,在数据量较大的情况下,如果直接执行这些计算,会导致 Redis 实例阻塞
在主从集群中,为了避免主库因为 Set 做聚合计算(交集、差集、并集)时导致主库被阻塞,可以选择一个从库完成聚合统计,或者把数据返回给客户端,由客户端来完成聚合统计。

点赞

Set 类型可以保证一个用户只能点一个赞,这里举例子一个场景,key 是文章id,value 是用户id。
uid:1 、uid:2uid:3 三个用户分别对 article:1 文章点赞了。
uid:1 取消了对 article:1 文章点赞。
获取 article:1 文章所有点赞用户 :
获取 article:1 文章的点赞用户数量:
判断用户 uid:1 是否对文章 article:1 点赞了:

共同关注

Set 类型支持交集运算,所以可以用来计算共同关注的好友、公众号等。
key 可以是用户id,value 则是已关注的公众号的id。
uid:1 用户关注公众号 id 为 5、6、7、8、9,uid:2 用户关注公众号 id 为 7、8、9、10、11。
uid:1 和 uid:2 共同关注的公众号:
给 uid:2 推荐 uid:1 关注的公众号:
验证某个公众号是否同时被 uid:1 或 uid:2 关注:
 

抽奖活动

存储某活动中中奖的用户名 ,Set 类型因为有去重功能,可以保证同一个用户不会中奖两次。
key为抽奖活动名,value为员工名称,把所有员工名称放入抽奖箱 :
如果允许重复中奖,可以使用 SRANDMEMBER 命令。
如果不允许重复中奖,可以使用 SPOP 命令。
  • Redis
  • Redis 哈希对象Redis 有序集合对象
    目录