Redis sorted set 类型操作及常用命令

Redis sorted set 类型操作及常用命令

Scroll Down

七个原则

  1. Redis 是一个操作数据结构的语言工具,它提供基于 TCP 的协议以操作丰富的数据结构。在 Redis 中,数据结构这个词的意义不仅表示在某种数据结构上的操作,更包括了结构本身及这些操作的时间空间复杂度。
  2. Redis 定位于一个内存数据库,正是由于内存的快速访问特性,才使得 Redis 能够有如此高的性能,才使得 Redis 能够轻松处理大量复杂的数据结构, Redis 会尝试其它的存储方面的选择,但是永远不会改变它是一个内存数据库的角色。
  3. Redis 使用基础的 API 操作基础的数据结构, Redis 的 API 与数据结构一样,都是一些最基础的元素,你几乎可以将任何信息交互使用此 API 格式表示。作者调侃说,如果有其它非人类的智能生物存在,他们也能理解 Redis 的 API。因为它是如此的基础。
  4. Redis 有着诗一般优美的代码,经常有一些不太了解 Redis 有的人会建议 Redis 采用一些其它人的代码,以实现一些 Redis 未实现的功能,但这对我们来说就像是非要给《红楼梦》接上后四十回一样。
  5. Redis 始终避免复杂化,我们认为设计一个系统的本质,就是与复杂化作战。我们不会为了一个小功能而往源码里添加上千行代码,解决复杂问题的方法就是让复杂问题永远不要提复杂的问题。
  6. Redis 支持两个层成的 API,第一个层面包含部分操作 API,但它支持用于分布式环境下的 Redis。第二个层面的 API 支持更复杂的 multi-key 操作。它们各有所长,但是我们不会推出两者都支持的 API,但我们希望能够提供实例间数据迁移的命令,并执行 multi-key 操作。
  7. 我们以优化代码为乐,我们相信编码是一件辛苦的工作,唯一对得起这辛苦的就是去享受它。如果我们在编码中失去了乐趣,那最好的解决办法就是停下来。我们决不会选择让 Redis 不好玩的开发模式。

Sorted Set 类型及操作

sorted set 是 set 的一个升级版本, 它在 set 的基础上增加了一个顺序属性,这一属性在添加修改元素的时候可以指定,每次指定后, zset 会自动重新按新的值调整顺序。可以理解为有两列的 mysql 表,一列存 value,一列存顺序。操作中 key 理解为 zset 的名字。

和 set 一样 sorted set 也是 string 类型元素的集合,不同的是每个元素都会关联一个 double类型的 score。sorted set 的实现是 skip list 和 hash table 的混合体。

当元素被添加到集合中时,一个元素到 score 的映射被添加到 hash table 中,所以给定一个元素获取 score 的开销是 O(1),另一个 score 到元素的映射被添加到 skip list,并按照 score 排序,所以就可以有序的获取集合中的元素。添加,删除操作开销都是 O(log(N))和 skip list 的开销一致,redis 的 skip list 实现用的是双向链表,这样就可以逆序从尾部取元素。 sorted set 最经常的使用方式应该是作为索引来使用.我们可以把要排序的字段作为 score 存储,对象的 id 当元素存储。、

常用命令及操作

zadd

向名称为 key 的 zset 中添加元素 member, score 用于排序。如果该元素已经存在,则根据score 更新该元素的顺序。

127.0.0.1:6379> zadd myzset 1 Jacob
(integer) 1
127.0.0.1:6379> zadd myzset 2 Jacob2
(integer) 1
127.0.0.1:6379> zadd myzset 3 Jacob2
(integer) 0
127.0.0.1:6379> zrange myzset 0 -1 withscores
1) "Jacob"
2) "1"
3) "Jacob2"
4) "3"
zrem

删除名称为 key 的 zset 中的元素。

127.0.0.1:6379> zrem myzset Jacob2
(integer) 1
127.0.0.1:6379> zrange myzset 0 -1 withscores
1) "Jacob"
2) "1"
zincrby

如果在名称为 key 的 zset 中已经存在元素 member,则该元素的 score 增加 increment;否则向集合中添加该元素,其 score 的值为 increment。

127.0.0.1:6379> zrange myzset 0 -1 withscores
1) "Jacob"
2) "1"
127.0.0.1:6379> zincrby myzset 2 Jacob
"3"
127.0.0.1:6379> zrange myzset 0 -1 withscores
1) "Jacob"
2) "3"
zrank

返回名称为 key 的 zset 中 member 元素的排名(按 score 从小到大排序)即下标。

127.0.0.1:6379> zrange myzset 0 -1 withscores
1) "Jacob2"
2) "1"
3) "Jacob3"
4) "2"
5) "Jacob"
6) "3"
127.0.0.1:6379> zrank myzset Jacob3
(integer) 1

Jacob3 的下标是 1,我这里取的是下标,而不是 score 。

zrevrank

返回名称为 key 的 zset 中 member 元素的排名(按 score 从大到小排序)即下标。

127.0.0.1:6379> zrange myzset 0 -1 withscores
1) "Jacob2"
2) "1"
3) "Jacob3"
4) "2"
5) "Jacob"
6) "3"
127.0.0.1:6379> zrevrank myzset Jacob3
(integer) 1
zrevrange

返回名称为 key 的 zset(按 score 从大到小排序)中的 index 从 start 到 end 的所有元素。

127.0.0.1:6379> zrevrange myzset 0 -1 withscores
1) "Jacob"
2) "3"
3) "Jacob3"
4) "2"
5) "Jacob2"
6) "1"
zrangebyscore

返回集合中 score 在给定区间的元素。

127.0.0.1:6379> zrangebyscore myzset 2 3 withscores
1) "Jacob3"
2) "2"
3) "Jacob"
4) "3"
zcount

返回集合中 score 在给定区间的数量。

127.0.0.1:6379> zcount myzset 1 3
(integer) 3
127.0.0.1:6379> zcount myzset 1 2
(integer) 2
zcard

返回集合中元素个数。

127.0.0.1:6379> zrange myzset 0 -1 withscores
1) "Jacob2"
2) "1"
3) "Jacob3"
4) "2"
5) "Jacob"
6) "3"
127.0.0.1:6379> zcard myzset
(integer) 3
zscore

返回给定元素对应的 score 。

127.0.0.1:6379> zrange myzset 0 -1 withscores
1) "Jacob2"
2) "1"
3) "Jacob3"
4) "2"
5) "Jacob"
6) "3"
127.0.0.1:6379> zscore myzset Jacob
"3"
zremrangebyrank

从小到大排序,删除集合中排名在给定区间的下标元素。

127.0.0.1:6379> zrange myzset 0 -1 withscores
1) "Jacob2"
2) "1"
3) "Jacob3"
4) "2"
5) "Jacob"
6) "3"
127.0.0.1:6379> zscore myzset Jacob
"3"
127.0.0.1:6379> zremrangebyrank myzset 2 2
(integer) 1
127.0.0.1:6379> zrange myzset 0 -1 withscores
1) "Jacob2"
2) "1"
3) "Jacob3"
4) "2"
zremrangebyscore

从小到大排序,删除集合中 score 在给定区间的元素。

127.0.0.1:6379> zrange myzset 0 -1 withscores
1) "Jacob2"
2) "1"
3) "Jacob3"
4) "2"
127.0.0.1:6379> zremrangebyscore myzset 2 3
(integer) 1
127.0.0.1:6379> zrange myzset 0 -1 withscores
1) "Jacob2"
2) "1"