Redis Set 实现关注、取关和共同关注黑马点评第 9 章前半部分学习笔记本文整理自黑马点评 Redis 实战篇第 9 章前半部分。第 9 章的主题是「好友关注」前半部分主要解决两个问题用户如何关注/取关另一个用户以及如何用 Redis Set 快速查询共同关注。1. 这一篇解决什么问题黑马点评里有一个很常见的社交功能我可以关注一个博主 我也可以取消关注 进入某个博主主页时可以看到我和他都关注了哪些人。这里其实有两层问题第一层关注关系怎么存 第二层共同关注怎么快速查第 9.1 小节解决第一层用 MySQL 的tb_follow表保存关注关系。第 9.2 小节解决第二层用 Redis Set 保存每个用户关注的人然后通过交集查询共同关注。2. 关注关系本质上是什么关注关系不是用户和博客的关系而是用户和用户的关系。比如用户 5 关注了用户 10 用户 6 关注了用户 10 用户 5 关注了用户 20这说明用户 10 有两个粉丝5 和 6 用户 5 关注了两个人10 和 20项目中用tb_follow表表示这种关系对应实体类是TableName(tb_follow)publicclassFollowimplementsSerializable{TableId(valueid,typeIdType.AUTO)privateLongid;privateLonguserId;privateLongfollowUserId;privateLocalDateTimecreateTime;}最重要的是这两个字段userId 发起关注的人也就是粉丝 followUserId 被关注的人也就是博主如果数据库里有一条记录user_id 5 follow_user_id 10意思是用户 5 关注了用户 10。这个方向非常重要后面 Feed 流推送时也会依赖它。3. 关注和取关接口Controller 入口PutMapping(/{id}/{isFollow})publicResultfollow(PathVariable(id)LongfollowUserId,PathVariable(isFollow)BooleanisFollow){returnfollowService.follow(followUserId,isFollow);}请求示例PUT /follow/10/true表示当前登录用户关注用户 10。PUT /follow/10/false表示当前登录用户取消关注用户 10。这里没有让前端传当前用户 id因为当前用户应该由服务端从登录上下文中获取LonguserIdUserHolder.getUser().getId();这样可以避免用户伪造请求替别人关注或取关。4. 关注和取关的核心代码Service 实现OverridepublicResultfollow(LongfollowUserId,BooleanisFollow){LonguserIdUserHolder.getUser().getId();Stringkeyfollows:userId;if(isFollow){FollowfollownewFollow();follow.setUserId(userId);follow.setFollowUserId(followUserId);booleanisSuccesssave(follow);if(isSuccess){stringRedisTemplate.opsForSet().add(key,followUserId.toString());}}else{booleanisSuccessremove(newQueryWrapperFollow().eq(user_id,userId).eq(follow_user_id,followUserId));if(isSuccess){stringRedisTemplate.opsForSet().remove(key,followUserId.toString());}}returnResult.ok();}先看 MySQL 部分。关注时FollowfollownewFollow();follow.setUserId(userId);follow.setFollowUserId(followUserId);save(follow);等价于INSERTINTOtb_follow(user_id,follow_user_id)VALUES(当前登录用户id,被关注用户id);取关时remove(newQueryWrapperFollow().eq(user_id,userId).eq(follow_user_id,followUserId));等价于DELETEFROMtb_followWHEREuser_id当前登录用户idANDfollow_user_id被关注用户id;所以关注功能本质上很简单关注新增一条关系记录 取关删除一条关系记录5. 判断是否关注进入博主主页时前端需要知道当前用户是否已经关注了这个博主从而决定按钮显示「关注」还是「已关注」。ControllerGetMapping(/or/not/{id})publicResultisFollow(PathVariable(id)LongfollowUserId){returnfollowService.isFollow(followUserId);}ServiceOverridepublicResultisFollow(LongfollowUserId){LonguserIdUserHolder.getUser().getId();Integercountquery().eq(user_id,userId).eq(follow_user_id,followUserId).count();returnResult.ok(count0);}它对应的 SQL 是SELECTCOUNT(*)FROMtb_followWHEREuser_id当前登录用户idANDfollow_user_id被查看的用户id;如果数量大于 0说明已经关注。6. 为什么 9.2 要引入 Redis Set9.1 只用 MySQL 就可以完成关注、取关、判断是否关注。但 9.2 要做「共同关注」。假设当前用户是 5用户 5 关注了10, 20, 30现在打开用户 8 的主页用户 8 关注了20, 30, 40那么共同关注就是20, 30这本质上是集合交集{10, 20, 30} ∩ {20, 30, 40} {20, 30}Redis Set 天然适合这个场景因为它支持交集运算。7. Redis 中怎么保存关注集合每个用户维护一个 Setkey: follows:{userId} value: 该用户关注的所有用户 id比如follows:5 {10, 20, 30} follows:8 {20, 30, 40}关注成功时stringRedisTemplate.opsForSet().add(key,followUserId.toString());对应 Redis 命令SADD follows:5 10取关成功时stringRedisTemplate.opsForSet().remove(key,followUserId.toString());对应 Redis 命令SREM follows:5 10这里 MySQL 是真实数据源Redis Set 是为了共同关注查询做的加速结构。8. 共同关注接口ControllerGetMapping(/common/{id})publicResultfollowCommons(PathVariable(id)Longid){returnfollowService.followCommons(id);}请求示例GET /follow/common/8意思是查询当前登录用户和用户 8 的共同关注。ServiceOverridepublicResultfollowCommons(Longid){LonguserIdUserHolder.getUser().getId();Stringkeyfollows:userId;Stringkey2follows:id;SetStringintersectstringRedisTemplate.opsForSet().intersect(key,key2);if(intersectnull||intersect.isEmpty()){returnResult.ok(Collections.emptyList());}ListLongidsintersect.stream().map(Long::valueOf).collect(Collectors.toList());ListUserDTOusersuserService.listByIds(ids).stream().map(user-BeanUtil.copyProperties(user,UserDTO.class)).collect(Collectors.toList());returnResult.ok(users);}核心是这一行SetStringintersectstringRedisTemplate.opsForSet().intersect(key,key2);它对应 Redis 命令SINTER follows:5 follows:8得到共同关注的用户 id 后再回 MySQL 查询用户信息并转成UserDTO返回给前端。9. 数据链路总结关注链路用户点击关注 - PUT /follow/{id}/true - 获取当前登录用户 userId - tb_follow 新增关系 - Redis: SADD follows:{userId} {followUserId}取关链路用户点击取消关注 - PUT /follow/{id}/false - 获取当前登录用户 userId - tb_follow 删除关系 - Redis: SREM follows:{userId} {followUserId}共同关注链路进入博主主页 - GET /follow/common/{id} - 取 follows:{当前用户id} - 取 follows:{博主id} - Redis 求交集 - 根据交集 id 查用户信息 - 返回共同关注用户列表10. 容易踩的坑1. userId 和 followUserId 容易搞反userId 当前登录用户发起关注的人 followUserId 被关注的人博主2./follow/or/not/{id}不是取消关注接口它实际是判断是否关注接口。3. Redis Set 不是真实数据源真实关注关系仍然在 MySQL 的tb_follow表。Redis Set 是为了共同关注快速求交集。4. 共同关注查的是「两个人关注的人」的交集不是粉丝交集也不是谁关注了我。11. 面试怎么说如果面试官问共同关注怎么实现可以回答关注关系本身保存在 MySQL 的tb_follow表中字段user_id表示发起关注的人follow_user_id表示被关注的人。为了快速查询共同关注我在用户关注或取关时同步维护 Redis Setkey 是follows:{userId}value 是该用户关注的用户 id。查询共同关注时对当前用户和目标用户的两个 Set 做交集SINTER得到共同关注的用户 id再回数据库查询用户信息返回。12. 总结第 9 章前半部分可以浓缩成一句话MySQL 负责保存真实关注关系Redis Set 负责把每个用户关注的人组织成集合从而用交集快速实现共同关注。
企业数字化 ERP 产品动态
相关推荐
2026年7月亲测:深圳封箱机定制哪家强? 2026年7月亲测:深圳封箱机定制哪家强?行业痛点分析当前,深圳工字封箱机定制厂家面临着三大核心挑战:多规格切换效率低下、复杂场景适配性不足以及综合成本居高不下。传统设备在换型时需停机调整模具,耗时15-30分钟&… · 2026/9/12 2:03:27
文档格式互转还在求爷爷告奶奶?这款神器Word、PDF、Excel、PPT一键通吃! 工作中最抓狂的瞬间:精心排版的Word合同发给客户,格式全乱;Excel数据表转成PDF,表格线 mysteriously 消失;收到的PPT课件想改成Word笔记,复制粘贴到手酸;更别提那些冷门格式,电脑里根… · 2026/9/21 0:04:59
什么是函数式编程 在维基百科中,已经对函数式编程有了很详细的介绍。
那我们就来摘取一下Wiki上对Functional Programming的定义: In computer science, functional programming is a programming paradigm that treats computation as the evaluation of mathematical f… · 2026/9/21 14:36:11
企业信用建设与数据安全管理的关键实践 1. 企业信用建设的时代价值与行业意义在数字经济高速发展的当下,企业信用已成为衡量商业主体综合实力的重要维度。北京市信用承诺企业评选作为区域信用体系建设的重要抓手,其评选结果直接反映了企业在合规经营、契约精神和社会责任方面的综合表现。建投数… · 2026/9/23 16:44:11
AI助手安全机制解析:从开放式生态到官方工具商店 1. 为什么我们需要更可信的AI助手?在人工智能技术快速发展的今天,AI助手已经成为我们日常生活和工作中的重要伙伴。从简单的日程提醒到复杂的业务流程自动化,AI正在承担越来越多的责任。但随之而来的安全问题也日益凸显——当AI助手能够自主执… · 2026/9/23 16:44:11
全同态加密从原理到实践:噪声、自举与密文计算入门 最近在整理隐私计算这块的笔记,正好把全同态加密(Fully Homomorphic Encryption,简称FHE)这条线从概念到落地实践系统地过了一遍。写这篇东西的初衷很简单:我发现网上讲FHE的资料要么是纯学术论文风格的数学推导&#… · 2026/9/23 16:44:11
SAP Fiori后端授权模型解析与最佳实践 1. SAP Fiori 后端授权模型概述在 SAP Fiori 应用开发与部署过程中,后端授权模型往往是最容易被忽视却又最为关键的一环。很多开发团队花费大量时间在前端界面设计和用户体验优化上,却在授权配置环节草草了事,导致应用上线后出现各种权限问题… · 2026/9/23 16:44:04
科技公司网站模板:从设计原则到高性能落地实践 做科技公司网站模板这个事儿,说实话一开始我是有点抗拒的。前几年市面上号称"科技感"的模板,十有八九就是深色背景配一条紫色渐变,再加几个飘来飘去的粒子特效。客户看了觉得挺"科技",但真上线就露馅——页面… · 2026/9/23 16:44:04
OpenSpec:面向AI协作的接口契约协议层 1. OpenSpec不是另一个CLI工具,而是Spec驱动开发的底层协议层你第一次在GitHub上看到fission-ai/openspec这个包名时,大概率会下意识点开它的npm页面,扫一眼README,然后——关掉。因为标题写着“OpenSpec”,简介里却只… · 2026/9/23 16:44:04
3招搞定手机怎么下载微信面试难题实战项目解析 3招搞定手机怎么下载微信面试难题实战项目解析 面试被问“手机怎么下载微信”背后的原理,90%的人答不上来。别笑,这看似弱智的问题,实则是考察你对移动应用分发机制、安全校验及网络协议理解的试金石。我带过不少校招新人,他们背了八股文,却连一个A… · 2026/9/23 0:00:03
你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型 你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型 面试被问“高并发下如何保证消息不丢失”,你张口就是“用Redis”,结果面试官追问“如果Redis宕机了怎么办”,你瞬间卡壳。这种场景太常见了,很多新手在背八股文时,只记住了技术名词… · 2026/9/23 0:00:29