资讯专栏INFORMATION COLUMN

Redis有序集合类型

Flink_China / 2593人阅读

摘要:今天我们继续学习中的数据类型,今天我们学习有序集合类型,也是中的大数据类型中的最后一个。下面我们看一下列表集合有序集合的它们个数据类型之间的区别。

今天我们继续学习Redis中的数据类型,今天我们学习有序集合类型,也是Redis中的5大数据类型中的最后一个。看名字,我们就知道,有序集合也是一种集合,并且这个集合还是有序的。那有序集合和列表有什么不同呢?因为列表也是有序的。 它们到底有什么不同呢?有序集合的有序和列表的有序是不同的。列表中的有序指的的是插入元素的顺序,和查询元素的顺序相同。而有序集合中的有序指的是它会为每个元素设置一个分数(score),而查询时可以通过分数计算元素的排名,然后在返回结果。因为有序集合也是集合类型,所以有序集合中也是不插入重复元素的,但在有序集合中分数则是可以重复,那如果在有序集合中有多个元素的分数是相同的,那么这些重复的元素的排名是怎么计算的呢?在下面的内容中我们在做详细说明。下面我们看一下列表、集合、有序集合的它们3个数据类型之间的区别。

数据结构 是否允许重复元素 是否有序 有序实现方式 应用场景
列表 索引下标 时间轴、消息队列
集合 标签、社交
有序集合 分数 排行榜、社交

下面我们重点了解一下Redis中有序集合的相关命令。

命令

一、集合内

1.添加元素

zadd key [NX|XX] [CH] [INCR] score member [score member ...]

zadd命令也是有返回值的,返回值就是当前zadd命令成功添加元素的个数。除此之外,zadd命令还有很多其它的选填参数。下面我们详细了解一下:

nx: 元素必须不存在时,才可以设置成功。

xx: 元素必须存在时,才可以设置成功。

ch:

incr: 对score做增加。

备注:由于有序集合相比集合提供了排序字段,正是因为如此也付出了相应的代价,,zadd的时间复杂度为O(log(n)),sadd的时间复杂度为O(1)。


2.计算成员个数

zcard key


3.计算某个成员的分数

zscore key member

在使用zscore命令时,如果key不存在,或者元素不存在时,该命令返回的都是(nil)。


4.计算成员的排名

zrank key member
zrevrank key member

zrank命令是从分数低到高排名,而zrevrank命令则恰恰相反,从高到低排名。有一点要特别注意zrank和zrevrank命令与zscore命令不同的前者是通过分数计算出最后的排名,而后者则是直接返回当前元素的分数。


5.删除元素

zrem key member [member ...]

返回的结果为成功删除元素的个数,因为zrem命令是支持批量删除的。


6.增加元素分数

zincrby key increment member

虽然zincrby命令是增加元素分数的,但我们也可以指定负数,这样当前元素的分数,则会相减。


7.返回指定排名范围的元素

zrange key start stop [WITHSCORES]
zrevrange key start stop [WITHSCORES]

zrange命令是通过分数从低到高返回数据,而zrevrange命令是通过分数从高到低返回数据。如果执行命令时如果添加了WITHSCORES可选参数,而返回数据时会返回当前元素的分数。


8.返回指定分数范围的元素

zrangebyscore key min max [WITHSCORES] [LIMIT offset count]
zrevrangebyscore key max min [WITHSCORES] [LIMIT offset count]

min和max参数同时还支持开区间(小括号)和闭区间(中括号),同时我们还可以用-inf和+inf参数代表无限小和无限大。

备注:闭区间的没有验证成功,执行时会报错,这个有待验证。


9.返回指定分数范围元素个数

zcount key min max


10.删除指定指定排名内的升序元素

zremrangebyrank key start stop


11.删除指定分数范围元素

zremrangebyscore key min max


二、集合间操作

1.交集

zinterstore destination numkeys key [key ...] [WEIGHTS weight] [AGGREGATE SUM|MIN|MAX]

因为zinterstore命令参数比较多,所以下面我们详细了解一下:

destination:将交集的计算结果,保存到这个键中。

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

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

WEIGHTS weight:每个键的权重,在做交集计算时,每个键中的分数值都会乘以这个权重,默认每个键的权重为1。

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


下面我们将权重设置为0.5,这样当计算交集后,有序集合中的元素分数将都会减半,并且使用max参数汇总。


2.并集

zunionstore destination numkeys key [key ...] [WEIGHTS weight] [AGGREGATE SUM|MIN|MAX]

zunionstore命令的相关参数和zinterstore命令相同。


时间复杂度

下面我们了解一下上述命令的时间复杂度。

