Sorted Set 类型
文章目录
- Sorted Set 类型
- zadd 命令
- zrange 命令
- zcard 命令
- zcount 命令
- zrevrange 命令
- zrangebyscore 命令
- zpopmax 命令
- bzpopmax 命令
- zpopmin 命令
- bzpopmin 命令
- zrank 命令
- zscore 命令
- zrem 命令
- zremrangebyrank 命令
- zremrangebyscore 命令
- zincrby 命令
- zinterstore 命令
- zunionstore 命令
前面文章讲解了 Set 类型,Set 类型有一个特点,就是集合中的元素是唯一的。而 Zset 类型(Sorted Set)不同,它是一个有序集合,集合中的每一个元素是由“两个单元组成的”,分别是: 元素本身+对应的分数,依靠这个分数,就维护了集合中元素的有序性,什么意思呢,举个例子:
在三国中,每一个武将都是有武力值的,我们根据武力值就可以对武将进行一个排名,如下图:
在 zset 类型中,默认是按照**“升序”**的方式排列的,提供了一组获取元素分数、元素范围查询等等功能命令,下面就来介绍一些主要并且常用的命令。
zadd 命令
使用 zadd 命令往有序集合中添加元素和分数,在不指定选项的情况下,如果元素已经存在,则更新分数,如果元素不存在,则添加元素及分数
语法:zadd key [NX | XX] [GT | LT] [CH] [INCR] score member [score member…….]
NX:只能添加新元素,如果元素已经存在,则不能修改已经存在的元素
XX:只能更新已经存在元素,如果元素不存在,不能添加新元素
CH:默认情况下,zadd 返回的是本次成功添加的元素个数,但指定这个选项之后,如果只是更新了分数,那么还会把更新分数的元素给计算上
LT:当前指定的元素必须存在,并且新的分数比当前元素的分数小,才会更新
GT:当前指定的元素必须存在,并且新的分数比当前元素的分数大,才会更新
INCR:将元素的分数加上指定的分数,此时只能指定一个元素和一个分数
score member:表示要添加的元素及分数,并且可以指定多个
操作演示:
- 不指定任何选项
zadd key score member
返回值*:成功添加的元素个数
时间复杂度:log(N),会先查找,再加入
- 指定 nx 选项
zadd key nx score member
返回值:成功添加元素的个数
时间复杂度:log(N),会先查找,再加入
使用 nx 选项添加“赵云”,因为“赵云”存在,所以并没有对 “赵云” 这个元素进行修改
因为 “关羽” 不存在,所以,就可以成功添加 “关羽”
- 指定 xx 选项
zadd key xx score member
返回值:0,就算修改分数成功,也会返回 0
时间复杂度:log(N),会先查找,在加入
使用 xx 选项,添加 “曹操”,因为曹操这个元素已经存在,所以,就只会更新“分数”
因为 “刘备” 不存在,所以,在使用 xx 选项进行添加时,也不会成功添加
- 指定 ch 选项
zadd key ch score member
返回值:成功添加以及更新的元素个数
时间复杂度:log(N)
修改 “曹操” 的分数为77,修改成功后,返回了一个0,但是,这个返回值就不太好,我们就无法知道我们是否已经修改成功
如果加上 ch 选项,那么,就也会将成功修改的元素数量返回,如下图:
修改曹操的分数为 95
- 指定 incr 选项
zadd key incr score member
返回值:修改之后的分数
给 “曹操” 加上 5 分
zrange 命令
查看有序集合中的元素
语法:zrange key start end [withscores]
【start end】 表示左右区间,获取指定区间内的元素,cong 0 开始,并且支持负数
withscores 选项表示将元素的分数也显示出来
时间复杂度:O(log(N) + M),此处 log(N) 要找start对应的位置,接下来就开始遍历,M 表示遍历的元素个数。
操作演示:
注意:在redis 中,对于字符,存储的是二进制数据,在获取的时候,获取的也是二进制数据,并不会进行“字符集编码”,所以,在使用 redis-cli 使用 Redis 客户端时,需要再加一个 – raw 选项才可以显示出来字符。
zcard 命令
获取有序列表中元素的个数
语法:zcard key
返回值:元素个数
时间复杂度:O(1)
操作演示:
zcount 命令
获取指定区间中元素的个数
语法:zcount key min max
min 表示左区间
max 表示右区间
并且是闭区间,是包含边界值的,如果不想包含边界值,可以使用 (min (max,这里的 min、max 表示下标,获取指定下标内的元素个数
返回值:元素的个数
时间复杂度:log(N)
注意:zcount 在计算元素个数的时候,是先根据分数找到元素,在根据元素获取到排名,两个排名再相减,就得到了元素的个数。
操作演示:
使用开区间,不包含 98
使用开区间,不包含98,也不包含100
注意:min 和 max 是可以写成浮点数的(zset 分数本身就是浮点数)
在浮点数中,存在两个特殊的数值:inf(无穷大)、-inf(负无穷大),下面演示以下:
也就是获取到所有的元素个数
zrevrange 命令
按照分数降序遍历打印
语法:zrevrange key start end [withscores]
返回值:所有元素降序排列
时间复杂度:O(N)
操作演示:
zrangebyscore 命令
按照分数查询元素,和上面的 zcount 类似,只不过,zcount是在下标区间内查询,而 zrangebyscore 是在指定的分数范围内查询,并获取到区间内的元素
语法:zrangebyscore key min max [withscores]
返回值:区间内的元素
时间复杂度:O(logN+M)
操作演示:
zpopmax 命令
删除有序集合中分数最高的 count 个元素
语法:zpopmax key [count]
返回值:返回删除的元素
时间复杂度:O(log(N)*M),M 表示删除元素的个数
操作演示:
注意:如果存在多个元素,分数相同,并且同时为最大值,zpopmax删除的时候,仍然删除其中一个,因为,在有序列表中,分数相同的元素在排序时会按照字典序来排,删除靠前的元素
bzpopmax 命令
zpopmax 的阻塞版本,如果有序集合为空,则进行阻塞,阻塞超过一定时间后,就停止阻塞等待,这里就可以把这个有序集合看成一个带有“阻塞功能”的优先级队列
语法:bzpopmax key [key……] timeout
这里的 timeout 单位是:秒
返回值:指定键中最大的元素
时间复杂度:O(logN)
操作演示:
当指定的 “键” 不存在时,就进行阻塞,下图中,设置的阻塞等待时间是 600 秒
在另一个Redis 客户端添加 key1 这个键,此时,正在阻塞的客户端会直接获取到里面的元素,返回的值包含三部分:“键” 、元素、分数
zpopmin 命令
删除有序集合中最小的元素
语法:zpopmin key [count]
时间复杂度:O(logN*M)
返回值:返回删除的元素
操作演示:
bzpopmin 命令
zpopmin 的阻塞版本,如果有序集合为空,则进行阻塞,阻塞超过一定时间后,就停止阻塞等待,这里就可以把这个有序集合看成一个带有“阻塞功能”的优先级队列
语法:bzpopmin key [key] timeout
可以同时监听多个 key ,哪个 key 不为空,就返回哪个 key 中最小的元素
返回值:删除成功的最小的元素
时间复杂度:O(logN)
这里和 bzpopmax 的用法一样,就不在演示。
zrank 命令
查看元素在有序集合中的位置(按照升序的方式查看)
语法:zrank key member
返回值:指定元素的位置
时间复杂度:O(logN)
操作演示:
zrevrank key member
这个是按照倒序的方式查看的
zscore 命令
查询指定元素的分数
语法:zscore key member
时间复杂度:O(1)
返回值:指定元素的分数
操作演示:
zrem 命令
删除指定的元素
语法:zrem key member [member]、
时间复杂度:O(logN *M)
返回值:表示删除成功的元素个数
操作演示:
zremrangebyrank 命令
删除指定范围内的元素
语法:zremrangebyrank key start end
时间复杂度:O(longN + M)
N 是有序集合的元素个数
M 是start - end 区间内的元素
[start,end] 这是闭区间
返回值:成功删除元素的个数
操作演示:
zremrangebyscore 命令
通过大小分数来指定一个删除的区间
语法:zremrangebyscore key min max
这里的 [min,max] 默认是闭区间,当然也可以通过 “(” 自定开区间
时间复杂度:O(logN+M)
返回值:成功删除元素的个数
操作演示:
删除[50,70] 之间的分数
zincrby 命令
给指定元素的分数加上指定的分数值
语法:zincrby key increment member
increment 表示要添加的指定分数值,也可以指定负数,这样就变成减法了
时间复杂度:O(logN)
返回值:加上分数后的值
操作演示:
给 v6 的分数加上10
zinterstore 命令
求指定的有序列表的交集、
语法:zinterstore destination numkeys key[key….] [weigths weight……] [aggregate < sum | min | max]
destination:表示存储交集结果的key
numskeys:表示key的数量
wieghts:给元素分配不同的权重,也就是让元素的分数*指定的权重
agrregate 表示求交集时,交集的结果中元素的分数应该按照哪种规定描述
返回值:交集结果
操作演示:
给 key1 中添加 v1-10、v2-20、v3-30、v4-40
给 key2 中添加 v3-10、v4-20、v5-30、v6-40
求得交集的结果为
注意:这里交集结果中元素的分数默认是是交集中相同元素分数的和,但是也可以通过选项指定分数的规则
zunionstore 命令
求指定的有序列表的并集
语法:zunionstore destination numkeys key[key….] [weigths weight……] [aggregate < sum | min | max]
返回值:并集的结果
操作演示:
以上是 zset 类型中主要并且常用命令的一个简单讲解,如果想要学习其他的命令可以参考官方文档:zset命令官方文档跳转链接