Redis点赞业务设计与实现(Redis键值设计)

网友投稿 681 2022-05-29

【辰兮要努力】:hello你好我是辰兮,很高兴你能来阅读,昵称是希望自己能不断精进,向着优秀程序员前行!

博客来源于项目以及编程中遇到的问题总结,偶尔会有读书分享,我会陆续更新Java前端、后台、数据库、项目案例等相关知识点总结,感谢你的阅读和关注,希望我的博客能帮助到更多的人,分享获取新知,大家一起进步!

吾等采石之人,应怀大教堂之心,愿你们奔赴在各自的热爱中…

文章目录

一、Redis序言

二、Redis

一、Redis序言

一年前就已经接触了Redis的相关知识,了解了这个强大的Redis缓存数据库,接下来会陆续抽时间整理Redis的相关具体应用在电影购票,等相关场景的实现和Redis键值的设计思路,希望自己努力成为一名合格的开发工程师!

Redis简介

Redis 是开源免费的,遵守BSD协议,是一个高性能的key-value非关系型数据库。

Redis特点:

3、Redis支持数据的备份,即master-slave模式的数据备份。

4、性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s 。

5、原子 – Redis的所有操作都是原子性的,同时Redis还支持对几个操作全并后的原子性执行。

6、丰富的特性 – Redis还支持 publish/subscribe, 通知, 设置key有效期等等特性。

二、Redis

先说一下自己项目遇到的真实场景,就是给一个社交圈平台帖子和评论的Redis键值设计!

当我给 当前帖子(post)后这个接口会有两个逻辑

第一:当前帖子总赞数+1 ,然后将新的总数存储在redis中;

第二:用Redis记录用户 给这个帖子

当我给 当前帖子某一条评论(review)后这个接口会有两个逻辑

第一:当前评论总赞数+1 ,然后将新的总数存储在redis中;

第二:用Redis记录用户 给这个该评论

用户给帖子这里的用户ID(userId)是从后台直接获取的,这里有一个逻辑就是:判断如果用户未登录是无法进行的;

服务器开启postman测试

正常postman测试 传入帖子ID(postId)和状态likeStatus

Redis点赞业务的设计与实现(Redis键值设计)

测试数据给id为65的帖子,传入1代表 0代表取消赞

测试数据 给帖子Id为66号的帖子 ,传入1代表 0代表取消赞

这里我们登陆Redis的桌面工具查看我们存储redis键值的情况!

来看看显示一下存储效果,POSTID是存储总数的,POST_USERID是记录用户的,绑定的是用户id和帖子id

如上显示的是记录了65,66号帖子的数,同时记录了34号用户了65和66号帖子;

如上我们要设计两个键值:一个存储总数目的键,一个记录具体用户的键

//单独记录帖子本身的键的设计 String key = "POSTID:" + postId; //记录用户具体帖子的键值设计 String userKey = "POST_USERID:" + postId + "-" + userId;

1

2

3

4

键值这里是可以灵活设计的,但是你要确保唯一且自己能看懂

相关代码:,要传入的是帖子id(postId) ,用户id (userId),用户状态likeStatus 0代表取消,1代表

简单逻辑就是先判断Redis中有无我们需要的键

1.如果有我们要的键,我们直接从键中取出对应的值 即(总数 +用户情况)

2.如果没有我们要的键,我们先从数据库中取总数的情况,如果数据库中取出总数为0,那么代表是第一次,我们给他设置为1,并存储在对应的Redis中

3.针对具体的情况,再看看用户是1还是取消赞0,再对应的+ -和增加删除

