当前位置:网站首页>怎么利用Redis实现点赞功能
怎么利用Redis实现点赞功能
2022-06-30 02:38:00 【亿速云】
怎么利用Redis实现点赞功能
这篇文章主要介绍“怎么利用Redis实现点赞功能”,在日常操作中,相信很多人在怎么利用Redis实现点赞功能问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么利用Redis实现点赞功能”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
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*/@Overridepublic void saveLiked2Redis(String likedUserId, String likedPostId) { String key = RedisKeyUtils.getLikedKey(likedUserId, likedPostId); redisTemplate.opsForHash().put(RedisKeyUtils.MAP_KEY_USER_LIKED,key, LikedStatusEnum.LIKE.getCode());}//取消点赞@Overridepublic 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*/@Overridepublic void incrementLikedCount(String likedUserId) { redisTemplate.opsForHash().increment(RedisKeyUtils.MAP_KEY_USER_LIKED_COUNT,likedUserId,1);}//[email protected] void decrementLikedCount(String likedUserId) { redisTemplate.opsForHash().increment(RedisKeyUtils.MAP_KEY_USER_LIKED_COUNT, likedUserId, -1);}/*** 获取Redis中的用户点赞详情记录*/@Overridepublic List<UserLikeDetail> getLikedDataFromRedis() { Cursor<Map.Entry<Object,Object>> 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中的用户被点赞数量*/@Overridepublic List<UserLikCountDTO> getLikedCountFromRedis() { Cursor<Map.Entry<Object,Object>> 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;}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的用户点赞数据到数据库@[email protected] 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); } });}@[email protected] 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); } });}
到此,关于“怎么利用Redis实现点赞功能”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!
边栏推荐
- Pytoch learning (II)
- 重磅来袭--UE5的开源数字孪生解决方案
- [dry goods sharing] the latest WHQL logo certification application process
- Bucket sort
- CMake教程系列-02-使用cmake代码生成二进制
- 1380. lucky numbers in matrices
- PMP考生如何应对新考纲?看过来!
- FDA邮件安全解决方案
- Global and Chinese market of mobile commerce solutions 2022-2028: Research Report on technology, participants, trends, market size and share
- 2022年7月深圳地区CPDA数据分析师认证
猜你喜欢

Precautions for purchasing wildcard SSL certificate

How vscode debugs into standard library files / third-party package source code

Select sort

主流CA吊销俄罗斯数字证书启示:升级国密算法SSL证书,助力我国网络安全自主可控

Raki's notes on reading paper: discontinuous named entity recognition as maximum clique discovery

IBM websphere通道联通搭建和测试

Wechat applet page Jump and parameter transfer

选购通配符SSL证书注意事项

如何使用SMS向客户传递服务信息?指南在这里!

什么是自签名证书?自签名SSL证书的优缺点?
随机推荐
Jupyter notebook displays a collection of K-line graphs
002 color classification
SQLite使用
银行的理财产品一般期限是多久?
RAII内存管理
Ffmpeg source code
2022年7月深圳地区CPDA数据分析师认证
隐藏在科技教育中的steam元素
如何预防钓鱼邮件?S/MIME邮件证书来支招
Heap sort
Shenzhen CPDA Data Analyst Certification in July 2022
Select sort
新考纲下的PMP考试有多难?全面解析
Merge sort
Pytorch学习(二)
[论]【DSTG】Dynamic SpatiotemporalGraph Convolutional Neural Networks for Traffic Data Imputation
Matlab code running tutorial (how to run the downloaded code)
Jupyter notebook显示k线图集合
Seven common errors of SSL certificate and their solutions
重磅来袭--UE5的开源数字孪生解决方案