欢迎各位彦祖与热巴畅游本人专栏与博客
你的三连是我最大的动力
以下图片仅代表专栏特色 [点击箭头指向的专栏名即可闪现]
专栏跑道一
➡️网络空间安全——全栈前沿技术持续深入学习
专栏跑道二
➡️ 24 Network Security -LJS
专栏跑道三
➡️ MYSQL REDIS Advance operation
专栏跑道四
➡️HCIP;H3C-SE;CCIP——LJS[华为、华三、思科高级网络]
专栏跑道五
➡️RHCE-LJS[Linux高端骚操作实战篇]
专栏跑道六
➡️数据结构与算法[考研+实际工作应用+C程序设计]
专栏跑道七
➡️RHCSA-LJS[Linux初级及进阶骚技能]
上节回顾
Redis数据类型之Set类型及操作
1. Set 类型及操作
1.1简介:
在Redis中,我们可以将Set类型看作为没有排序的字符集合,和List类型一样,我们也可以在该类型的数据值上执行添加、删除或判断某一元素是否存在等操作。
需要说明的是,这些操作的时间复杂度为 O(1),即常量时间内完成次操作。
Set可包含的最大元素数量是4294967295。和List类型不同的是,这一点和C++标准库中的set容器是完全相同的。
换句话说,如果多次添加相同元素,Set 中将仅保留该元素的一份拷贝。
和List类型相比,Set类型在功能上还存在着一个非常重要的特性,即在服务器端完成多个Sets之间的聚合计算操作
如 unions、intersections和differences。由于这些操作均在服务端完成,因此效率极高,而且也节省了大量的网络IO开销
1.2Set的三个特性无序性:
- 无序性:集合里面数据是没顺序区分。
- 确定性:集合里面数据个数是确定的。
- 唯一性:集合里面数据不能彼此重复。
2. Set 相关命令列表
2.1Set 类型及相关命令列表及其语法格式说明表一
Set 类型及相关命令列表和其 语法格式说明表一
命令原型 | 时间复杂度 | 命令描述 | 返回值 |
SADD key member [member ...] | O(N) |
|
|
SCARD key | O(1) |
|
|
SISMEMBER key member | O(1) |
|
|
SISMEMBER key member SMEMBERS key |
O(1) |
|
|
SPOP key |
O(N) |
|
|
SREM key member [member ...] |
O(1) |
|
|
SRANDMEMBER key | O(N) |
|
|
2.1Set 类型及相关命令列表及其语法格式说明表二
Set类型及相关命令列表二
命令原型 | 时间复杂度 | 命令描述 | 返回值 |
SMOVE source destination member | O(1) |
|
|
SDIFF key [key ...] | O(N) |
|
|
SDIFFSTORE destination key [key ...] | O(N) |
|
|
SINTER key [key ...] | O(N*M) |
|
|
SINTERSTORE destination key [key ...] | O(N*M) |
|
|
SUNION key [key ...] | O(N) |
|
|
SUNIONSTORE destination key [key ...] | O(N) |
|
|
3.1Set类型及操作相关命令举例
1. SADD/SMEMBERS/SCARD/SISMEMBER
- 在Shell命令行下启动Redis的客户端程序
/> redis-cli
- 插入测试数据,由于该键myset之前并不存在,因此参数中的三个成员都被正常插入
redis 127.0.0.1:6379>sadd myset a b c (integer) 3
- 由于参数中的a在myset中已经存在,因此本次操作仅仅插入了d和e两个新成员
redis 127.0.0.1:6379>sadd myset a d e (integer) 2
- 判断a是否已经存在,返回值为1表示存在
redis 127.0.0.1:6379>sismember myset a (integer) 1
- 判断f是否已经存在,返回值为0表示不存在
redis 127.0.0.1:6379>sismember myset f (integer) 0
- 通过smembers命令查看插入的结果,从结果可以,输出的顺序和插入顺序无关
redis 127.0.0.1:6379> smembers myset 1) "c" 2) "d" 3) "a" 4) "b" 5) "e"
- 获取Set集合中元素的数量
redis 127.0.0.1:6379>scard myset (integer) 5
3.2 SPOP/SREM/SRANDMEMBER/SMOVE
- 删除该键,便于后面的测试
redis 127.0.0.1:6379>del myset (integer) 1
- 为后面的例子准备测试数据
redis 127.0.0.1:6379>sadd myset a b c d (integer) 4
- 查看Set中成员的位置
redis 127.0.0.1:6379> smembers myset 1) "c" 2) "d" 3) "a" 4) "b"
- 结果可以看出,该命令确实是随机的返回了某一成员
redis 127.0.0.1:6379>srandmember myset "c"
- Set中尾部的成员b被移出并返回,事实上b并不是之前插入的第一个或最后一个成员
redis 127.0.0.1:6379>spop myset "b"
- 查看移出后Set的成员信息
redis 127.0.0.1:6379> smembers myset 1) "c" 2) "d" 3) "a"
- 从Set中移出a、d和f三个成员,其中f并不存在,因此只有a和d两个成员被移出,返回为2
redis 127.0.0.1:6379>srem myset a d f (integer) 2
- 查看移出后的输出结果
redis 127.0.0.1:6379>smembers myset 1) "c"
- 为后面的smove命令准备数据
redis 127.0.0.1:6379>sadd myset a b (integer) 2 redis 127.0.0.1:6379>sadd myset2 c d (integer) 2
- 将a从myset移到myset2,从结果可以看出移动成功
redis 127.0.0.1:6379>smove myset myset2 a (integer) 1
- 再次将a从myset移到myset2,由于此时a已经不是myset的成员了,因此移动失败并返回0
redis 127.0.0.1:6379>smove myset myset2 a (integer) 0
- 分别查看myset和myset2的成员,确认移动是否真的成功
redis 127.0.0.1:6379>smembers myset 1) "b" redis 127.0.0.1:6379> smembers myset2 1) "c" 2) "d" 3) "a"
3.3SDIFF/SDIFFSTORE/SINTER/SINTERSTORE
- 为后面的命令进而准备测试数据
redis 127.0.0.1:6379>sadd myset a b c d (integer) 4 redis 127.0.0.1:6379> sadd myset2 c (integer) 1 redis 127.0.0.1:6379>sadd myset3 a c e (integer) 3
- myset和myset2相比,a、b和d三个成员是两者之间的差异成员。
- 再用这个结果继续和myset3进行差异比较,b和d是myset3不存在的成员
redis 127.0.0.1:6379>sdiff myset myset2 myset3 1) "d" 2) "b"
- 将3个集合的差异成员存在在diffkey关联的Set中,并返回插入的成员数量
redis 127.0.0.1:6379>sdiffstore diffkey myset myset2 myset3 (integer) 2
- 查看一下sdiffstore的操作结果
redis 127.0.0.1:6379>smembers diffkey 1) "d" 2) "b"
- 从之前准备的数据就可以看出,这三个Set的成员交集只有c
redis 127.0.0.1:6379>sinter myset myset2 myset3 1) "c
- 将3个集合中的交集成员存储到与interkey关联的Set中,并返回交集成员的数量
redis 127.0.0.1:6379> sinterstore interkey myset myset2 myset3 (integer) 1
- 查看一下sinterstore的操作结果
redis 127.0.0.1:6379>smembers interkey 1) "c"
- 获取3个集合中的成员的并集
redis 127.0.0.1:6379>sunion myset myset2 myset3 1) "b" 2) "c" 3) "d" 4) "e" 5) "a"
- 将3个集合中成员的并集存储到unionkey关联的set中,并返回并集成员的数量
redis 127.0.0.1:6379>sunionstore unionkey myset myset2 myset3 (integer) 5
- 查看一下suiionstore的操作结果
redis 127.0.0.1:6379>smembers unionkey 1) "b" 2) "c" 3) "d" 4) "e" 5) "a"
4.应用场景
- 可以使用Redis的Set数据类型跟踪一些唯一性数据
- 比如访问某一博客的唯一IP地址信息。对于此场景,我们仅需在每次访问该博客时将访问者的IP存入Redis中,Set数据类型会自动保证IP地址的唯一性。
- 充分利用Set类型的服务端聚合操作方便、高效的特性,可以用于维护数据对象之间的关联关系。
- 比如所有购买某一电子设备的客户ID被存储在一个指定的 Set中,而购买另外一种电子产品的客户ID被存储在另外 一个Set中,
- 如果此时我们想获取有哪些客户同时购买了这两种商品时,Set的 intersections命令就可以充分发挥它的方便和效率的优势了
5.应用场景举例
5.1设计四个好友
[root@localhost ~]# redis-cli 127.0.0.1:6379> set it_user:id:1:username tom OK 127.0.0.1:6379> set it_user:id:1:email tom@qq.ocm一个简单的实例 sns的常用功能,获取共同好友 OK 127.0.0.1:6379> set it_user:id:2:username john OK 127.0.0.1:6379> set it_user:id:2:email john@qq.ocm OK 127.0.0.1:6379> set it_user:id:3:username bob OK 127.0.0.1:6379> set it_user:id:3:email bob@qq.com OK 127.0.0.1:6379> set it_user:id:4:username smith OK 127.0.0.1:6379> set it_user:id:4:email smith@qq.com OK 127.0.0.1:6379> keys it_user:id*
1) "it_user:id:4:username" 2) "it_user:id:1:username" 3) "it_user:id:2:username" 4) "it_user:id:2:email" 5) "it_user:id:1:email" 6) "it_user:id:3:email" 7) "it_user:id:4:email" 8) "it_user:id:3:username"
5.2设定好友集合
#1号好友为2号和3号 127.0.0.1:6379> sadd set:user:id:1:friend 2 (integer) 1 127.0.0.1:6379> sadd set:user:id:1:friend 3 (integer) 1 127.0.0.1:6379> SMEMBERS set:user:id:1:friend 1) "2" 2) "3"
#4号好友为3号 127.0.0.1:6379> sadd set:user:id:4:friend 3 (integer) 1 127.0.0.1:6379> SMEMBERS set:user:id:4:friend 1) "3"
5.3好友关系
#共同好友(交集) 127.0.0.1:6379> SINTER set:user:id:1:friend set:user:id:4:friend 1) "3" #全部好友(并集) 127.0.0.1:6379> sunion set:user:id:1:friend set:user:id:4:friend 1) "2" 2) "3" #推荐好友(差集) 127.0.0.1:6379> SDIFF set:user:id:1:friend set:user:id:4:friend 1) "2"
- 效果图
- 编