Redis Sorted Set类型介绍

xiaoxiao2021-02-28  125

Redis Sorted Set类型介绍

Sorted set是Redis的一种数据类型,与set类型和hash类型的混合相似。同set类型一样,sorted set中的元素都是惟一的,不能重复的字作串元素。所以在某些场景下,sorted set类型同set类型一样。

但是set类型对象中元素是无序的,而sorted set类型对象中的每个元素都与一个叫做score的浮点值相关联(这也是为什么说它与hash类型相似,因为它的每个元素同样都映射一个值)。

此外,sorted set中的元素是按次序被取出的(所以他们不是基于请求被排序的,有序性是sorted set数据结构的一个特征)。sorted set中的元素按照如下规则排序:

如果A元素与B元素对应的score值不一样,那么对应score大的那个元素大。如果A元素与B元素对应的score值相同,那么按字典顺序比较A与B字符串(A字符串与B字符串是不可能相等的,因为sorted set中元素惟一)。

让我们以一个简单的例子开始,添加一些黑客的名字作为sorted set的元素,用他们的出生的年作为score值:

>zadd hackers 1940 "Alan Kay" (integer) 1 >zadd hackers 1957 "Sophie Wilson" (integer) 1 >zadd hackers 1949 "Anita Borg" (integer) 1 >zadd hackers 1965 "Yukihiro Matsumoto" (integer) 1 >zadd hackers 1914 "Hedy Lamarr" (integer) 1 >zadd hackers 1916 "Claude Shannon" (integer) 1 >zadd hackers 1969 "Linus Torvalds" (integer) 1 >zadd hackers 1912 "Alan Turing" (integer) 1

正如你看到的,ZADD命令与SADD命令类似,但是多取了一个参数(放在要添加元素之前),就是score。ZADD命令也支持批量操作,所以即使上面的例子没用,你也可以自由的指定多个score-value对。

对于此sorted set,要返回一个按照黑客出生年排序的黑客列表是无意义的,因为实际上,他们已结排过序了。

注:Redis Sorted set是通过双端品数据结构实现的,包含一个skip list 和 一个hash组成,所以我们在sorted set上添加一个元素操作的时间复杂度为O(log(N))。这样虽然很好,但是当我们请求对元素进行排序的时候,redis将什么都不会做,因为已经排过序了:

>zrange hackers 0 -1 1)"Alan Turing" 2)"Hedy Lamarr" 3)"Claude Shannon" 4)"Alan Kay" 5)"Anita Borg" 6)"Richard Stallman" 7)"Sophie Wilson" 8)"Yukihiro Matsumoto" 9)"Linus Torvalds"

注:0和-1表示从索引为0的元素到最后一个元素(同LRANGE命令相似)。

如果想要与现有排序相反,如从年轻到到最老的,可以使用ZREVRANGE命令。

>zrevrange hackers 0 -1 1)"Linus Torvalds" 2)"Yukihiro Matsumoto" 3)"Sophie Wilson" 4)"Richard Stallman" 5)"Anita Borg" 6)"Alan Kay" 7)"Claude Shannon" 8)"Hedy Lamarr" 9)"Alan Turing"

也可以连同score一块输出,使用WITHSCORES参数:

>zrange hackers 0 -1 withscores 1)"Alan Turing" 2)"1912" 3)"Hedy Lamarr" 4)"1914" 5)"Claude Shannon" 6)"1916" 7)"Alan Kay" 8)"1940" 9)"Anita Borg" 10)"1949" 11)"Richard Stallman" 12)"1953" 13)Sophie Wilson" 14)"1957" 15)"Yukihiro Matsumoto" 16)"1965" 17)"Linus Torvalds" 18)"1969"

范围操作

ZRANGEBYSCORE命令可用于范围查询操作,如获取出生的年小于等于1950的个体:

>zrangebyscore hackers -inf 1950 1)"Alan Turing" 2)"Hedy Lamarr" 3)"Claude Shannon" 4)"Alan Kay" 5)"Anita Borg"

这个命令或解释为我们向Redis请求返回所有score值在负无穷和1950(两端边界都包含)之间的元素。-inf表示负无穷。

ZREMRANGEBYSCORE命令可用于范围删除操作,如要删除出生年在1940和1960之间的黑客:

>zremrangebyscore hackers 1940 1960 (integer) 4

ZREMRANGEBYSCORE也许不是最好命令名称,但却非常有用,并且返回被删除元素的个数。

另外一个对于sorted set元素极其有用的操作ZRANK是获取排名操作,用于获取元素在sorted set集合中的位置:

>zrank hackers "Linus Torvalds" (integer) 4

同样的,ZREVRANK命令为获取元素从相反方向开始的位置。

Lexicographical(词典顺序的) scores

在Redis 2.8中,新增了一个可以按词典顺序排序的功能。sorted set所有元素的词典顺序比较使用C语言的memcmp函数,没有做任何调整,可以放心使用,任何Redis实例都会给出相同的结果。

用于sorted set词典相关命令主要有:ZRANGEBYLEX,ZREVRANGEBYLEX,ZREMRANGEBYLEX和ZLEXCOUNT。

>zadd hackers01 0 "Alan Kay" 0 "Sophie Wilson" 0 "Richard Stallman" 0 "Anita Borg" 0 "Yukihiro Matsumoto" 0 "Hedy Lamarr" 0 "Claude Shannon" 0 "Linus Torvalds" 0 "Alan Turing" (integer) 9

由于Sorted set的排序规则,这上面的元素都已经按照词典顺序排序过了:

>zrange hackers 0 -1 1)"Alan Kay" 2)"Alan Turing" 3)"Anita Borg" 4)"Claude Shannon" 5)"Hedy Lamarr" 6)"Linus Torvalds" 7)"Richard Stallman" 8)"Sophie Wilson" 9)"Yukihiro Matsumoto"

我们可以使用ZRANGEBYLEX命令根据词典顺序获取一定范围的值:

>zrangebylex hackers [B [P 1)"Claude Shannon" 2)"Hedy Lamarr" 3)"Linus Torvalds"

更新score:排行榜

关于sorted set集合最后要注意的是:Sorted set的scores在任何时候都可能被更改。仅仅需要调用ZADD添加一个集合中已存在的元素,Redis就会自动做一个时间复杂度为O(log(N))的更改sorted set的scores和位置的操作。因此,sorted set适用于需要大量更新操作的场景。

注:因为这个特征,一个通常使用场景就是排行榜。

转载请注明原文地址: https://www.6miu.com/read-21633.html

最新回复(0)