命令 时间复杂度
zadd key [NX/XX] [CH] [INCR] score member [score member ...] O(k*log(n)),k是添加元素的个数,n是当前有序集合元素个数
zcard key O(1)
zscore key member O(1)
zrank key member O(log(n)),n是当前有序集合元素个数
zrevrank key member O(log(n)),n是当前有序集合元素个数
zrem key member [member ...] O(k*log(n)),k是删除元素的个数,n是当前有序集合元素个数
zincrby key increment member O(log(n)),n是当前有序集合元素个数
zrange key start stop [WITHSCORES] O(log(n) + k),k是要获取的元素个数,n是当前有序集合个数
zrevrange key start stop [WITHSCORES] O(log(n) + k),k是要获取的元素个数,n是当前有序集合个数
zrangebyscore key min max [WITHSCORES] [LIMIT offset count] O(log(n) + k),k是要获取的元素个数,n是当前有序集合个数
zrevrangebyscore key max min [WITHSCORES] [LIMIT offset count] O(log(n) + k),k是要获取的元素个数,n是当前有序集合个数
zcount key min max O(log(n)),n是当前有序集合元素个数
zremrangebyrank key start stop O(log(n) + k),k是要删除的元素个数,n是当前有序集合个数
zremrangebyscore key min max O(log(n) + k),k是要删除的元素个数,n是当前有序集合个数
zinterstore destination numkeys key [key ...] [WEIGHTS weight] [AGGREGATE SUM/MIN/MAX] O(n k) + O(m log(m)),n是元素元素最小的有序集合元素个数,k是有序集合个数,m是结果集中元素个数
zunionstore destination numkeys key [key ...] [WEIGHTS weight] [AGGREGATE SUM/MIN/MAX] O(n) + O(m * log(m)),n是所有有序集合元素个数和,m是结果集中元素个数。

内部编码

有序集合类型的内部编码有两种,它们分别是:

ziplist(压缩列表):当有序集合的元素个数小于128个(默认设置),同时每个元素的值都小于64字节(默认设置),Redis会采用ziplist作为有序集合的内部实现。

skiplist(跳跃表):当上述条件不满足时,Redis会采用skiplist作为内部编码。

备注:上述中的默认值,也可以通过以下参数设置:zset-max-ziplist-entries和zset-max-ziplist-value。


下面我们用以下示例来验证上述结论。

1.当元素个数比较少,并且每个元素也比较小时,内部编码为ziplist:


2.当元素个数超过128时,内部编码为skiplist。下面我们将采用python动态创建128个元素,下面为源码:

import redis

r = redis.Redis(host="127.0.0.1", port=6379)

if r.object("encoding", "zsetkey") != None:
    print("Key为【zsetkey】的字节编码为【%s】" % r.object("encoding", "zsetkey").decode("utf-8"))

for i in range(1, 600):
    r.zadd("zsetkey",i,1)

if r.object("encoding", "zsetkey") != None:
    print("Key为【zsetkey】的字节编码为【%s】" % r.object("encoding", "zsetkey").decode("utf-8"))
Key为【zsetkey】的字节编码为【ziplist】
Key为【zsetkey】的字节编码为【skiplist】

3.当有序集合中有任何一个元素大于64个字节时,内部编码为skiplist。

import redis

r = redis.Redis(host="127.0.0.1", port=6379)

if r.object("encoding", "zsetkey") != None:
    print("Key为【zsetkey】的字节编码为【%s】" % r.object("encoding", "zsetkey").decode("utf-8"))

value = ""
for i in range(1, 600):
    value += str(i)

r.zadd("zsetkey",value,1)

if r.object("encoding", "zsetkey") != None:
    print("Key为【zsetkey】的字节编码为【%s】" % r.object("encoding", "zsetkey").decode("utf-8"))
Key为【zsetkey】的字节编码为【skiplist】


上述内容就是Redis中有序集合的内容,如有不正确的地方,欢迎留言,谢谢。


原文链接:http://jilinwula.com/article/...

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/36622.html

相关文章

  • 玩转Redis - 使用有序集合(sorted sets)实现投票游戏

    摘要:是求两个有序集合的并集,可以用来合并两个投票中所有参与的人的排行榜。经过考察技术方案和实现成本,决定采用提供的有序集合,实现投票过程和实时排名的展示,直接读取缓存,避免了非核心业务对数据库的突发高并发访问。 redis是一种提供多种数据类型的开源key-value存储系统,通常将数据全部存储在内存中。 showImg(https://segmentfault.com/img/remot...

    AndroidTraveler 评论0 收藏0
  • 玩转Redis - 使用有序集合(sorted sets)实现投票游戏

    摘要:是求两个有序集合的并集,可以用来合并两个投票中所有参与的人的排行榜。经过考察技术方案和实现成本,决定采用提供的有序集合,实现投票过程和实时排名的展示,直接读取缓存,避免了非核心业务对数据库的突发高并发访问。 redis是一种提供多种数据类型的开源key-value存储系统,通常将数据全部存储在内存中。 showImg(https://segmentfault.com/img/remot...

    LeoHsiun 评论0 收藏0
  • redis 数据类型及操作命令

    摘要:数据类型支持五种数据类型字符串,哈希,列表,集合及有序集合。类型是最基本的数据类型,类型的值最大能存储。集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是。 Redis 数据类型 Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。 String(字符串)String是最常用、最简单...

    K_B_Z 评论0 收藏0
  • redis 数据类型及操作命令

    摘要:数据类型支持五种数据类型字符串,哈希,列表,集合及有序集合。类型是最基本的数据类型,类型的值最大能存储。集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是。 Redis 数据类型 Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。 String(字符串)String是最常用、最简单...

    617035918 评论0 收藏0
  • Redis 数据类型

    摘要:简介是一个速度非常快的非关系数据库它可以存储键与种不同两类型的值之间的映射可以将存储在内存中的键值对持久到硬盘可以使用复制特性来扩展读性能还可以使用客户端分片来扩展写性能分片分片是一种将数据划分为多个部分的方法对数据的划分可以基于键包含的基 Redis 简介 Redis 是一个速度非常快的非关系数据库, 它可以存储键与 5 种不同两类型的值之间的映射. 可以将存储在内存中的键值对持久到...

    Flands 评论0 收藏0

发表评论

0条评论

Flink_China

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<