//,要传入的是帖子id,用户id,用户状态0代表取消,1代表 public void updateLike(Long postId, Long userId, Integer likeStatus) { //单独记录帖子本身的键的设计 String key = "POSTID:" + postId; //记录用户具体帖子的键值设计 String userKey = "POST_USERID:" + postId + "-" + userId; //如果redis中有这个键 if (redisTemplate.hasKey(key)) { //我们将相关的值取出来,这个值就是该帖子的总数 Object o = redisTemplate.opsForValue().get(key); if (o != null) { //取出总数值,转换成int类型进行总数加减 int likeNum = Integer.parseInt(o.toString()); //如果用户 if (likeStatus == 1) { try { //逻辑1:帖子总数+1,存储对应的键值,key为键,后总数加一存储 redisTemplate.opsForValue().set(key, likeNum + 1, 10L, TimeUnit.MINUTES); //逻辑2:记录对用户的情况,将用户和对应帖子绑定,在redis中存储对应的键 redisTemplate.opsForValue().set(userKey, 1, 1L, TimeUnit.DAYS); } catch (Exception e) { logger.error("redis error:{}", e); } // 写入数据库post_like,其实也可以在数据库中记录对应情况,这样是防止redis过期,具体业务具体分析; //postLikeService.save(postId, userId); } else { try { redisTemplate.opsForValue().set(key, likeNum - 1, 10L, TimeUnit.MINUTES); redisTemplate.delete(userKey); } catch (Exception e) { logger.error("redis error:{}", e); } postLikeService.delete(postId, userId); //总赞数 postMapper.updatePostCountLike(postId, (long) (likeNum - 1)); } } } else { /** 这里是判断Redis中没有相关键值记录,即Redis中没有记录具体的帖子总数和某一个用户的情况。 这里一般是两个情况 1.该帖子从来没有被过 这是第一次,第一次的时候就会设置键值 2.Redis中相关键值对过期 **/ // 首先我们查询数据库,拿取数据库的该帖子的总数,这两步具体看业务需求 Post post = postMapper.selectByPrimaryKey(postId); int likeCount = post.getLikeCount(); //当用户的时候 if (likeStatus == 1) { try { //逻辑一:首先帖子总数的存储在Redis中 redisTemplate.opsForValue().set(key, likeCount + 1, 10L, TimeUnit.MINUTES); //逻辑二:在Redis中记录某一个具体用户的情况 redisTemplate.opsForValue().set(userKey, 1, 1L, TimeUnit.DAYS); //这个likecount是数据库取出来的,如果总数为0,代表没有人过,帖子总数设置1 if (likeCount == 0) { post.setLikeCount(1); //同时同步更新到数据库数据表中 这一步更加你自己的业务需求走 简单的demo不需要 postMapper.updateByPrimaryKey(post); } } catch (Exception e) { logger.error("redis error:{}", e); } // 写入数据库post_like 按需求看自己是否要同步到数据库 //postLikeService.save(postId, userId); } else { //如果取出来的总数为0,总数无法 -1 ,出现这样的情况是我postman测试直接传入likestatus为0的情况,真实页面如果没有是无法传入0进来的; if (likeCount == 0) { logger.error("总数为0,无法取消"); } else { try { // redisTemplate.opsForValue().set(key, likeCount - 1, 10L, TimeUnit.MINUTES); redisTemplate.delete(userKey); } catch (Exception e) { logger.error("redis error:{}", e); } } } } }

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

如上的每一行我都写了注释,具体你应用到你的Redis中要根据项目具体的业务逻辑来,代码可以适当删减;

核心逻辑不变:设计一个存储总数目的键,设计一个记录具体用户的键,键值保持唯一且和具体的帖子对应

//单独记录帖子本身的键的设计 String key = "POSTID:" + postId; //记录用户具体帖子的键值设计 String userKey = "POST_USERID:" + postId + "-" + userId;

1

2

3

4

所以我们一般采用帖子ID (postId)来拼接一个字符串保持此键的唯一

如上是存储,你如果要显示给前端页面就用如下方式再取出来即可,Redis中也可以去除总数;

String userKey = "POST_USERID:" + postId + "-" + userId; boolean likeStatus = redisTemplate.hasKey(userKey); //从redis中判断用户是否喜欢帖子 postVo.setLikeStatus(likeStatus);

1

2

3

4

想必你一定有了更深入的了解,我们下期Redis文章见……

The best investment is to invest in yourself.

2020.10.18 愿你们奔赴在自己的热爱里!

Redis 数据库

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:两所大学中的智能车竞赛校内赛
下一篇:Python 爬虫实战五之模拟登录淘宝并获取所有订单
相关文章