利用Redis实现点赞功能的示例代码
本篇文章向大家介绍《利用Redis实现点赞功能的示例代码》,主要包括Redis点赞,具有一定的参考价值,需要的朋友可以参考一下。
提到点赞,大家一想到的是不是就是朋友圈的点赞呀?其实点赞对我们来说并不陌生,我们经常会在手机软件或者网页中看到它,今天就让我们来了解一下它的实现吧。我们常见的设计思路大概分为两种:一种自然是用 MySQL 等数据库直接落地存储, 另外一种就是将点赞的数据保存到 Redis 等缓存里,在一定时间后刷回 MySQL 等数据库。
MySQL 和 Redis优缺点
首先我们来说一下两种方法各自的优缺点:我们以 MySQL 和 Redis 为例。
1、直接写入数据库:
优点:这种方法实现简单,只需完成数据库的增删改查就行;
缺点:数据库读写压力大,如果遇到热门文章在短时间内被大量点赞的情况,直接操作数据库会给数据库带来巨大压力,影响效率。
2、使用 Redis 缓存:
优点:性能高,读写速度快,缓解数据库读写的压力;
缺点:开发复杂,不能保证数据安全性即 redis 挂掉的时候会丢失数据, 同时不及时同步 redis 中的数据, 可能会在 redis 内存置换的时候被淘汰掉。不过对于点赞数据我们不需要那么精确,丢失一点数据问题不大。
接下来就从以下三个方面对点赞功能做详细的介绍
•Redis 缓存设计
•数据库设计
•开启定时任务持久化存储到数据库
1、Redis 缓存设计及实现
Redis 的整合我们在上一篇文章中已经介绍过了,此处就不再赘述了。我们了解到,我们在做点赞的时候需要记录以下几类数据:一类是某用户被其他用户点赞的详细记录,一类是。考虑到查询与存取方便快捷,我这边采用 Hash 结构进行存储,存储结构如下:
(1)某用户被其他用户点赞的详细记录: MAP_USER_LIKED
为键值, 被点赞用户id::点赞用户id 为 filed, 1或者0 为 value
(2)某用户被点赞的数量统计: MAP_USER_LIKED_COUNT
为键值, 被点赞用户id 为 filed, count
为 value
部分代码如下
/** * 将用户被其他用户点赞的数据存到redis */ @Override public void saveLiked2Redis(String likedUserId, String likedPostId) { String key = RedisKeyUtils.getLikedKey(likedUserId, likedPostId); redisTemplate.opsForHash().put(RedisKeyUtils.MAP_KEY_USER_LIKED,key, LikedStatusEnum.LIKE.getCode()); } //取消点赞 @Override public void unlikeFromRedis(String likedUserId, String likedPostId) { String key = RedisKeyUtils.getLikedKey(likedUserId, likedPostId); redisTemplate.opsForHash().put(RedisKeyUtils.MAP_KEY_USER_LIKED,key,LikedStatusEnum.UNLIKE.getCode()); } /** * 将被点赞用户的数量+1 */ @Override public void incrementLikedCount(String likedUserId) { redisTemplate.opsForHash().increment(RedisKeyUtils.MAP_KEY_USER_LIKED_COUNT,likedUserId,1); } //-1 @Override public void decrementLikedCount(String likedUserId) { redisTemplate.opsForHash().increment(RedisKeyUtils.MAP_KEY_USER_LIKED_COUNT, likedUserId, -1); } /** * 获取Redis中的用户点赞详情记录 */ @Override public List<userlikedetail> getLikedDataFromRedis() { Cursor<map.entry>> scan = redisTemplate.opsForHash().scan(RedisKeyUtils.MAP_KEY_USER_LIKED, ScanOptions.NONE); List<userlikedetail> list = new ArrayList(); while (scan.hasNext()){ Map.Entry<object object> entry = scan.next(); String key = (String) entry.getKey(); String[] split = key.split("::"); String likedUserId = split[0]; String likedPostId = split[1]; Integer value = (Integer) entry.getValue(); //组装成 UserLike 对象 UserLikeDetail userLikeDetail = new UserLikeDetail(likedUserId, likedPostId, value); list.add(userLikeDetail); //存到 list 后从 Redis 中删除 redisTemplate.opsForHash().delete(RedisKeyUtils.MAP_KEY_USER_LIKED, key); } return list; } /** * 获取Redis中的用户被点赞数量 */ @Override public List<userlikcountdto> getLikedCountFromRedis() { Cursor<map.entry>> cursor = redisTemplate.opsForHash().scan(RedisKeyUtils.MAP_KEY_USER_LIKED_COUNT, ScanOptions.NONE); List<userlikcountdto> list = new ArrayList(); while(cursor.hasNext()){ Map.Entry<object object> map = cursor.next(); String key = (String) map.getKey(); Integer value = (Integer) map.getValue(); UserLikCountDTO userLikCountDTO = new UserLikCountDTO(key,value); list.add(userLikCountDTO); //存到 list 后从 Redis 中删除 redisTemplate.opsForHash().delete(RedisKeyUtils.MAP_KEY_USER_LIKED_COUNT,key); } return list; }</object></userlikcountdto></map.entry></userlikcountdto></object></userlikedetail></map.entry></userlikedetail>
Redis 存储结构如图
2、数据库设计
这里我们可以和直接将点赞数据存到数据库一样,设计两张表:
(1)用户被其他用户点赞的详细记录:user_like_detail
DROP TABLE IF EXISTS `user_like_detail`; CREATE TABLE `user_like_detail` ( `id` int(11) NOT NULL AUTO_INCREMENT, `liked_user_id` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '被点赞的用户id', `liked_post_id` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '点赞的用户id', `status` tinyint(1) NULL DEFAULT 1 COMMENT '点赞状态,0取消,1点赞', `create_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '创建时间', `update_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '修改时间', PRIMARY KEY (`id`) USING BTREE, INDEX `liked_user_id`(`liked_user_id`) USING BTREE, INDEX `liked_post_id`(`liked_post_id`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '用户点赞表' ROW_FORMAT = Dynamic; SET FOREIGN_KEY_CHECKS = 1;
(2)用户被点赞的数量统计:user_like_count
DROP TABLE IF EXISTS `user_like_count`; CREATE TABLE `user_like_count` ( `id` int(11) NOT NULL AUTO_INCREMENT, `like_num` int(11) NULL DEFAULT 0, PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; SET FOREIGN_KEY_CHECKS = 1;
3、开启定时任务持久化存储到数据库
我们使用 Quartz 来实现定时任务,将 Redis 中的数据存储到数据库中,为了演示效果,我们可以设置一分钟或者两分钟存储一遍数据,这个视具体业务而定。在同步数据的过程中,我们首先要将 Redis 中的数据在数据库中进行查重,舍弃重复数据,这样我们的数据才会更加准确。
部分代码如下
//同步redis的用户点赞数据到数据库 @Override @Transactional public void transLikedFromRedis2DB() { List<userlikedetail> list = redisService.getLikedDataFromRedis(); list.stream().forEach(item->{ //查重 UserLikeDetail userLikeDetail = userLikeDetailMapper.selectOne(new LambdaQueryWrapper<userlikedetail>() .eq(UserLikeDetail::getLikedUserId, item.getLikedUserId()) .eq(UserLikeDetail::getLikedPostId, item.getLikedPostId())); if (userLikeDetail == null){ userLikeDetail = new UserLikeDetail(); BeanUtils.copyProperties(item, userLikeDetail); //没有记录,直接存入 userLikeDetail.setCreateTime(LocalDateTime.now()); userLikeDetailMapper.insert(userLikeDetail); }else{ //有记录,需要更新 userLikeDetail.setStatus(item.getStatus()); userLikeDetail.setUpdateTime(LocalDateTime.now()); userLikeDetailMapper.updateById(item); } }); } @Override @Transactional public void transLikedCountFromRedis2DB() { List<userlikcountdto> list = redisService.getLikedCountFromRedis(); list.stream().forEach(item->{ UserLikeCount user = userLikeCountMapper.selectById(item.getKey()); //点赞数量属于无关紧要的操作,出错无需抛异常 if (user != null){ Integer likeNum = user.getLikeNum() + item.getValue(); user.setLikeNum(likeNum); //更新点赞数量 userLikeCountMapper.updateById(user); } }); } </userlikcountdto></userlikedetail></userlikedetail>
至此我们就实现了基于 Redis 的点赞功能,我们还需要注意一点:查询用户点赞情况时,需要同时查询数据库+缓存中的数据。
以上就是本文的全部内容了,是否有顺利帮助你解决问题?若是能给你带来学习上的帮助,请大家多多支持golang学习网!更多关于数据库的相关知识,也可关注golang学习网公众号。

- 上一篇
- Redis哨兵模式实现一主二从三哨兵

- 下一篇
- Redis实现库存扣减的解决方案防止商品超卖
-
- 高大的台灯
- 这篇技术贴太及时了,太细致了,赞 ??,已收藏,关注老哥了!希望老哥能多写数据库相关的文章。
- 2023-03-21 07:55:03
-
- 如意的蜜粉
- 很好,一直没懂这个问题,但其实工作中常常有遇到...不过今天到这,看完之后很有帮助,总算是懂了,感谢楼主分享博文!
- 2023-01-30 03:55:59
-
- 数据库 · Redis | 4小时前 |
- Redis与MySQL缓存同步方法解析
- 245浏览 收藏
-
- 数据库 · Redis | 5小时前 |
- Redis性能监控工具有哪些
- 124浏览 收藏
-
- 数据库 · Redis | 6小时前 |
- RedisList队列优化方法分享
- 378浏览 收藏
-
- 数据库 · Redis | 6小时前 |
- Redis位图实现用户签到优化方案
- 322浏览 收藏
-
- 数据库 · Redis | 15小时前 |
- Redis数据安全防护全攻略
- 112浏览 收藏
-
- 数据库 · Redis | 15小时前 |
- Redis哈希技巧与实战应用
- 204浏览 收藏
-
- 数据库 · Redis | 15小时前 |
- 扩展Redis集群节点的步骤与注意事项
- 163浏览 收藏
-
- 数据库 · Redis | 16小时前 |
- 高并发Redis优化技巧分享
- 147浏览 收藏
-
- 数据库 · Redis | 16小时前 |
- Redis主从复制故障排查指南
- 477浏览 收藏
-
- 数据库 · Redis | 20小时前 |
- Redis与HBase存储方案详解
- 414浏览 收藏
-
- 数据库 · Redis | 23小时前 |
- Redis与MongoDB缓存优化方法
- 193浏览 收藏
-
- 数据库 · Redis | 1天前 |
- Redis安全配置更新操作教程
- 313浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 542次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 511次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 498次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 484次学习
-
- 千音漫语
- 千音漫语,北京熠声科技倾力打造的智能声音创作助手,提供AI配音、音视频翻译、语音识别、声音克隆等强大功能,助力有声书制作、视频创作、教育培训等领域,官网:https://qianyin123.com
- 96次使用
-
- MiniWork
- MiniWork是一款智能高效的AI工具平台,专为提升工作与学习效率而设计。整合文本处理、图像生成、营销策划及运营管理等多元AI工具,提供精准智能解决方案,让复杂工作简单高效。
- 89次使用
-
- NoCode
- NoCode (nocode.cn)是领先的无代码开发平台,通过拖放、AI对话等简单操作,助您快速创建各类应用、网站与管理系统。无需编程知识,轻松实现个人生活、商业经营、企业管理多场景需求,大幅降低开发门槛,高效低成本。
- 107次使用
-
- 达医智影
- 达医智影,阿里巴巴达摩院医疗AI创新力作。全球率先利用平扫CT实现“一扫多筛”,仅一次CT扫描即可高效识别多种癌症、急症及慢病,为疾病早期发现提供智能、精准的AI影像早筛解决方案。
- 98次使用
-
- 智慧芽Eureka
- 智慧芽Eureka,专为技术创新打造的AI Agent平台。深度理解专利、研发、生物医药、材料、科创等复杂场景,通过专家级AI Agent精准执行任务,智能化工作流解放70%生产力,让您专注核心创新。
- 98次使用
-
- 使用Redis实现点赞取消点赞的详细代码
- 2023-01-07 322浏览