Redis 有序集合和集合一样也是string类型元素的集合,且不允许重复的成员。
不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。
有序集合的成员是唯一的,但分数(score)却可以重复。
集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。 集合中最大的成员数为 232 - 1 (4294967295, 每个集合可存储40多亿个成员)。
实例
排序根据以下规则:
- 如果A和B是两个具有不同分数的元素,则如果A.score是> B.score,则A>B。
- 如果A和B的得分完全相同,那么如果A字符串在字典上大于B字符串,则A>B。 A和B字符串不能相等,因为排序后的集合只有唯一的元素。
实例
> zadd hackers 1940 "Alan Kay"
(integer) 1
> zadd hackers 1957 "Sophie Wilson"
(integer 1)
> zadd hackers 1953 "Richard Stallman"
(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相似,但是采用了一个额外的参数(放置在要添加的元素之前)作为得分。 ZADD也是可变参数,因此即使在上面的示例中未使用它,您也可以自由指定多个得分-值对。
使用 sorted sets,返回按其出生年份排序的hackers列表很简单,因为实际上它们已经被排序了。
注意事项: sorted sets是通过包含跳跃表和哈希表的双端口数据结构实现的,因此,每次添加元素时,Redis都会执行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到最后一个元素(-1的工作方式与LRANGE命令的情况相同)。
与ZRANGE相反的排序可以使用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"
也可以使用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"
sorted sets可以在范围内操作,比如获取所有在1950年(含)之前出生的人,我们使用ZRANGEBYSCORE命令来做到这一点:
> zrangebyscore hackers -inf 1950
1) "Alan Turing"
2) "Hedy Lamarr"
3) "Claude Shannon"
4) "Alan Kay"
5) "Anita Borg"
我们要求Redis返回分数在负无穷大和1950之间的所有元素(包括两个极端)。
也可以删除元素范围。 让我们从sorted sets中删除所有1940年至1960年之间出生的hackers:
> zremrangebyscore hackers 1940 1960
(integer) 4
ZREMRANGEBYSCORE可能不是最好的命令名称,但是它可能非常有用,并返回已删除元素的数量。
为排序的集合元素定义的另一种极其有用的操作是get-rank操作。 可以问一个元素在有序元素集合中的位置是什么。
> zrank hackers "Anita Borg"
(integer) 4
考虑到元素以降序方式排序,ZREVRANK命令也可用于获得排名。