【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 集合。

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地址、手机号的存储等。总之,高效、方便地帮我们去重,还有这么多方便的操作命令,这个家伙你值得拥有。

你可能感兴趣的:(redis,java,数据库,缓存,开发语言)