标题:【Redis04】Redis基础:Set相关操作
Redis基础学习:Set相关操作
继续我们的 Redis 基础学习,学完了 String、List、Hash 之后,就到了另一个非常重要的数据类型,也就是 Set 类型的使用。这个类型吧,其实就是一个不重复的 List ,或者说是一个标准的数学上的 集合 。换句话说,它的值是不能重复的。适合什么场景呢?我们最后再说。
基础操作
首先还是来看它最基本的操作,也就是添加、查询。使用 SADD 就可以添加数据,如果已经有相同的数据了,就无法添加成功。使用 SMEMBERS 可以获取到集合中全部的数据。
127.0.0.1:6379> sadd a A
(integer) 1
127.0.0.1:6379> sadd a B
(integer) 1
127.0.0.1:6379> sadd a A
(integer) 0
127.0.0.1:6379> smembers a
1) "B"
2) "A"
127.0.0.1:6379> scard a
(integer) 2
上面例子中,最后我们还使用了一个 SCARD ,这个命令是返回 Set 中有多少数据。SADD 命令直接就可以批量添加,因此,在 Set 类型中没有专门的批量添加的命令。
127.0.0.1:6379> sadd a D E F G D E G
(integer) 4
127.0.0.1:6379> smembers a
1) "G"
2) "A"
3) "B"
4) "D"
5) "E"
6) "F"
是否存在
判断一个值是否已经在 Set 中存在使用 SISMEMBER 命令,非常简单好用。
127.0.0.1:6379> sismember a B
(integer) 1
127.0.0.1:6379> sismember a C
(integer) 0
在 Redis6.2 之后,还新增加了一个命令,那就是 SMISMEMBER ,它可以批量的返回给定的内容是否在 Set 中。
127.0.0.1:6379> smismember a A B C D
1) (integer) 1
2) (integer) 0
3) (integer) 0
4) (integer) 1
获取、弹出
获取一个 Set 中的数据有两种方式,一个是弹出,也就是 SPOP 命令。而另一个则是随机的获取指定条数的数据,注意,是随机的,是获取不是弹出,这个命令是 SRANDMEMBER 。
127.0.0.1:6379> spop a
"E"
127.0.0.1:6379> spop a 2
1) "F"
2) "B"
127.0.0.1:6379> srandmember a
"G"
127.0.0.1:6379> srandmember a 2
1) "G"
2) "D"
127.0.0.1:6379> smembers a
1) "G"
2) "A"
3) "D"
这两个命令都有一个可选的 count 参数,如果不设置的话默认就是弹出一个或者获取一个,而如果设置的 count 大于集合内部的元素数量,将会返回整个集合,不会有额外的元素。
移动
和之前学习过的 LMOVE 一样,也是将某一个 Set 中的指定数据移动到另一个 Set 中。它的使用方式比较简单,参数就是下面这三个。
SMOVE source destination member
127.0.0.1:6379> smove a b G
(integer) 1
127.0.0.1:6379> SMEMBERS a
1) "A"
2) "D"
127.0.0.1:6379> SMEMBERS b
1) "G"
如果要移动到的 key 不存在的话,就会创建一个新的 Set 。
删除
127.0.0.1:6379> srem a A B C D
(integer) 2
127.0.0.1:6379> keys a
(empty array)
SREM 命令可以删除 Set 中的指定数据,同时也支持批量删除,当全部删完之后,这条 key 也就不存在了。
集合操作
集合操作是什么意思呢?开头我们就已经说过了,Set 是一个标准的 集合 。那么是集合的话,就肯定会有 交、并、差 的操作,毕竟这都是集合最基本的功能。所幸的是,Redis 已经为我们准备好了这些命令。
首先,我们要准备一些数据。
127.0.0.1:6379> sadd a A B C D
(integer) 4
127.0.0.1:6379> sadd b D E G F
(integer) 4
127.0.0.1:6379> sadd c B D G H I J
(integer) 6
差集
差集就是给定的集合 a ,在其它集合 b、c.... 中不存在的数据。说人话就是 a 有,其它没有的,使用的是 SDIFF 命令,可以多个集合进行比较。
127.0.0.1:6379> SDIFF a b
1) "C"
2) "A"
3) "B"
127.0.0.1:6379> SDIFF a b c
1) "C"
2) "A"
第一个 a 和 b 的差集是 A/B/C ,第二个 a/b/c 三个集合的差集只有 A/C 了,因为在 c 这个集合中有 B 存在。中学基础知识就不多说了吧。
另外,我们还可以将差集结果保存到另一个 Set 中,使用的是 SDIFFSTORE 命令。
127.0.0.1:6379> SDIFFSTORE diff1 a b
(integer) 3
127.0.0.1:6379> SMEMBERS diff1
1) "C"
2) "A"
3) "B"
我们将 a/b 的差集保存到了 diff1 这个集合中,如果给定的 key 不存在的话,也是会新创建一个的。
交集
同样的,高中的知识,比较的集合中都存在的元素,使用的是 SINTER 。
127.0.0.1:6379> SINTER a b
1) "D"
127.0.0.1:6379> SINTER a b c
1) "D"
127.0.0.1:6379> SINTER b c
1) "G"
2) "D"
它也有将结果保存到另外一个集合中的命令 SINTERSTORE 。
127.0.0.1:6379> SINTERSTORE inter1 b c
(integer) 2
127.0.0.1:6379> SMEMBERS inter1
1) "G"
2) "D"
并集
最后就是并集了,比较集合中全部的元素都获取到,使用的是 SUNION 。
127.0.0.1:6379> sunion a b c
1) "C"
2) "J"
3) "D"
4) "B"
5) "A"
6) "E"
7) "F"
8) "G"
9) "I"
10) "H"
127.0.0.1:6379> sunion a c
1) "G"
2) "C"
3) "J"
4) "D"
5) "B"
6) "A"
7) "I"
8) "H"
它也一样有保存到另一个集合的命令 SUNIONSTORE 。
127.0.0.1:6379> SUNIONSTORE sunion1 a c
(integer) 8
127.0.0.1:6379> SMEMBERS sunion1
1) "G"
2) "C"
3) "J"
4) "D"
5) "B"
6) "A"
7) "I"
8) "H"
增量迭代
和上一篇 Hash 中的 HSCAN 一样,在 Set 中也有一个 SSCAN ,同样是用于做迭代遍历的。我们还是需要先创建一个大一点的 Set 集合。
<?php
for ($i = 0; $i <= 100000; $i++) {
$data[] = 'k' . $i;
}
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$redis->sAddArray('d', $data);
然后就是对这个集合的迭代,相关的知识和参数上篇 HSCAN 中已经介绍过了,这里也就不再过多赘述了。
127.0.0.1:6379> SCARD d
(integer) 100001
127.0.0.1:6379> sscan d 0
1) "53248"
2) 1) "k12288"
2) "k72092"
3) "k63131"
4) "k52873"
5) "k54468"
6) "k16895"
7) "k51935"
8) "k66298"
9) "k26723"
10) "k65523"
127.0.0.1:6379> sscan d 53248
1) "10240"
2) 1) "k67890"
2) "k58599"
3) "k12540"
4) "k7451"
5) "k34905"
6) "k48765"
7) "k2167"
8) "k77963"
9) "k20956"
10) "k90465"
11) "k73384"
127.0.0.1:6379> sscan d 53248 match k6* count 1
1) "45056"
2) 1) "k67890"
总结
Set 这个类型的操作比较简单,功能也很清晰,是非常典型的中学数学学习过的集合的概念。那么它有哪些应用场景呢?一是集合操作,比如两个人的好友列表去重后推荐;二是随机推荐,比如电商网站边的一些推荐购买(当然现在更多是大数据AI推荐了)或者推荐文章,另外像是年会抽奖,随机弹一个幸运儿出来;三是唯一性,一些需要唯一的集合数据,比如IP地址、手机号的存储等。总之,高效、方便地帮我们去重,还有这么多方便的操作命令,这个家伙你值得拥有。
视频链接
微信文章地址:https://mp.weixin.qq.com/s/hbjwnwag0co8QnFmEz6VXg