有序集合相对于哈希、 列表、 集合来说会有一点点陌生, 但既然叫有序集合, 那么它和集合必然有着联系, 它保留了集合不能有重复成员的特性,但不同的是, 有序集合中的元素可以排序。 但是它和列表使用索引下标作为排序依据不同的是, 它给每个元素设置一个分数(score) 作为排序的依据。 如图所示, 该有序集合包含kris、 mike、 frank、 tim、 martin、 tom,它们的分数分别是1、 91、 200、 220、 250、 251, 有序集合提供了获取指定分数和元素范围查询、 计算成员排名等功能, 合理的利用有序集合, 能帮助我们在实际开发中解决很多问题。
有序集合中的元素不能重复, 但是score可以重复, 就和一个班里的同学学号不能重复, 但是考试成绩可以相同。比如在排行榜这个场景中使用有序集合。
1.集合内
添加成员
zadd key score member [score member …]
返回结果代表成功添加成员的个数
有关zadd命令有两点需要注意:
·Redis3.2为zadd命令添加了nx、 xx、 ch、 incr四个选项:
·nx: member必须不存在, 才可以设置成功, 用于添加。
·xx: member必须存在, 才可以设置成功, 用于更新。
·ch: 返回此次操作后, 有序集合元素和分数发生变化的个数
·incr: 对score做增加, 相当于后面介绍的zincrby。
有序集合相比集合提供了排序字段, 但是也产生了代价, zadd的时间复杂度为O(log(n) ) , sadd的时间复杂度为O(1)
(2) 计算成员个数
zcard key
和集合类型的scard命令一样, zcard的时间复杂度为O(1)。
(3) 计算某个成员的分数
zscore key member
如果成员不存在则返回nil
(4) 计算成员的排名
zrank key member
zrevrank key member
zrank是从分数从低到高返回排名, zrevrank反之
(5) 删除成员
zrem key member [member …]
返回结果为成功删除的个数。
(6) 增加成员的分数
zincrby key increment member
(7) 返回指定排名范围的成员
zrange key start end [withscores]
zrevrange key start end [withscores]
有序集合是按照分值排名的, zrange是从低到高返回, zrevrange反之。下面代码返回排名最低的是三个成员, 如果加上withscores选项, 同时会返回成员的分数。
(8) 返回指定分数范围的成员
zrangebyscore key min max [withscores] [limit offset count]
zrevrangebyscore key max min [withscores] [limit offset count]
其中zrangebyscore按照分数从低到高返回, zrevrangebyscore反之。withscores选项会同时返回每个成员的分数。 [limit offset count]选项可以限制输出的起始位置和个数。
同时min和max还支持开区间(小括号) 和闭区间(中括号) , -inf和+inf分别代表无限小和无限大。
(9) 返回指定分数范围成员个数
zcount key min max
(10) 删除指定排名内的升序元素
zremrangebyrank key start end
下面操作删除第start到第end名的成员
(11) 删除指定分数范围的成员
zremrangebyscore key min max
2.集合间的操作
(1) 交集
zinterstore 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
(2) 并集
zunionstore destination numkeys key [key …] [weights weight [weight …]][aggregate sum|min|max]
该命令的所有参数和zinterstore是一致的, 只不过是做并集计算。
内部编码
有序集合类型的内部编码有两种:
·ziplist(压缩列表) : 当有序集合的元素个数小于zset-max-ziplistentries配置(默认128个) , 同时每个元素的值都小于zset-max-ziplist-value配置(默认64字节) 时, Redis会用ziplist来作为有序集合的内部实现, ziplist可以有效减少内存的使用。
·skiplist(跳跃表) : 当ziplist条件不满足时, 有序集合会使用skiplist作为内部实现, 因为此时ziplist的读写效率会下降。