一、基本操作

有序集合也是集合的一种,顾名思义,它和集合的不同之处在于它是有序的 ,而集合无序。它通过给集合中每一个元素都关联一个分数来是的元素有序,同时提供了多个方式获取排序之后的元素。

1.1 增加和删除元素

增加元素:

ZADD key score member [score member ...]

当key不存在时自动创建,分数支持整数和双精度浮点数,同时还可以使用+inf-inf分别表示正无穷大和负无穷大。执行成功返回添加的元素个数。

删除元素:

ZREM key member [member ...]

移除元素,返回成功移除的个数。

示例:

# 增加元素
127.0.0.1:6379> zadd age 24 maqian 25 xiaoming 26 xiaobai
(integer) 3
# 移除元素
127.0.0.1:6379> zrem age maqian
(integer) 1

1.2 获取元素

获取元素有以下几个操作:

# 获取有序集合中元素的数量
ZCARD key
# 获取某个元素的分数
ZSCORE key member
# 获取某个元素的排名(正序)
ZRANK key member
# 获取某个元素的排名(逆序)
ZREVRANK key member

注意事项:所有的排名都是从0开始的。

# 添加一个有序集合
127.0.0.1:6379> zadd age 24 xiaoming 25 xiaobai 26 xiaojiang
(integer) 3
# 获取集合的元素个数
127.0.0.1:6379> zcard age
(integer) 3
# 获取xiaobai的分数
127.0.0.1:6379> zscore age xiaobai
"25"
# 获取xiaojiang的排名
127.0.0.1:6379> zrank age xiaojiang
(integer) 2
# 获取xiaojiang的排名,逆序
127.0.0.1:6379> zrevrank age xiaojiang
(integer) 0

除了上面的几个操作以外,有序集合还提供了一些其他的api:

# 返回索引在[start, stop]之间的元素
ZRANGE key start stop [WITHSCORES]
ZREVRANGE key start stop [WITHSCORES]
# 获取分数范围在[min, max]之间的元素
ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]
# 获取分数范围在[min, max]之间的元素个数
`ZCOUNT key min max`

默认情况下,redis只返回元素的key,不会返回分数。WITHSCORES的作用就是在返回key的同时还返回分数。

1.3 增加分数

member成员增加分数increment,返回值是更改后的分数:

ZINCRBY key increment member

示例:

127.0.0.1:6379> zincrby age 2 xiaojiang
"28"

1.4 根据条件删除元素

删除指定范围的元素:

# 删除排名在[start, end]之间的元素
ZREMRANGEBYRANK key start end
# 删除分数在[min, max]之间的元素
ZREMRANGEBYSCORE key min max

二、编码和原理

有序集合内部使用ziplistskiplist来编码,当集合满足下面两个条件时,对象使用ziplist,否则使用skiplist

  1. 集合的元素个数小于128
  2. 所有元素的长度小于64

当条件不足时,redis会自动转换编码。一个转换示例:

127.0.0.1:6379> zadd age 10 nginx
(integer) 1
127.0.0.1:6379> object encoding age
"ziplist"
# 添加一个长度超过64的key,...是省略的60个字符
127.0.0.1:6379> zadd age 10 wwwwwww...wwwwwwww
(integer) 1
# 编码转换成skiplist
127.0.0.1:6379> object encoding age
"skiplist"

除了用链表以外,有序集合还是用了哈希表作为底层实现之一。哈希表保存了所有节点和分数的对应关系,它的作用主要是方便定位元素位置,在O(1)的时间内找到元素。否则,根据跳跃表的特性,需要(logN)的时间才能找到数据,对于集合而言效率太低了。

字典里面保存了所有节点和分数的对应关系,但是所有的对象节点并不是额外再创建的,它是直接用的跳跃表中元素的节点,这样避免了占用额外空间,二来还可以直接定位到对应节点地址,方便修改。

有序集合内部结构图如图所示:

最后修改:2020 年 02 月 17 日
如果觉得我的文章对你有用,请随意赞赏