本文主要是介绍Redis基本类型学习之Sorted Set,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
你必须非常努力,才能看起来毫不费力!
微信搜索公众号[ 漫漫Coding路 ],一起From Zero To Hero !
前言
Sorted Set,即有序集合,是一种类似于List(集合)和 Hash(哈希)的混合数据类型。与集合一样,有序集合由唯一的、不重复的字符串元素组成,因此在某种意义上,有序集合也是一个集合。但是集合内的元素没有排序,有序集合中的每个元素都与一个浮点值相关联,称为分数,集合中的元素会根据分数大小进行排序。由于每个元素都映射到一个值(分数),因此有序集合也类似于哈希数据类型。
有序集合的排序规则如下:
- A、B两个元素有不同的分数,如果
A.Score>B.Score
,那么A>B
- A、B两个元素分数相同,如果按照字符串的字典排序
A>B
,那么A>B
ZADD
可用版本:>= 1.2.0
时间复杂度: M*O(log(N)),其中M为新增的元素个数,N为有序集合中现有的元素个数
命令格式
ZADD key [NX|XX] [GT|LT] [CH] [INCR] score member [score member ...]
命令描述
- 将一个或多个
member
、score
数据对加入到key
对应的有序集合中 - 如果指定的
member
已经存在有序集合中,则更新分数,同时会重新插入member
元素,以确保该元素在正确位置 - 如果
key
对应的有序集合不存在,会先创建一个空的有序集合 score
可以是整数或者双精度浮点数的字符串表示形式,+inf
和-inf
也是有效值。- 如果
key
对应的value类型不是Sorted Set
, 返回Error
可选参数
- XX:只更新已经存在的元素,不添加新元素
- NX:只添加新元素,不更新已有元素
- LT:新元素会添加;对于已存在元素,当新
score
值小于当前score
值时才会更新 - GT:新元素会添加;对于已存在元素,当新
score
值大于当前score
值时才会更新 - CH:改变返回值的计算逻辑。默认返回的是新添加的元素个数,提供该参数后返回被改变的元素个数:即新增的元素个数和score值被更新的元素个数之和。如果元素已经存在,且新的score值与当前score值一样,不会被计数
- INCR:提供该参数后的命令类似
ZINCRBY
,将score加上一个值,只允许提供一个member和score
注意:GT、LT 和 NX 选项是互斥的。
整数值score范围
有序集合使用double类型的64位浮点数来表示score
值,能够表示-(253)到+(253)之间的整数。在更实际的应用中,-9007199254740992 和 9007199254740992 之间的所有整数都可以完美表示。较大的整数或分数以指数形式表示,因此可能只得到较大的整数或者近似值的浮点数。
返回值
- 整数值:
- 未提供可选参数时,返回新增元素个数(不包含更新score的元素)
- 提供
CH
参数时,返回被改变的元素个数(新增和更新)
- 字符串:提供了
INCR
参数,返回字符串- 更新成功,返回更新后元素新的
score
值 NX
、XX
参数导致未更新,返回 nil
- 更新成功,返回更新后元素新的
示例
# 1. 不使用可选参数添加元素
127.0.0.1:6379> zadd myzset 1 one
(integer) 1
127.0.0.1:6379> zadd myzset 2 two
(integer) 1
# 遍历元素,不返回score
127.0.0.1:6379> ZRANGE myzset 0 -1
1) "one"
2) "two"
# 遍历元素,返回score
127.0.0.1:6379> ZRANGE myzset 0 -1 WITHSCORES
1) "one"
2) "1"
3) "two"
4) "2"# 2. 重复添加同一个元素,score会被更新
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> zadd myzset 1 one
(integer) 1
# 默认返回新增的元素个数
127.0.0.1:6379> zadd myzset 2 one
(integer) 0
127.0.0.1:6379> ZRANGE myzset 0 -1 WITHSCORES
1) "one"
2) "2"
# 添加 CH 参数,返回被改变的元素个数
127.0.0.1:6379> zadd myzset ch 3 one
(integer) 1
127.0.0.1:6379> ZRANGE myzset 0 -1 WITHSCORES
1) "one"
2) "3"# 3. NX参数
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> zadd myzset 1 one
(integer) 1
127.0.0.1:6379> zadd myzset NX 2 one
(integer) 0
127.0.0.1:6379> ZRANGE myzset 0 -1 WITHSCORES
1) "one"
2) "1"# 4. XX参数
127.0.0.1:6379> zadd myzset 3 three
(integer) 1
# four不存在,添加失败
127.0.0.1:6379> zadd myzset XX 4 four
(integer) 0
# three已存在,可以添加成功
127.0.0.1:6379> zadd myzset XX 3.1 three
(integer) 0
127.0.0.1:6379> zrange myzset 0 -1 withscores
1) "one"
2) "1"
3) "three"
4) "3.1000000000000001"# GT、LT参数
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> zadd myzset 5 five
(integer) 1
127.0.0.1:6379> zadd myzset 6 six
(integer) 1
# GT: 4不大于5,更新失败
127.0.0.1:6379> zadd myzset GT 4 five
(integer) 0
# LT: 4小于5,更新成功
127.0.0.1:6379> zadd myzset LT 4 six
(integer) 0
127.0.0.1:6379> zrange myzset 0 -1 withscores
1) "six"
2) "4"
3) "five"
4) "5"
ZSCORE
可用版本:>= 1.2.0
时间复杂度: O(1)
命令格式
ZSCORE key member
命令描述
- 返回
key
对应的有序集合中,member
对应的score
值 - 如果集合不存在,或者
member
不在集合中,返回nil
返回值
字符串:member
对应的score
值
示例
127.0.0.1:6379> zadd myset 18 user1:age
(integer) 1
127.0.0.1:6379> zscore myset user1:age
"18"
# member不存在
127.0.0.1:6379> zscore myset user0:age
(nil)
ZCARD
可用版本:>= 1.2.0
时间复杂度: O(1)
命令格式
ZCARD key
命令描述
- 返回
key
对应的有序集合基数(长度)
返回值
整数值:有序集合长度或者0(有序集合不存在)
示例
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> zadd myset 1 one
(integer) 1
127.0.0.1:6379> zadd myset 2 two
(integer) 1
127.0.0.1:6379> zcard myset
(integer) 2
ZCOUNT
可用版本:>= 2.0.0
时间复杂度: O(log(N)),N为有序数组中的元素个数
命令格式
ZCOUNT key min max
命令描述
- 返回
key
对应的有序集合中,score
值位于min
和max
之间的元素数量
返回值
整数值:元素数量
示例
127.0.0.1:6379> zadd myzset 1 one
(integer) 1
127.0.0.1:6379> zadd myzset 2 two
(integer) 1
127.0.0.1:6379> zadd myzset 3 three
(integer) 1
127.0.0.1:6379> zadd myzset 4 four
(integer) 1# 在2-4之间的有3个
127.0.0.1:6379> zcount myzset 2 4
(integer) 3
ZRANGE
可用版本:>= 1.2.0
时间复杂度:O(log(N)+M) ,N为有序数组中的元素个数,M为返回的元素个数
命令变化
自6.2.0版本后,新增REV
, BYSCORE
, BYLEX
and LIMIT
参数
命令格式
ZRANGE key min max [BYSCORE|BYLEX] [REV] [LIMIT offset count] [WITHSCORES]
命令描述
- 返回
key
对应的有序集合中,特定范围内的元素 - ZRANGE可以执行不同类型的范围查询:根据索引(index)、分数(score)和字典顺序(lexicographical)
- 自6.2.0版本,
ZRANGE
可以代替如下命令ZREVRANGE
、ZRANGEBYSCORE
、ZREVRANGEBYSCORE
、ZRANGEBYLEX
和ZREVRANGEBYLEX
常用行为和选项
元素默认是由最低到最高分数排序的,相同分数的元素按照字典序升序排序。
- REV:将排序反转,即从大到小排序,字典顺序也会反转;
- LIMIT:返回结果集中的子集,从
offset
位置开始返回count
个值(类似于SQL 中的*SELECT LIMIT offset, count
*),当count为负数时,返回offset
后的所有元素。注意:使用该参数时,需要配合BYSCORE或BYLEX使用;同时,Redis需要遍历offset个元素才能得到返回值,如果offset较大,复杂度可能会达到O(N); - WITHSCORES:返回元素的同时,返回score值。格式为value1,score1,…,valueN,scoreN;
索引作为查询范围
- 命令默认按照索引作为返回元素的范围,
min
和max
是索引范围,0为第一个元素,1为第二个元素,以此类推;在这些元素中按照score由低到高排序后返回。由于Redis默认就是由低到高排序,所以该命令就是返回第min到第max的元素 - 范围首尾都是闭区间,即[min,max];
- 索引值也可以是负数,-1表示最后一个元素,-2表示倒数第二个元素,以此类推;
- 给定索引超出列表范围不会报错:
- 如果min大于列表最大索引或者大于max,返回空集合
- 如果max大于列表最大索引,Redis则令 max=最大索引
分值作为查询范围
- 当使用了
BYSCORE
参数,将会在score值介于min和max之间的元素中,按照score由低到高的顺序返回元素; - min和max可以是
-inf
和+inf
,表示负无穷和正无穷; - 默认左右都是闭区间,即[min,max],如果想使用开区间,可以在索引前加上’('符号
- ZRANGE zset (1 5 BYSCORE 返回 (1,5]
- ZRANGE zset (5 (10 BYSCORE 返回 (5,10)
字典序作为查询范围
- 当使用了
BYLEX
参数,将会在返回字典序排序后介于min和max的元素中,按照score由低到高的顺序返回元素; - 当有序数组中,所有元素的score值都一样时,才应该使用该参数;当元素score不一样时,使用该命令的返回结果不确定;
- min或max前需要提供’(‘或者’['符号,用于表示开区间或者闭区间;
- 对于min或者max,可以使用’+‘或者’-'符号,表示正无穷或者负无穷的字符串;当有序集合中所有元素score值都相同,使用
ZRANGEBYLEX myzset - *
会返回所有元素;
返回值
数组:范围内的元素列表(如果使用了WITHSCORES参数,会同时返回score值)
示例
# 插入四条数据
127.0.0.1:6379> zadd myset 1 one
(integer) 1
127.0.0.1:6379> zadd myset 2 two
(integer) 1
127.0.0.1:6379> zadd myset 4 four
(integer) 1
127.0.0.1:6379> zadd myset 3 three
(integer) 1# 默认按照索引
127.0.0.1:6379> zrange myset 0 -1
1) "one"
2) "two"
3) "three"
4) "four"# 默认按照索引
127.0.0.1:6379> zrange myset 0 -1
1) "one"
2) "two"
3) "three"
4) "four"# 默认按照索引
127.0.0.1:6379> zrange myset 1 2
1) "two"
2) "three"# REV参数,降序返回
127.0.0.1:6379> zrange myset 0 -1 rev
1) "four"
2) "three"
3) "two"
4) "one"# WITHSCORES参数
127.0.0.1:6379> zrange myset 0 -1 withscores
1) "one"
2) "1"
3) "two"
4) "2"
5) "three"
6) "3"
7) "four"
8) "4"# 返回score值为[1,3]之间的元素
127.0.0.1:6379> zrange myset 1 3 byscore
1) "one"
2) "two"
3) "three"# 返回score值为[1,3)内的元素
127.0.0.1:6379> zrange myset 1 (3 byscore
1) "one"
2) "two"# byscore,配合使用LIMIT offset count参数
127.0.0.1:6379> zrange myset 1 3 byscore limit 1 2
1) "two"
2) "three"# 使用BYLEX参数
127.0.0.1:6379> zrange myset [a (p bylex
1) "one"
ZRANGEBYSCORE
可用版本:>= 1.0.5
时间复杂度: O(log(N)+M) ,N为有序数组中的元素个数,M为返回的元素个数
命令格式
ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]
命令描述
- 返回score值介于
min
和max
之间的元素,由低到高排序,score值相同的按照字典序排序 - LIMIT:返回结果集中的子集,从
offset
位置开始返回count
个值(类似于SQL 中的*SELECT LIMIT offset, count
*),当count为负数时,返回offset
后的所有元素。注意:使用该参数时,Redis需要遍历offset个元素才能得到返回值,如果offset较大,复杂度可能会达到O(N); - WITHSCORES:返回元素的同时,返回score值。
自6.2.0版本后,该命令考虑被废弃,建议使用ZRANGE命令加BYSCORE参数。
开闭区间
-
默认左右都是闭区间,即[min,max],如果想使用开区间,可以在索引前加上’('符号
-
ZRANGE zset (1 5 BYSCORE 返回 (1,5]
-
ZRANGE zset (5 (10 BYSCORE 返回 (5,10)
-
-
min和max可以是
-inf
和+inf
,表示负无穷和正无穷
返回值
数组:范围内按照分数升序排序的元素数组
示例
127.0.0.1:6379> zadd myzset 1 one
(integer) 1
127.0.0.1:6379> zadd myzset 2 two
(integer) 1
127.0.0.1:6379> zadd myzset 3 three
(integer) 1# 返回所有元素
127.0.0.1:6379> zrangebyscore myzset -inf +inf
1) "one"
2) "two"
3) "three"# 带有 WITHSCORES 参数
127.0.0.1:6379> zrangebyscore myzset -inf +inf withscores
1) "one"
2) "1"
3) "two"
4) "2"
5) "three"
6) "3"127.0.0.1:6379> zrangebyscore myzset 2 3
1) "two"
2) "three"# 左开右闭
127.0.0.1:6379> zrangebyscore myzset (2 3
1) "three"
ZRANGEBYLEX
可用版本:>= 2.8.9
时间复杂度: O(log(N)+M) ,N为有序数组中的元素个数,M为返回的元素个数
命令格式
ZRANGEBYLEX key min max [LIMIT offset count]
命令描述
- 当有序数组中所有元素的score值都相同时,该命令将元素按照字典序排序,返回第min到max之间的元素,默认升序排序;
- 如果score值不相同,返回的元素不确定;
- 命令使用C语言中的memcmp()函数,对元素由低到高排序;如果公共部分相同,长的字符串排序更高;
- LIMIT:返回结果集的子集,从
offset
位置开始返回count
个值(类似于SQL 中的*SELECT LIMIT offset, count
*),当count为负数时,返回offset
后的所有元素。注意:使用该参数时,Redis需要遍历offset个元素才能得到返回值,如果offset较大,复杂度可能会达到O(N);
自6.2.0版本后,该命令考虑被废弃,建议使用ZRANGE命令加BYLEX参数。
区间
- min或max前
必须
使用’(‘或者’['符号,用于表示开区间或者闭区间; - 对于min或者max,也可以使用’+‘或者’-'符号,表示正无穷或者负无穷的字符串;当有序集合中所有元素score值都相同,使用
ZRANGEBYLEX myzset - *
会返回所有元素;
返回值
数组:范围内按照字典序升序排序的元素数组
示例
127.0.0.1:6379> ZADD myzset 0 a 0 b 0 c 0 d 0 e 0 f 0 g
(integer) 7
127.0.0.1:6379> ZRANGEBYLEX myzset - [c
1) "a"
2) "b"
3) "c"
127.0.0.1:6379> ZRANGEBYLEX myzset - (c
1) "a"
2) "b"
127.0.0.1:6379> ZRANGEBYLEX myzset [aaa (g
1) "b"
2) "c"
3) "d"
4) "e"
5) "f"
ZREVRANGE
可用版本:>= 1.2.0
时间复杂度: O(log(N)+M) ,N为有序数组中的元素个数,M为返回的元素个数
命令格式
ZREVRANGE key start stop [WITHSCORES]
命令描述
- 返回有序集合中特定范围内的元素,按照索引值从高到低排序,相同分数的按照字典序倒序排序返回
ZREVRANGE
与ZRANGE
类似,唯一不同的是ZREVRANGE
是从高到低排序,而ZRANGE
由低到高- 如果使用
WITHSCORES
参数,会打印出元素分值
自6.2.0版本后,ZREVRANGE命令考虑被废弃,建议使用后续的ZRANGE命令加REV参数。
返回值
数组:范围内按照降序排序的元素数组
示例
127.0.0.1:6379> zadd revset 1 one
(integer) 1
127.0.0.1:6379> zadd revset 2 two
(integer) 1
127.0.0.1:6379> zadd revset 3 three
(integer) 1
127.0.0.1:6379> zadd revset 4 four
(integer) 1
127.0.0.1:6379> zrevrange revset 0 -1
1) "four"
2) "three"
3) "two"
4) "one"
127.0.0.1:6379> zrevrange revset -3 -1
1) "three"
2) "two"
3) "one"# withscore可选参数
127.0.0.1:6379> zrevrange revset 0 -1 withscores
1) "four"
2) "4"
3) "three"
4) "3"
5) "two"
6) "2"
7) "one"
8) "1"
ZREVRANGEBYSCORE
可用版本:>= 2.2.0
时间复杂度: O(log(N)+M) ,N为有序数组中的元素个数,M为返回的元素个数
命令格式
ZREVRANGEBYSCORE key max min [WITHSCORES] [LIMIT offset count]
命令描述
- 返回score值介于
max
和min
之间的元素,排序为由高到低;相同分数的也按照字典序倒序排序返回; - 除了排序规则不同外,
ZREVRANGEBYSCORE
和ZRANGEBYSCORE
功能一致;
自6.2.0版本后,ZREVRANGE命令考虑被废弃,建议使用ZRANGE命令加BYSCORE和REV参数。
返回值
数组:范围内按照降序排序的元素数组
示例
127.0.0.1:6379> zadd myzset 1 one
(integer) 1
127.0.0.1:6379> zadd myzset 2 two
(integer) 1
127.0.0.1:6379> zadd myzset 3 three
(integer) 1
127.0.0.1:6379> zadd myzset 4 four
(integer) 1# 正无穷到负无穷
127.0.0.1:6379> zrevrangebyscore myzset +inf -inf
1) "four"
2) "three"
3) "two"
4) "one"# 默认闭区间
127.0.0.1:6379> zrevrangebyscore myzset 3 1
1) "three"
2) "two"
3) "one"# 前开后闭
127.0.0.1:6379> zrevrangebyscore myzset (3 1
1) "two"
2) "one"
ZREVRANGEBYLEX
可用版本:>= 2.8.9
时间复杂度: O(log(N)+M) ,N为有序数组中的元素个数,M为返回的元素个数
命令格式
ZREVRANGEBYLEX key max min [LIMIT offset count]
命令描述
- 当有序数组中所有元素的score值都相同时,该命令将元素按照字典序排序,返回max到min之间的元素,由高到低降序排序;
- 除了倒序排序外,
ZREVRANGEBYLEX
和ZRANGEBYLEX
命令一致;
自6.2.0版本后,ZREVRANGEBYLEX命令考虑被废弃,建议使用ZRANGE命令加BYLEX和REV参数。
返回值
数组:范围内按照降序排序的元素数组
示例
127.0.0.1:6379> ZADD myzset 0 a 0 b 0 c 0 d 0 e 0 f 0 g
(integer) 7
127.0.0.1:6379> zrevrangebylex myzset + -
1) "g"
2) "f"
3) "e"
4) "d"
5) "c"
6) "b"
7) "a"# 闭区间
127.0.0.1:6379> ZREVRANGEBYLEX myzset [c -
1) "c"
2) "b"
3) "a"# 开区间
127.0.0.1:6379> ZREVRANGEBYLEX myzset (c -
1) "b"
2) "a"127.0.0.1:6379> ZREVRANGEBYLEX myzset (g [aaa
1) "f"
2) "e"
3) "d"
4) "c"
5) "b"
总结
本文介绍了有序集合中的部分相关命令,包括
- ZADD:添加元素
- ZSCORE:获取元素score值
- ZCARD:返回集合长度
- ZCOUNT:返回给定区间的元素个数
- ZRANGE系列:升序或降序,遍历指定范围内的元素
更多
个人博客: https://lifelmy.github.io/
微信公众号:漫漫Coding路
这篇关于Redis基本类型学习之Sorted Set的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!