Redis 集合与有序集合数据类型及命令详解

时间:2024-03-17 07:12:28

集合

集合(set) 类型也是用来保存多个的字符串元素, 但和列表类型不一样的是, 集合中不允许有重复元素, 并且集合中的元素是无序的, 不能通过索引下标获取元素。

一个集合最多可以存储232-1个元素。 Redis除了支持集合内的增删改查, 同时还支持多个集合取交集、 并集、 差集, 合理地使用好集合类型

命令

添加元素
sadd key element [element ...]  
获取所有元素
smembers key

返回结果是无序的

删除元素
srem key element [element ...]
计算元素个数
scard key
判断元素是否在集合中
sismember key element

如果给定元素 element 在集合内返回1, 反之返回0

随机从集合返回指定个数元素
srandmember key [count]

[count] 是可选参数, 如果不写默认为1

从集合随机弹出元素
spop key

spop操作可以从集合中随机弹出一个元素,并在执行后将该元素从集合中删除

Redis从3.2版本开始, spop也支持[count]参数

集合间操作

交集
sinter key [key ...]  

求交集并保存结果到另一个集合

sinterstore destination key [key ...]
并集
sunion key [key ...]

求并集并保存结果到另一个集合

suionstore destination key [key ...]
差集
sdiff key [key ...]

求差集并保存结果到另一个集合

sdiffstore destination key [key ...]

内部编码

inset

intset(整数集合) : 当集合中的元素都是整数且元素个数小于set-maxintset-entries配置(默认512个) 时, Redis会选用intset来作为集合的内部实现, 从而减少内存的使用。

  1. 当元素个数较少且都为整数时, 内部编码为intset

hashtable

hashtable(哈希表) : 当集合类型无法满足intset的条件时, Redis会使用hashtable作为集合的内部实现

  1. 当元素个数超过512个, 内部编码变为hashtable

  2. 当某个元素不为整数时, 内部编码也会变为hashtable

开发场景

  • sadd=Tagging(标签)

  • spop/srandmember=Random item(生成随机数, 比如抽奖)

  • sadd+sinter=Social Graph(社交需求)

有序集合

有序集合保留了集合不能有重复成员的特性,但不同的是, 有序集合中的元素可以排序。 但是它和列表使用索引下标作为排序依据不同的是, 它给每个元素设置一个分数(score) 作为排序的依据。

有序集合中的元素不能重复, 但是score可以重复

命令

添加成员
zadd key score member [score member ...]  

Redis3.2为zadd命令添加了nx、 xx、 ch、 incr四个选项:

  • nx: member必须不存在, 才可以设置成功, 用于添加。

  • xx: member必须存在, 才可以设置成功, 用于更新。

  • ch: 返回此次操作后, 有序集合元素和分数发生变化的个数

  • incr: 对score做增加, 相当于后面介绍的zincrby。

计算成员个数
zcard key  
计算某个成员的分数
zscore key member  
计算成员的排名

正序排名

zrank key member

逆序排名

zrevrank key member  
删除成员
zrem key member [member ...]  
增加成员的分数
zincrby key increment member  
返回指定排名范围的成员

正序

zrange key start end [withscores]

逆序

zrevrange key start end [withscores]  
返回指定分数范围的成员

正序

zrangebyscore key min max [withscores] [limit offset count]

逆序

zrevrangebyscore key max min [withscores] [limit offset count]  

withscores 选项会同时返回每个成员的分数。

[limit offset count] 选项可以限制输出的起始位置和个数

同时 minmax 还支持开区间( 小括号)闭区间( 中括号)-inf+inf 分别代表无限小和无限大

zrangebyscore seqset (1 (3 WITHSCORES
zrangebyscore seqset (1 +inf WITHSCORES
删除指定分数范围的成员
zremrangebyscore key min max  

集合间的操作

交集
zinterstore destination numkeys key [key ...] [weights weight [weight ...]] [aggregate sum|min|max]  
并集
zunionstore destination numkeys key [key ...] [weights weight [weight ...]] [aggregate sum|min|max]

  • destination: 交集计算结果保存到这个键。

  • numkeys: 需要做交集计算键的个数。

  • key[key...]: 需要做交集计算的键。

  • weights weight[weight...]: 每个键的权重, 在做交集计算时, 每个键中的每个member会将自己分数乘以这个权重, 每个键的权重默认是1。

  • aggregate sum|min|max: 计算成员交集后, 分值可以按照sum( 和) 、min( 最小值) 、 max( 最大值) 做汇总, 默认值是sum。

内部编码

ziplist

ziplist(压缩列表) : 当有序集合的元素个数小于zset-max-ziplistentries配置(默认128个) , 同时每个元素的值都小于zset-max-ziplist-value配置(默认64字节) 时, Redis会用ziplist来作为有序集合的内部实现, ziplist可以有效减少内存的使用。

  1. 当元素个数较少且每个元素较小时, 内部编码为skiplist

skiplist

skiplist(跳跃表) : 当ziplist条件不满足时, 有序集合会使用skiplist作为内部实现, 因为此时ziplist的读写效率会下降。

  1. 当元素个数超过128个, 内部编码变为 ziplist

  2. 当某个元素大于64字节时, 内部编码也会变为 skiplist

参考资料:《Redis 开发与运维》