Redis数据结构和内部编码--有序集合(SortedSet)
Redis数据结构和内部编码--有序集合(SortedSet)
一. 概念
有序集合用来存储多个字符串元素,同时这些元素是有序无重复的。但是它和列表使用索引下标进行排序不同,它给每个元素设置一个分数(SCORE)做为排序依据。有序集合中元素不可以重复,但是元素的分数是可以重复的。此外,有序集合提供了获取指定分数和元素范围查询,计算成员排名等功能。
二. 命令
2.1 添加成员
命令:zadd key [nx|xx|ch|incr]score member[score member2…]
返回:成功添加成员的个数
例如:zadd zset1 1 v1 10 v2 20 v3 15 v4
返回:4
zadd命令添加了nx|xx|ch|incr四个选项:
nx:member必须不存在,才可以设置成功,用于添加
xx: member必须存在,才可以设置成功,用于修改
ch:返回此次操作后,有序集合元素和分数发生变化的个数
incr:对score做增加
2.2 计算成员个数
命令:zcard key
例如:zadd zset1 1 v1 10 v2 20 v3 15 v4
zcard zset1
返回:4
2.3 计算某个成员的分数
命令:zscore key member
例如:zadd zset1 1 v1 10 v2 20 v3 15 v4
zscore zset1 v2
返回:10
2.4 计算成员的排名
命令:(1)zrank key member 从低到高返回排名,分数最低的返回排名0
(2) zrevrank keymember从高到低返回排名,分数最高的返回排名0
例如:zadd zset1 1 v1 2 v2 3 v3 4 v4 5 v5
zrank zset1 v2
返回: 1
2.5 删除成员
命令:zrem key member[member2..] 返回成功删除成员的个数
例如:zadd zset1 1 v1 2 v2 3 v3 4 v4 5 v5
zrem zset1 v2 v3
返回: 2
2.6 增加成员分数
命令: zincrby key increment member
例如: zadd zset1 1 v1
zincrby zset1 2 v1
zrange zset1 0 -1
返回:3
v1
2.7 返回指定排名(按分数)范围的成员
命令:(1)zrange key start end [withscores]从低到高,增加withscores属性则显示分数
(2)zrevrange key start end [withscores] 从高到低,增加withscores属性则显示分数
例如:zadd zset1 1 v1 2 v2 3 v3 4 v4 5 v5
zrange zset1 1 3 withscores
返回:1) "v2"
2) "2"
3) "v3"
4) "3"
5) "v4"
例如:zadd zset1 1 v1 2 v2 3 v3 4 v4 5 v5
zrevrange zset1 1 3 withscores
返回:1) "v4"
2) "4"
3) "v3"
4) "3"
5) "v2"
6) "2"
2.8 返回指定分数范围的成员
命令:zrangebyscore key min max [withscores] [limit offset count],
选项:withscores—是否输出分数
limitoffset count---限制起始位置和个数
min和max支持开区间(小括号)和闭区间(中括号),+inf和-inf分别表示正负无穷大
例如: zadd zset1 10 v1 20 v2 30 v3 40 v4 50 v5
zrangebyscore zset1 20 50 withscores limit 0 4
返回:1) "v2"
2) "20"
3) "v3"
4) "30"
5) "v4"
6) "40"
2.9 返回指定分数范围成员个数
命令:zcount key min max
例如:zadd zset1 10 v1 20 v2 30 v3 40 v4 50 v5
zcount zset1 20 40
返回:3
2.10 删除指定排名内的升序元素
命令: zremrangebyrank key start end
例如:zadd zset1 10 v1 20 v2 30 v3 40 v4 50 v5
zremrangebyrank zset1 1 3
返回:3
继续查询:zrange zset1 0 -1
返回:v1
v5
2.11 删除指定分数范围的成员
命令: zremrangebyscore key min max
例如:zadd zset1 10 v1 20 v2 30 v3 40 v4 50 v5
zremrangebyscore zset1 10 30
返回:3
继续查询:zrange zset1 0 -1
返回:v4
v5
2.12 求多个集合的交集
命令:zinterstore destination numkeys key [key…][weights weight[weight…]] [aggregatesum|min|max]
选项:destination:交集计算结果保存到这个键中
numkeys:需要做交集计算的键的个数
key[key…]:需要做交集计算的键
weights weight[weight…]:每个键的权重,在做交集计算时,每个键中的每个member会将自己分数乘以这个权重,每个键的权重默认是1.
Aggregate sum|min|max:计算成员交集后,分值可以按照sum,min,max做汇总,默认值是sum。
例如:zadd zset1 10 v1 20 v2 30 v3 40 v4 50 v5 60 v6 [
zadd zset2 110 v1 120 v2 130 v3 140 v4 150 v5 160 v6
zinterstoreinterstoreset1 2 zset1 zset2 weights 1 0.05 aggregate max
返回: 1) "v1"
2) "10"
3) "v2"
4) "20"
5) "v3"
6) "30"
7) "v4"
8) "40"
9) "v5"
10) "50"
11) "v6"
12) "60"
2.13 求多个集合的并集
命令:zunionstore destination numkeys key [key…][weights weight[weight…]] [aggregatesum|min|max]
选项:destination:交集计算结果保存到这个键中
numkeys:需要做交集计算的键的个数
key[key…]:需要做交集计算的键
weights weight[weight…]:每个键的权重,在做交集计算时,每个键中的每个member会将自己分数乘以这个权重,每个键的权重默认是1.
Aggregate sum|min|max:计算成员交集后,分值可以按照sum,min,max做汇总,默认值是sum。
例如:zadd zset1 10 v1 20 v2 30 v3 40 v4 50 v5 60 v6 [
zadd zset2 110 v1 120 v2 130 v3 140 v4 150 v5 160 v6
zunionstoreinterstoreset1 2 zset1 zset2 weights 1 0.05 aggregate max
返回:
1) "v1"
2)"15.5"
3)"v2"
4)"26"
5)"v3"
6)"36.5"
7)"v4"
8)"47"
9)"v5"
10) "57.5"
11) "v6"
12) "68"
三. 有序集合命令的时间复杂度
四. 内部编码
集合类型的内部编码有两种:
(1) ziplist(压缩列表),当集合中的元素都是整数,且元素个数小于zset-max-ziplist-entries配置(默认512个)时,Redis会采用ziplist来做为集合的内部实现,从而减少内存的使用。
(2) skiplist(跳跃表),当有序集合类型无法满足ziplist的条件时,Redis就会使用skiplist做为有序集合的内部实现。
五. 有序集合的适用场景及方案
(1)zrevrangebyrank=排名系统
(2)zadd,zincrby=点赞