Redis - 集合和有序集合类型
集合
1、简介
集合(set)类型也是用来保存多个字符串元素的,但和列表不同的是,集合中不允许存在重复元素,同时集合中的元素是无序的,不能通过索引下标获取元素。一个集合中最多可以存储2^32-1个元素。Redis中除了支持集合内的增删改查外,还支持多个集合间取交集、并集、差集。
2、常用命令
1)集合内操作
(1)添加
sadd key element [element ...]
返回结果为添加成功的元素个数。
(2)删除
srem key element [element ...]
返回结果为成功删除
(3)计数
scard key
scard命令不会遍历集合中所有的元素,而是直接使用redis内部的变量。
(4)判断元素是否存在
sismember key element
如果元素element存在,返回1,反之返回0。
(5)随机从集合中返回指定个数的元素
srandmember key [count]
[count]为可选项,如果不传,默认为1.
(6)从集合中随机弹出元素
spop key
从Redis3.2开始,spop也支持[count]参数。
spop和srandmember都能从集合中随机取出元素,不同的是,spop命令会把元素从集合中删除,而srandmember不会改变集合。
(7)获取所有元素
smembers key
smembers属于比较重的命令,如果元素过多的时候,会存在阻塞Redis的可能性,可以使用scan进行代替完成。
2)集合间操作
(1)多个集合之间的交集
sinter key [key ...]
(2)多个集合之间的并集
sunion key [key ...]
(3)多个集合之间的差集
sdiff key [key ...]
(4)将交集、并集、差集的结果保存
sinterstore new_key key [key ...]sunionstore new_key key [key ...]sdiffstore new_key key [key ...]
集合间的运算在元素较多时,会比较耗时,所以Redis提供了上面三个命令,可以将集合间交集、并集、差集的结果存储到new_key中,new_key本身也是集合类型。
3、内部编码
集合类型的内部编码有两种:
- intset(整数集合)
当集合中的元素都是整数,并且元素个数小于set-max-intset-entries配置(默认512)时,Redis会选择intset来作为集合的内部实现,从而减少内存的使用。
- hashtable(哈希表)
当集合类型无法满足intset的条件时,Redis会使用hashtable作为集合的内部实现。
(1)元素个数超过512个时,内部编码使用hashtable
(2)当某个元素不是整数时,内部编码也会使用hashtable
4、使用场景
集合使用的典型场景为标签(tag)例如一个文章属于历史类,同时也属于教育类,另一个文章属于新闻类,这些类别就是文章的标签。有了这些数据,就可以得到属于某一个标签的文章有哪些等。
除了标签系统可以使用集合外,使用到随机数类型的系统(比如抽奖)也是集合的一个使用场景,使用spop或者srandmember命令,随机从集合中抽取中奖信息。
有序集合
1、简介
有序集合保留了集合不能有重复元素的特性,但不同的是,它内部的元素是可以排序的。只是排序时,和列表使用下标作为排序依据不同,有序集合会给每个元素设置一个分数(score)作为排序依据。有序集合内的元素不能重复,但是元素的score是可以相同,就和一个公司内每个员工的工号可以不同,但是绩效得分是可以相同是一个道理。
2、常用命令
1)集合内操作
(1)添加
zadd key score element [score element ...]
返回结果为成功添加元素的个数。
在Redis3.2以后,为zadd添加了nx、xx、ch、incr四个选项
- nx:element必须存在,才可以设置成功,用于添加
- xx:element必须不存在,才可以设置成功,用于更新
- ch:返回此次操作后,有序集合元素和分数发生变化的个数。
- incr:对score做增加
(2)计数
zcard key
(3)计算元素的分数
zscore key element
(4)计算成员的排名
zrank key elementzrevrank key element
zrank是从分数从低到高返回排名,zrevrank反之。
(5)删除成员
zrem key element [element ...]
返回结果为成功删除的个数。
(6)增加成员的分数
zincrby key increment element
(7)返回指定排名范围内的元素
zrange key start end [withscore]zrevrange key start end [withscore]
有序集合是按照得分排名的,zrange是从低到高返回,zrevrange反之,如果加上withscore参数,则会同时返回成员的分数。
(8)返回指定分数范围内的元素
zrangebyscore key min max [withscore] [limit offset count]zrevrangebyscore key min max [withscore] [limit offset count]
zrangebyscore 按照分数从低到高返回,zrevrangebyscore反之,withscore选项会同时返回每个元素的得分,limit offset count 选项会限制输出的起始位置和个数。
min和max参数支持开区间(小括号)和闭区间(大括号),-inf和+inf分别代表 无限小和无限大。
(9)返回指定得分范围的元素个数
zcount key min max
(10)删除指定排名内的元素
zremrangebyrank key start end
2)集合间操作
(1)交集
zinterstore new_key numkeys key [key ...] [weights weight [weight ...]] [aggregate sum|min|max]
命令参数说明如下:
- new_key:交集计算结果保存到这个新键中
- numkeys:需要做交集计算的键的个数
- key [key …]:需要做交集的键
- weights weight [weight …]:计算每个键的权重,在做交集计算的时候,为每个元素的分数乘以权重值,得到新的集合中的元素的得分
- aggregate sum|min|max:计算元素交集后,分值可以按照sum(和)、min(最小值)、max(最大值)做汇总,默认值是sum
(2)并集
zunionstore new_key numkeys key [key ...] [weights weight [weight ...]] [aggregate sum|min|max]
该命令的参数和zinterstore命令参数完全相同,只不过做的是并集操作。
3、内部编码
有序集合类型有两种内部编码格式:
-
ziplist(压缩列表)
当有序集合的元素个数小于zset-max-ziplist-entries配置(默认128个),同时每个元素的值都小于zset-max-ziplist-value配置(默认64个字节)时,Redis会使用ziplist作为有序集合的内部实现,ziplist可以有效地额减少内存的消耗。
-
skiplist(跳跃列表)
当ziplist条件不满足的时候,有序集合会使用skiplist作为内部的实现,因为此时ziplist的读写效率会下降。
4、使用场景
有序集合最典型的使用场景就是排行榜系统,对博客进行各个维度的统计,生成排行榜信息。
阅读世界,共赴山海
423全民读书节,邀你共读