假设我们存在这样的需求:我们需要存储大量的数据,且需要在查询上要求更高的效率。似乎前面提到的数据类型已不满足我们现有的需求,在本篇文章中,我们引入一个全新的概念:set数据类型。与hash存储结构类似,但是仅存储键,不存储值(nil),并且不重复存储。
本篇是该系列文章的第七篇,你可以通过以下链接阅读之前的内容
03-redis入门知识第3篇-redis的基本操作与数据类型
04-redis入门知识第4篇-redis中的string数据类型与基本的数据存取操作
sadd key member1 [member2]
smembers key
srem key member1 [member2]
scard key
sismember key member
公司旗下新的网站做推广,统计网站的 PV(访问量),UV(独立访客),IP(独立 IP)
PV:网站被访问次数,可通过刷新界面提交访问量
UV:网站被不同用户访问的次数,可通过 cookie 统计访问量,相同用户切换 IP 地址,UV 不变
IP:网站被不同 IP 地址访问的总次数,可通过 IP 地址统计访问量,相同 IP 不同用户访问,IP 不变
解决方案
如记录不同的 IP,示例指令如下:
sadd ips 1.2.3.4
sadd ips 2.3.4.5
sadd ips 2.3.4.5
虽然我们记录了 3 次 IP 地址,但有两次 IP 地址是一样的,所以一共有两个 IP,使用scard ips
指令可以看到以下结果
(integer) 2
srandmember key [count]
spop key [count]
假设我们现在有这样的需求:每位用户首次使用新闻APP时,会推荐三项的爱好内容。但是后期为了增加用户的活跃度、兴趣点,必须让用户对其他信息类别逐渐产生兴趣,增加客户存留度,如何实现?
解决方案
通过 redis 的随机特性,我们可以将 redis 应用于随机类信息的检索,例如点歌单推荐,热点信息推荐,热卖旅游路线,应用 APP 推荐,大 V 推荐等等。
在redis中,我们可以使用以下操作指令进行集合操作
# 求交叉的数据
sinter key1 [key2...]
# 求合并的数据
sunion key1 [key2...]
# 求相差的数据,有方向性,用key1的集合 减去key1与key2的并集,得到的结果就是差集
sdiff key1 [key2...]
sinterstore desination key1 [key2...]
sunionstore desination key1 [key2...]
sdiffstore desination key1 [key2...]
示例:将 u1 与 u2 的交集存到 u3
sinterstore u3 u1 u2
smove source destination member
示例:将 u2 的 w1 移到 u1
smove u2 u1 w1
假设我们有如下需求
社交APP为了促进用户之间的交流,需要让每位用户拥有大量的好友,如何快速为用户积累更多的好友?
社区APP为了增加用户热度,提高用户存留性,需要用户在关注更多的人,以此获得更多的信息或热门话题,如何提高用户关注他人的总量?
外卖APP为了提升成单量,必须帮助用户挖掘美食需求,如何推荐用户最适合自己的美食?
对用户同类的信息进行关联搜索,二度关联搜索,深度关联搜索,示例如下:
对于 set 数据类型,我们要注意以下事项:
集团公司共有 12000 名员工,内部 OA 系统具有 700 多个角色,3000 多个业务操作,每位员工有一个或者多个角色,如何快速进行业务操作的权限校验?
操作过程如下示例:
# 给001角色添加2个权限:getall、getById
sadd rid:001 getall
sadd rid:001 getById
# 给002角色添加3个权限:getCount、getall、insert
sadd rid:002 getCount
sadd rid:002 getall
sadd rid:002 insert
# 将两个角色所有权限的交集保存给 007 用户
sunionstore uid:007 rid:001 rid:002
# 这时候查询 007 用户的权限列表
smembers uid:007
可以看到用户 007 具有已经包含和 001 角色和 002 角色的所有权限,如下:
1) "getCount"
2) "insert"
3) "getall"
4) "getById"
当然,除了查询出用户 007 的所有权限,我们还能检验 007 是否具有具体某个权限,如下指令
sismember uid:007 insert
返回结果如下
(integer) 1
可以看到 uid:007 这个集合包含 insert 这个元素,可以证明 007 这个用户具有 insert 权限
根据上面的权限校验示例,我们可以通过上面两种方式检验用户是否具有某个权限。
我们可以根据实际需求选择第一种还是第二种,但是在大型的模块化应用中,更鼓励大家使用 第一种方法,以达到 数据读取 与 业务逻辑 的分离。