Redis 支持多种数据结构,比如 字符串、列表、集合、有序集合 和 哈希 等数据结构。本次我整理了关于 有序集合 相关的命令,也就是关于 Sorted Sets 相关的命令,如下图。
上图中用红色圈中的部分,就是关于 有序集合 相关的命令。如果想要在 Redis 中查看相关的命令可以使用 help 命令来进行查看,命令如下。
127.0.0.1:6379> help @sorted_set
在按下回车后,可以看到 Sorted Sets 相关命令的说明,如下图。
图中就是部分关于 Sorted Sets 相关的部分命令。对于 Sorted Sets 有另外一个名称 —— zsets 或 zset。
Sorted Sets 数据类型是 Key 对应的 Value 的类型,在 Redis 中所有的 Key 都是字符串类型,所谓的数据类型表示的是 Value 的类型。在 Sorted Sets 中的 Value 是一个有序集合,集合是有序的(上篇文章的 Sets 是无序的),且是不可以重复的,有序集合包含两部分,分别是成员(member)和分数(score)两部分。
为了大家能够直接复制命令进行测试,下面我就不截图了。
该命令的作用是:添加一个或者多个带分数的成员到集合里,命令格式如下:
zadd key [NX|XX] [CH] [INCR] score member [score member ...]
例子如下:
127.0.0.1:6379> zadd language 100 java 200 c++ 50 python 150 ruby
(integer) 4
在命令中,language 是 key,其中 java、c++、 python 和 ruby 是 member,也就是成员;它们前面的数值是 score,也就是分数。从返回值可以看出,zadd 命令增加了 4 个元素。
我们来查看一下用 zadd 添加的元素:
127.0.0.1:6379> zrange language 0 -1 withscores
1) "python"
2) "50"
3) "java"
4) "100"
5) "ruby"
6) "150"
7) "c++"
8) "200"
参数 NX 和 XX 的说明
nx:只添加新成员
127.0.0.1:6379> zadd language nx 200 java 130 php 180 c++
(integer) 1
127.0.0.1:6379> zrange language 0 -1 withscores
1) "python"
2) "50"
3) "java"
4) "100"
5) "php"
6) "130"
7) "ruby"
8) "150"
9) "c++"
10) "200"
可以看到 java 和 c++ 的分数都没有改变,php 加入了 zset。
xx:更新已经存在的成员
127.0.0.1:6379> zadd language xx 200 java 180 c++ 30 shell
(integer) 0
127.0.0.1:6379> zrange language 0 -1 withscores
1) "python"
2) "50"
3) "php"
4) "130"
5) "ruby"
6) "150"
7) "c++"
8) "180"
9) "java"
10) "200"
可以看到 java 和 c++ 的分数发生了改变,而 shell 并没有加入 zset 当中。
ch:返回值为发生变化的成员总数
前面我们看到 zadd 的返回值是添加成员的个数,使用 ch 参数后,zadd 的返回值为发生变化的成员的个数
127.0.0.1:6379> zadd language ch 210 java
(integer) 1
127.0.0.1:6379> zadd language 220 java
(integer) 0
对比上面两条命令的返回值,使用了 ch 参数后,返回值为 1,说明有一个成员发生了变化;没有使用 ch 参数,返回值为 0,表示添加了 0 个成员。
incr:zadd 指令不再是设置,而是增加
前面 python 的值为 50,我们使用 incr 参数对 python 的分数进行增加,命令如下:
127.0.0.1:6379> zadd language incr 50 python
"100"
127.0.0.1:6379> zrange language 0 -1 withscores
1) "python"
2) "100"
3) "php"
4) "130"
5) "ruby"
6) "150"
7) "c++"
8) "180"
9) "java"
10) "220"
可以看到,python 的分数为 100,不增加 incr 参数的情况:
127.0.0.1:6379> zadd language 50 python
(integer) 0
127.0.0.1:6379> zrange language 0 -1 withscores
1) "python"
2) "50"
3) "php"
4) "130"
5) "ruby"
6) "150"
7) "c++"
8) "180"
9) "java"
10) "220"
可以看到,没有 incr 参数时,zadd 还具有设置分数的作用。
该命令的作用是:获取指定 key 中的成员数量。
127.0.0.1:6379> zcard language
(integer) 5
127.0.0.1:6379> zrange language 0 -1
1) "python"
2) "php"
3) "ruby"
4) "c++"
5) "java"
该命令的作用是:获取指定 key 下分数范围内的成员的数量
127.0.0.1:6379> zcount language 150 180
(integer) 2
127.0.0.1:6379> zrange language 0 -1 withscores
1) "python"
2) "50"
3) "php"
4) "130"
5) "ruby"
6) "150"
7) "c++"
8) "180"
9) "java"
10) "220"
从上面的命令可以看出,分数在 150 到 180 之间的成员有两个。
该命令的作用是:给 key 中的成员增加分数
127.0.0.1:6379> zincrby language 10 python
"60"
127.0.0.1:6379> zrange language 0 -1 withscores
1) "python"
2) "60"
3) "php"
4) "130"
5) "ruby"
6) "150"
7) "c++"
8) "180"
9) "java"
10) "220"
该命令的作用是:返回指定 key 的分数最大的 N 个成员,并将返回的成员从 key 中删除
127.0.0.1:6379> zpopmax language 1
1) "java"
2) "220"
在上面的命令中,language 后跟随的数值就是要获取的分数最大的 N 个成员
127.0.0.1:6379> zrange language 0 -1
1) "python"
2) "php"
3) "ruby"
4) "c++"
该命令的作用是:返回指定 key 的分数最小的 N 个成员,并将成员从 key 中删除
127.0.0.1:6379> zpopmin language 1
1) "python"
2) "60"
127.0.0.1:6379> zrange language 0 -1 withscores
1) "php"
2) "130"
3) "ruby"
4) "150"
5) "c++"
6) "180"
该命令的作用是:返回指定 key 中索引范围内的成员,命令格式如下
zrange key start stop [WITHSCORES]
这个命令是我们使用最多的命令,在上面的例子中已经反复使用过了。这里具体介绍一下。
127.0.0.1:6379> zrange language 0 -1
1) "php"
2) "ruby"
3) "c++"
命令格式中的,0 和 -1 表示查看 zset 中从开始位置到结束位置的所有成员,zset 的索引从 0 开始,-1 表示最后一个索引的位置,同理,第二个元素的索引值为 1,倒数第二个索引可以使用 -2 表示。
127.0.0.1:6379> zrange language -2 -1
1) "ruby"
2) "c++"
127.0.0.1:6379> zrange language 0 -2
1) "php"
2) "ruby"
命令格式中的 withscores 表示查看各个成员对应的分数,例子如下:
127.0.0.1:6379> zrange language 0 -1 withscores
1) "php"
2) "130"
3) "ruby"
4) "150"
5) "c++"
6) "180"
该命令的作用是:返回指定 key 中索引范围内的成员,顺序由高到底,命令格式如下:
zrevrange key start stop [WITHSCORES]
该命令与 zrange 类似,zrange 是按照分数由低到高的排序,而 zrevrange 则是由高到低进行排序,例子如下:
127.0.0.1:6379> zrevrange language 0 -1 withscores
1) "c++"
2) "180"
3) "ruby"
4) "150"
5) "php"
6) "130"
该命令的作用是:按照字典顺序进行排序后获取指定区间的成员,且可以进行分页。
127.0.0.1:6379> zadd score 0 aa 0 bb 0 cc 0 dd 0 ee 0 ff
(integer) 6
注意:使用 zrangebylex 要求所有成员的分数相同,因此上面的命令我们先添加一些要进行测试的成员和分数。
其命令格式如下:
ZRANGEBYLEX key min max [LIMIT offset count]
先来查看一下按照字典序进行排序的成员,命令如下:
127.0.0.1:6379> zrangebylex score - +
1) "aa"
2) "bb"
3) "cc"
4) "dd"
5) "ee"
6) "ff"
其中 - 号表示最小值,+ 号表示最大值
127.0.0.1:6379> zrangebylex score [a [d
1) "aa"
2) "bb"
3) "cc"
可以看到,我们查看了左侧为以字母 a 开头的闭区间,和右侧为以字母 d 开头的开区间的成员列表。在 min 和 max 进行匹配时,需要以 [ 或 ( 开头。网上资料中描述,[ 表示闭区间,( 开区间,但是经我测试发现,无论使用 [ 还是 ( ,最后的结果范围都是 左闭右开。(如果我测试的有误,也请大家指出,以便我进行改正,在此表示感谢!)
127.0.0.1:6379> zrangebylex score - (c
1) "aa"
2) "bb"
127.0.0.1:6379> zrangebylex score (a (c
1) "aa"
2) "bb"
从上面可以看出,使用 ( 同样时 左闭右开。
接着再看看 limit 的用法,limit 后面根两个参数,分别时 offset 和 count,也就是起始的偏移和数量,这两个参数类似 MySQL 的 limit 的用法。
127.0.0.1:6379> zrangebylex score - + limit 0 3
1) "aa"
2) "bb"
3) "cc"
127.0.0.1:6379> zrangebylex score - + limit 3 3
1) "dd"
2) "ee"
3) "ff"
该命令的作用是:用法和 zrangebylex 类似,只是顺序是反的,命令格式如下:
zrevrangebylex key max min [LIMIT offset count]
zrevrangebylex 命令在 key 的后面先给出 max,再给出 min,这个顺序正好与 zrangebylex 的顺序相反,这里就不再演示了。
该命令的作用是:返回成员之间的数量,命令格式如下:
zlexcount key min max
该命令的格式与 zrangebylex 的格式类似,只是不返回具体的成员区间,而是成员区间的个数,例子如下:
127.0.0.1:6379> zlexcount score - +
(integer) 6
127.0.0.1:6379> zlexcount score (a (c
(integer) 2
该命令的作用是:按照分数进行排序并获取成员,命令格式如下:
zrangebyscore key min max [WITHSCORES] [LIMIT offset count]
查看所有的成员
127.0.0.1:6379> zrangebyscore language -inf +inf
1) "php"
2) "ruby"
3) "c++"
其中,-inf 和 +inf 分别代表负无穷大和正无穷大 。
127.0.0.1:6379> zrangebyscore language 100 150 withscores
1) "php"
2) "130"
3) "ruby"
4) "150"
查看带分数的分数区间再 100 到 150 之间的成员
127.0.0.1:6379> zrangebyscore language (130 (160 withscores
1) "ruby"
2) "150"
查看分数在 130 到 160 之间的开区间的成员,zrangebyscore 不能使用 [ 开头
该命令的作用是:该命令的排序与 zrangebyscore 的顺序相反,该命令的格式如下:
zrevrangebyscore key max min [WITHSCORES] [LIMIT offset count]
该命令就不进行演示
该命令的作用是:按照分数由低到高的顺序查看成员的排名
127.0.0.1:6379> zrank language php
(integer) 0
127.0.0.1:6379> zrank language c++
(integer) 2
127.0.0.1:6379> zrank language ruby
(integer) 1
该命令的作用是:按照分数由高到低的顺序查看成员的排名
127.0.0.1:6379> zrevrank language php
(integer) 2
127.0.0.1:6379> zrevrank language ruby
(integer) 1
127.0.0.1:6379> zrevrank language c++
(integer) 0
该命令的作用是:删除 zset 中的一个或多个成员,当成员为空时,删除该 key
127.0.0.1:6379> zrem language c++ php ruby
(integer) 3
127.0.0.1:6379> zrange language 0 -1
(empty list or set)
127.0.0.1:6379> keys *
1) "score"
2) "key"
3) "lang"
该命令的作用是:按照排名进行删除成员,命令格式如下:
ZREMRANGEBYRANK key start stop
删除排名 0 和 1 的两个成员
127.0.0.1:6379> zadd language 50 c++ 100 java 150 asm 200 php 251 ruby 300 python
(integer) 6
127.0.0.1:6379> zremrangebyrank language 0 1
(integer) 2
127.0.0.1:6379> zrange language 0 -1
1) "asm"
2) "php"
3) "ruby"
4) "python"
该命令的作用是:按照分数进行删除成员,命令格式如下:
ZREMRANGEBYSCORE key min max
删除分数再 201 到 260 之间的成员
127.0.0.1:6379> zremrangebyscore language 201 260
(integer) 1
127.0.0.1:6379> zrange language 0 -1
1) "asm"
2) "php"
3) "python"
ruby 成员被删除了
该命令的作用是:按照字典顺序进行删除成员,命令格式如下:
ZREMRANGEBYLEX key min max
删除字母 o 到 q 区间的成员
127.0.0.1:6379> zremrangebylex language [o [q
(integer) 2
127.0.0.1:6379> zrange language 0 -1
1) "asm"
可以看到,php 和 python 被删除了
该命令的作用是:获取指定成员的分数
127.0.0.1:6379> zscore language php
"130"
127.0.0.1:6379> zscore language c++
"180"
127.0.0.1:6379> zscore language c
(nil)
127.0.0.1:6379> zscore language ruby
"150"
该命令的作用是:将两个或多个 zset 求交集,命令格式如下:
ZINTERSTORE destination numkeys key [key ...] [WEIGHTS weight] [AGGREGATE SUM|MIN|MAX]
求 k1 和 k2 的交集 k3,观察 k3 中成员的分数
127.0.0.1:6379> zadd k1 100 aa 200 bb 300 cc
(integer) 3
127.0.0.1:6379> zadd k2 100 aa 200 cc 300 dd
(integer) 3
127.0.0.1:6379> zinterstore k3 2 k1 k2
(integer) 2
127.0.0.1:6379> zrange k3 0 -1
1) "aa"
2) "cc"
127.0.0.1:6379> zrange k3 0 -1 withscores
1) "aa"
2) "200"
3) "cc"
4) "500"
求 k1 和 k2 的交集 k4,观察 k4 中成员的分数,这次使用参数 weights,该参数表示对应集合的权重
127.0.0.1:6379> zinterstore k4 2 k1 k2 weights 2 3
(integer) 2
127.0.0.1:6379> zrange k4 0 -1
1) "aa"
2) "cc"
127.0.0.1:6379> zrange k4 0 -1 withscores
1) "aa"
2) "500"
3) "cc"
4) "1200"
weights 后面跟着 2 和 3,表示 k1 的分数权重是 2 倍,k2 的分数的权重是 3 倍。
k4(aa) = k1(aa) * 2 + k2(aa) * 3 = 100 * 2 + 100 * 3 = 500
最后一个参数 aggregate 表示交集的聚合方式:
相加的聚合方式:sum
127.0.0.1:6379> zinterstore k5 2 k1 k2 aggregate sum
(integer) 2
127.0.0.1:6379> zrange k5 0 -1 withscores
1) "aa"
2) "200"
3) "cc"
4) "500"
默认就是 k1 和 k2 相同成员的分数相加的形式
最小分数的聚合方式:min
127.0.0.1:6379> zinterstore k6 2 k1 k2 aggregate min
(integer) 2
127.0.0.1:6379> zrange k6 0 -1 withscores
1) "aa"
2) "100"
3) "cc"
4) "200"
k1 和 k2 的 aa 是相等的,因此 k6 的 aa 仍然是 100,而 k1 和 k2 的 cc 是不相等的,取了它们中较小的那个
最大分数的聚合方式:max
127.0.0.1:6379> zinterstore k7 2 k1 k2 aggregate max
(integer) 2
127.0.0.1:6379> zrange k7 0 -1 withscores
1) "aa"
2) "100"
3) "cc"
4) "300"
k1 和 k2 的 aa 是相等的,因此 k7 的 aa 仍然是 100,而 k1 和 k2 的 cc 是不相等的,取了它们中较大的那个
该命令的作用是:将两个或多个 zset 求并集,命令格式如下:
zunionstore destination numkeys key [key ...] [WEIGHTS weight] [AGGREGATE SUM|MIN|MAX]
该命令的使用方式与 zinterstore 的方式相同,只是最后计算的是并集不是交集,这里不再进行演示。
Redis 的有序集合类型提供的命令还是比较多的,它不但可以当作一个集合来用,它还具备 排名、排序、分页、求交集 和 求并集 的功能,当然, 还可以在一些特定的应用场景中轻松的完成功能的开发。
待 Redis 常用的几种基本数据类型总结完成后,我会再逐步的整理 Redis 这几种基本数据类型的各种应用场景,希望大家可以喜欢。
这部分整理花了两个晚上完成的,其实累计也就 2 个小时左右,由于时间比较仓促,可能有些命令描述的不是特别清楚或者准确,但是命令都是我逐个敲出来的,按照命令来进行学习,基本应该是没有问题的。当然了,有问题也可以指出来,我进行改正。
评论