Redis | Redis 有序集合相关命令_php


        Redis 支持多种数据结构,比如 字符串、列表、集合、有序集合 和 哈希 等数据结构。本次我整理了关于 ​有序集合​ 相关的命令,也就是关于 ​Sorted Sets​ 相关的命令,如下图。

Redis | Redis 有序集合相关命令_ruby_02

        上图中用红色圈中的部分,就是关于 ​有序集合​ 相关的命令。如果想要在 Redis 中查看相关的命令可以使用 ​help​ 命令来进行查看,命令如下。


127.0.0.1:6379> help @sorted_set

        在按下回车后,可以看到 Sorted Sets 相关命令的说明,如下图。

Redis | Redis 有序集合相关命令_c++_03


        图中就是部分关于 Sorted Sets 相关的部分命令。对于 Sorted Sets 有另外一个名称 —— ​zsets​ 或 ​zset


常用 Sorted Sets 相关命令


        ​Sorted Sets 数据类型是 Key 对应的 Value 的类型,在 Redis 中所有的 Key 都是字符串类型,所谓的数据类型表示的是 Value 的类型。在 Sorted Sets 中的 Value 是一个有序集合,集合是有序的(上篇文章的 Sets 是无序的),且是不可以重复的,有序集合包含两部分,分别是成员(member)和分数(score)两部分。


        为了大家能够直接复制命令进行测试,下面我就不截图了。


1、zadd


        该命令的作用是:​添加一个或者多个带分数的成员到集合里​,命令格式如下:

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 还具有设置分数的作用


2、zcard


        该命令的作用是:获取指定 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"



3、zcount


        该命令的作用是:​获取指定 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 之间的成员有两个。


4、zincrby


        该命令的作用是:​给 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"


5、zpopmax


        该命令的作用是:​返回指定 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++"


6、zpopmin


        该命令的作用是:​返回指定 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"


7、zrange


        该命令的作用是:​返回指定 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"


8、zrevrange

        ​该命令的作用是:​返回指定 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"


9、zrangebylex


        ​该命令的作用是:​按照字典顺序进行排序后获取指定区间的成员,且可以进行分页

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"


10、zrevrangebylex

        ​该命令的作用是:​用法和 zrangebylex 类似,只是顺序是反的​,命令格式如下:

zrevrangebylex key max min [LIMIT offset count]


        zrevrangebylex 命令在 key 的后面先给出 max,再给出 min,这个顺序正好与 zrangebylex 的顺序相反,这里就不再演示了。


11、zlexcount

        ​该命令的作用是:​返回成员之间的数量​,命令格式如下:

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


12、zrangebyscore


        ​该命令的作用是:​按照分数进行排序并获取成员​,命令格式如下:

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 不能使用 [ 开头


13、zrevrangebyscore


        ​该命令的作用是:​该命令的排序与 zrangebyscore 的顺序相反​,该命令的格式如下:

zrevrangebyscore key max min [WITHSCORES] [LIMIT offset count]

        该命令就不进行演示


14、zrank


        ​该命令的作用是:​按照分数由低到高的顺序查看成员的排名

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


15、zrevrank


        该命令的作用是:​按照分数由高到低的顺序查看成员的排名

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


16、zrem


        该命令的作用是:​删除 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"


17、zremrangebyrank


        该命令的作用是:​按照排名进行删除成员​,命令格式如下:

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"


18、zremrangebyscore


        该命令的作用是:​按照分数进行删除成员​,命令格式如下:

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 成员被删除了


19、zremrangebylex


        该命令的作用是:​按照字典顺序进行删除成员​,命令格式如下:

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 被删除了


20、zscore


        ​该命令的作用是:​获取指定成员的分数

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"



21、zinterstore


        ​该命令的作用是:​将两个或多个 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 是不相等的,取了它们中较大的那个


22、zunionstore

        ​该命令的作用是:​将两个或多个 zset 求并集​,命令格式如下:

zunionstore destination numkeys key [key ...] [WEIGHTS weight] [AGGREGATE SUM|MIN|MAX]


        该命令的使用方式与 zinterstore 的方式相同,只是最后计算的是并集不是交集,这里不再进行演示。


总结

        Redis 的有序集合类型提供的命令还是比较多的,它不但可以当作一个集合来用,它还具备 ​排名​、​排序​、​分页​、​求交集​ 和 ​求并集 ​的功能,当然, 还可以在一些特定的应用场景中轻松的完成功能的开发。


        待 Redis 常用的几种基本数据类型总结完成后,我会再逐步的整理 Redis 这几种基本数据类型的各种应用场景,希望大家可以喜欢。


Redis | Redis 有序集合相关命令_php_04


        这部分整理花了两个晚上完成的,其实累计也就 2 个小时左右,由于时间比较仓促,可能有些命令描述的不是特别清楚或者准确,但是命令都是我逐个敲出来的,按照命令来进行学习,基本应该是没有问题的。当然了,有问题也可以指出来,我进行改正。



Redis | Redis 有序集合相关命令_php