redis数据类型 Set (集合)

1 基本命令

  • 插入、删除、查找
       和 Java 的 Set 差不多,不可重复插入相同数据,无序。
127.0.0.1:6379> SADD num one	# 插入元素
(integer) 1
127.0.0.1:6379> SADD num two
(integer) 1
127.0.0.1:6379> SADD num three
(integer) 1
127.0.0.1:6379> SMEMBERS num	# 获取集合所有值(可以和 List 作对比看出,Set 是无序的)
1) "three"
2) "one"
3) "two"
127.0.0.1:6379> SADD num three	# 可以看出,不可重复插入相同数据
(integer) 0
127.0.0.1:6379> SCARD num	# 获取集合大小
(integer) 3
127.0.0.1:6379> SISMEMBER num three	# 判断元素是否存在
(integer) 1
127.0.0.1:6379> SREM num three	# 移除元素
(integer) 1
127.0.0.1:6379> SMEMBERS num
1) "one"
2) "two"
  • 随机数(获取、删除)
127.0.0.1:6379> SMEMBERS num
1) "two"
2) "zero"
3) "three"
4) "four"
5) "one"
6) "five"
7) "six"
127.0.0.1:6379> SRANDMEMBER num 2	# 随机获取指定数量的值
1) "four"
2) "five"
127.0.0.1:6379> SRANDMEMBER num 2
1) "zero"
2) "two"
127.0.0.1:6379> SPOP num	# 随机移除指定数量的值(默认一个)
"three"
127.0.0.1:6379> SMEMBERS num
1) "zero"
2) "two"
3) "four"
4) "one"
5) "five"
6) "six"
  • 移动指定值到另一个集合中
127.0.0.1:6379> SMEMBERS num
1) "zero"
2) "four"
3) "five"
4) "six"
127.0.0.1:6379> SMOVE num num2 zero	# 移动指定值到另一个集合,其中 num 为原集合,num2 为目标集合(原子性操作)
(integer) 1
127.0.0.1:6379> SMEMBERS num
1) "four"
2) "five"
3) "six"
127.0.0.1:6379> SMEMBERS num2
1) "zero"
  • 差集、交集、并集
127.0.0.1:6379> SMEMBERS num
1) "four"
2) "five"
3) "six"
127.0.0.1:6379> SMEMBERS num2
1) "four"
2) "five"
3) "one"
4) "zero"
127.0.0.1:6379> SDIFF num num2	# 差集(这里要注意集合前后顺序,表示第一个集合与第二个集合的不同,注重点在第一个集合,适用于推荐好友)
1) "six"
127.0.0.1:6379> SDIFF num2 num # 差集(这里要注意集合前后顺序,表示第一个集合与第二个集合的不同,注重点在第二个集合,适用于推荐好友)
1) "zero"
2) "one"
127.0.0.1:6379> SINTER num num2	# 交集(适用于某些网站共同关注的博主)
1) "four"
2) "five"
127.0.0.1:6379> SUNION num num2	# 并集
1) "four"
2) "one"
3) "five"
4) "six"
5) "zero"

2 适用场景

  • 好友/关注/粉丝/感兴趣的人集合

  Set 类型唯一的特点使得其适合用于存储好友/关注/粉丝/感兴趣的人集合,集合中的元素数量可能很多,每次全部取出来成本不小,Set 类型提供了一些很实用的命令用于直接操作这些集合。

如:
a.sinter 命令可以获得 A 和 B 两个用户的共同好友
b. sismember 命令可以判断 A 是否是 B 的好友
c. scard 命令可以获取好友数量
d. 关注时,smove 命令可以将 B 从 A 的粉丝集合转移到 A 的好友集合

  需要注意的是,如果你用的是 Redis Cluster 集群,对于sinter、smove 这种操作多个 key 的命令,要求这两个 key 必须存储在同一个 slot(槽位)中,否则会报出 (error) CROSSSLOT Keys in request don’t hash to the same slot 错误。Redis Cluster 一共有 16384 个 slot,每个 key 都是通过哈希算法 CRC16(key) 获取数值哈希,再模 16384 来定位 slot 的。要使得两个 key 处于同一 slot,除了两个 key 一模一样,还有没有别的方法呢?答案是肯定的,Redis 提供了一种 Hash Tag 的功能,在 key 中使用 {} 括起 key 中的一部分,在进行 CRC16(key) mod 16384 的过程中,只会对 {} 内的字符串计算,例如 friend_set:{123456} 和 fans_set:{123456},分别表示用户 123456 的好友集合和粉丝集合,在定位 slot 时,只对 {} 内的 123456 进行计算,所以这两个集合肯定是在同一个 slot 内的,当用户 123456 关注某个粉丝时,就可以通过 smove 命令将这个粉丝从用户 123456 的粉丝集合移动到好友集合。相比于通过 srem 命令先将这个粉丝从粉丝集合中删除,再通过 sadd 命令将这个粉丝加到好友集合,smove 命令的优势是它是原子性的,不会出现这个粉丝从粉丝集合中被删除,却没有加到好友集合的情况。然而,对于通过 sinter 获取共同好友而言,Hash Tag 则无能为力,例如,要用 sinter 去获取用户 123456 和 456789 两个用户的共同好友,除非我们将 key 定义为 {friend_set}:123456 和 {friend_set}:456789,否则不能保证两个key会处于同一个 slot,但是如果真这样做的话,所有用户的好友集合都会堆积在同一个 slot 中,数据分布会严重不均匀,不可取,所以,在实战中使用 Redis Cluster 时,sinter 这个命令其实是不适合作用于两个不同用户对应的集合的(同理其它操作多个 key 的命令)。

  • 随机展示

  通常,App 首页的展示区域有限,但是又不能总是展示固定的内容,一种做法是先确定一批需要展示的内容,再从中随机获取。如酷狗音乐K歌擂台赛当日的打擂歌曲共 29 首,首页随机展示5首;昨日打擂金曲共 200 首,首页随机展示 30 首。Set 类型适合存放所有需要展示的内容,而 srandmember 命令则可以从中随机获取几个。

  • 黑名单/白名单

  经常有业务出于安全性方面的考虑,需要设置用户黑名单、Ip 黑名单、设备黑名单等,Set 类型适合存储这些黑名单数据,sismember 命令可用于判断用户、Ip、设备是否处于黑名单之中。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值