作者 / 以码为梯
排版 / 以码为梯
文章字数 / 3643
阅读时长 / 10分钟
希望大家可以从本文有所收获[握手]
有序集合作为集合的一种,它的成员也是唯一的,跟无序集合不同的是有序集合中每个成员都关联了一个用于排序的分数值(score)。有序集合中成员不能重复,但是每个成员对应的分数是可以重复的。有序集合中默认是按照分数值从小到大的方式对成员进行排序,对于分数值一样的成员依据字典序(lexicographical order)进行排序。
有序集合可以算是Redis中最复杂的数据类型,相对于无序集合多出了获取某范围之间的成员以及删除最大、最小、删除范围之间的成员等范围以及顺序相关的操作。
下面我们从新增成员、查询成员相关信息、删除成员、修改成员以及集合间操作这五个方面来了解有序集合相关的操作。
新增成员
Redis中使用ZADD命令来完成新增有序集合中成员的工作,该命令的语法如下:
ZADD key [NX|XX] [GT|LT] [CH] [INCR] score member [score member …]
从命令的语法中可以看出在新增成员时需要提供成员对应的分数值(score),而且命令还可以接收多个成员/分数值对,也就是说可以同时插入多个成员。
如果新增的成员已经存在于集合中,则会更新成员对应的分数值,并根据新的分数值调整成员的位置以保证正确的排序。在键对应的集合不是有序集合时,执行该命令会返回错误。
在插入的成员对应的分数值相同时,成员按照字典序排序。
命令中的分数值应该是双精度浮点数的字符串表示形式。+inf和-inf也是合法的,它们分别表示正无穷大和负无穷大。
最简单的ZADD命令是 ZADD key score member,另外ZADD命令还提供了可选项来实现各种不同的功能。
NX|XX
XX表示只更新已经存在于集合中的成员的分数值;NX表示只插入新的成员,不去更新已经存在的成员。
GT|LT
GT表示只有新的分数值大于对应的已经存在的成员的分数值时才会更新;LT表示只有新的分数值小于对应的已经存在的成员的分数值时才会更新。
这两个选项都是跟更新分数值相关的,所以不能跟NX选项同时使用。这两个选项单独使用时会插入集合中不存在的新成员,但选项结合XX使用时则只会更新已经存在于集合中的成员的分数值。
CH
该选项的作用是将命令的返回值从返回新增成员的个数修改为返回发生变化的成员的个数。
INCR
在添加了INCR选项之后,命令的作用变为将成员对应的分数值加上新的分数值且只能接收一个分数值/成员对,并返回成员新的分数值;在插入的成员不存在时命令不会报错而是把新成员插入有序集合并返回对应的分数值。
查询成员相关信息
在查询成员相关的信息时会有涉及到范围的命令,这时我们就需要考虑边界值的问题。在这些命令中默认情况下的范围是包含边界值的,但是可以通过在参数前面加上"("来表示不包含边界值。
查询成员相关信息的命令包括查询有序集合中成员的个数、查询有序集合中成员的分数值、获取有序集合中的成员、获取有序集合中成员的排名。
查询有序集合中成员的个数
Redis中ZCARD、ZCOUNT、ZLEXCOUNT这三个命令用于查询有序集合中成员的个数。其中ZCARD是查询集合中所有成员的个数,ZCOUNT是查询分数值在指定范围内的成员的个数、ZLEXCOUNT是查询字典序在指定范围的成员个数。三个命令的语法如下:
ZCARD key
ZCOUNT key min max
ZLEXCOUNT key min max
查询有序集合中成员的分数值
Redis中ZSCORE、ZMSCORE用于查询有序集合中成员的分数值。ZSCORE用于查询单个成员的分数值、ZMSCORE用于查看多个成员的分数值。在指定的成员不存在时,在返回结果中其分数值为(nil)。两个命令的语法如下:
ZSCORE key member
ZMSCORE key member [member ...]
获取有序集合中的成员
Redis中获取有序集合的方式主要有随机获取、范围获取、迭代器获取这三类。
随机获取
Redis中ZRANDMEMBER命令用于从有序集合中获取随机count个成员。该命令的语法如下:
ZRANDMEMBER key [count [WITHSCORES]]
命令中的count选项用于控制获取成员的个数。
count>0时返回的不重复的成员而且在count大于集合中成员个数时,返回集合中所有成员。
count<0时返回的成员可以重复,返回的成员的个数是count的绝对值个。
WITHSCORES选项用于在返回结果中带上成员对应的分数值。
范围获取
范围获取的命令包含ZRANGE 、ZRANGEBYSCORE、ZRANGEBYLEX、ZREVRANGE、ZREVRANGEBYSCORE、ZREVRANGEBYLEX,这些命令中我们只介绍ZRANGE(其余的命令都可以通过ZRANGE加上该命令的选项来完成相同效果);
ZRANGESTORE命令是将获取的成员保存到另一个有序集合。
命令ZRANGE的语法如下:
ZRANGE key min max [BYSCORE|BYLEX] [REV] [LIMIT offset count] [WITHSCORES]
命令ZRANGE中范围默认是索引(排名),且范围是包含两端的。索引可以为正数也可以为负数,索引为正数时0表示第一个成员,1表示第二个成员,以此类推;索引为负数时-1表示最后一个成员,-2表示倒数第二个成员,以此类推。
使用BYSCORE选项将范围调整为分数值范围;范围默认是包含两端的,可以在参数前面加上"("来表示不包含;使用-inf和+inf来表示负无穷大和正无穷大。
使用BYLEX将范围调整为字典序范围;范围必须以"("或"["为前缀,"("表示不包含,"["表示包含。
REV选项用于颠倒默认顺序(将顺序调整为从高分到低分的排序,如果按字典排序就调整为从后往前);
LIMIT选项用于获取范围的一个子集(LIMIT命令只能跟BYSCORE和BYLEX一起使用);
WITHSCORES用于在返回数组中包含成员对应的分数值。
迭代器获取
在集合中成员很多时,一次性从集合中取出所有的成员会造成服务阻塞,因此Redis提供了增量迭代的方式(ZSCAN)来获取集合中的成员。命令的格式为:
ZSCAN key cursor [MATCH pattern] [COUNT count]
获取有序集合中成员的排名
Redis中使用ZRANK、ZREVRANK命令获取指定成员的排名(排名是从0开始的),在成员不存在时返回nil。ZRANK是按照分数值从低到高排名;ZREVRANK是按照分数值从高到低排名;两个命令的语法如下:
ZRANK key member
ZREVRANK key member
删除成员
删除最大或最小成员
Redis中使用ZPOPMAX和ZPOPMIN以及它们的阻塞版本BZPOPMAX、BZPOPMIN来删除有序集合中分数值最大的和最小的成员,命令执行成功返回被删除的成员以及对应的分数值。两个命令的语法如下:
ZPOPMAX key [count]
ZPOPMIN key [count]
删除指定的成员
Redis中使用ZREM删除指定的成员,命令会忽略有序集合中不存在的成员,命令执行成功会返回被删除的成员的个数。在键对应的数据类型不是有序集合时命令会报错。命令的格式如下:
ZREM key member [member ...]
范围删除
Redis中使用ZREMRANGEBYRANK、ZREMRANGEBYSCORE、ZREMRANGEBYLEX来进行范围删除。三个命令的语法如下:
ZREMRANGEBYRANK key start stop
ZREMRANGEBYSCORE key min max
ZREMRANGEBYLEX key min max
ZREMRANGEBYRANK是以排名作为范围来删除成员,排名从0开始算;
ZREMRANGEBYSCORE是以分数值作为范围来删除成员,边界值默认是包含的,可以在参数前加上(来表示不包含;
ZREMRANGEBYLEX是以字典序作为范围来删除成员,参数必须以[或(为前缀。
修改成员
Redis中使用ZINCRBY命令来增加指定成员的分数值,命令返回修改之后的分数值。命令的格式如下:
ZINCRBY key increment member
当increment值小于0时,其实对成员的分数值做的是减法操作。
集合间操作
跟无序集合一样,有序集合之间也可以进行差集、交集、并集操作。
集合间的差集
Redis中使用ZDIFF、ZDIFFSTORE命令来实现集合之间的差集,ZDIFFSTORE命令把差集保存到另一个有序集合。在获取集合间的差集时成员的分数值是不需要考虑的。具体的命令如下:
ZDIFF numkeys key [key ...] [WITHSCORES]
ZDIFFSTORE destination numkeys key [key ...]
集合间的交集
Redis中使用ZINTERCARD来获取集合的交集的个数;使用ZINTER、ZINTERSTORE来获取集合的交集成员。
ZINTERCARD的功能比较简单,只是返回交集成员个数,命令语法如下:
ZINTERCARD numkeys key [key ...]
但是,我们在获取交集成员的时候需要考虑一个问题,那就是交集成员的分数值该如何设置?
举例来说就是,集合A中有成员a 1,集合B中有成员 a 2,当获取集合A和B的交集的时候,成员肯定是a,但是a对应的分数值该怎么取?是获取集合A中的a的分数值1,还是获取集合B中的a的分数值2,还是将两者的分数值相加?另外需不需给集合中分数值设置权重?
针对上面的问题,Redis提供了两个参数WEIGHTS、AGGREGATE,具体的命令语法如下:
ZINTER numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX] [WITHSCORES]
ZINTERSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX]
其中WEIGHTS用于控制集合中成员的权重(默认为1),AGGREGATE用于设置该如何设置交集成员的分数值(默认为SUM)。
集合间的并集
Redis中使用ZUNION、ZUNIONSTORE完成集合的并集,因为并集也需要判断相同成员的分数值,所以跟获取交集一样,也提供了WEIGHTS和AGGREGATE两个参数,命令的语法如下:
ZUNION numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX] [WITHSCORES]
ZUNIONSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX]
到这里这篇关于Redis中有序集合相关的命令就结束了,希望对大家能有些许帮助。
[奋斗]各位看官点赞评论转发再走呗[奋斗]