广告
返回顶部
首页 > 资讯 > 数据库 >利用Redis实现点赞功能的示例代码
  • 942
分享到

利用Redis实现点赞功能的示例代码

Redis 点赞功能Redis 点赞 2022-06-28 17:06:19 942人浏览 独家记忆
摘要

目录Mysql 和 Redis优缺点1、Redis 缓存设计及实现部分代码如下Redis 存储结构如图2、数据库设计3、开启定时任务持久化存储到数据库部分代码如下提到点赞,大家一想到的是不是就是朋友圈的点赞呀?其实点赞对

提到点赞,大家一想到的是不是就是朋友圈的点赞呀?其实点赞对我们来说并不陌生,我们经常会在手机软件或者网页中看到它,今天就让我们来了解一下它的实现吧。我们常见的设计思路大概分为两种:一种自然是用 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

部分代码如下


@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());
}


@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);
}


@Override
public 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;
}


@Override
public 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 存储结构如图

利用Redis实现点赞功能的示例代码

利用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);
        }
    });
}

至此我们就实现了基于 Redis 的点赞功能,我们还需要注意一点:查询用户点赞情况时,需要同时查询数据库+缓存中的数据。

以上就是利用Redis实现点赞功能的示例代码的详细内容,更多关于Redis点赞功能的资料请关注我们其它相关文章!

您可能感兴趣的文档:

--结束END--

本文标题: 利用Redis实现点赞功能的示例代码

本文链接: https://www.lsjlt.com/news/33098.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 利用Redis实现点赞功能的示例代码
    目录mysql 和 Redis优缺点1、Redis 缓存设计及实现部分代码如下Redis 存储结构如图2、数据库设计3、开启定时任务持久化存储到数据库部分代码如下提到点赞,大家一想到的是不是就是朋友圈的点赞呀?其实点赞对...
    99+
    2022-06-28
    Redis 点赞功能 Redis 点赞
  • 使用 Redis 缓存实现点赞和取消点赞的示例代码
    点赞功能是很多平台都会提供的一个功能,那么,我们要如何实现点赞和取消点赞呢? 这篇文章总结了我在项目中实现点赞的方法。 缓存 vs 数据库? 首先我们要考虑的是数据要放到哪里,很多...
    99+
    2022-11-11
  • 怎么利用Redis实现点赞功能
    这篇文章主要介绍“怎么利用Redis实现点赞功能”,在日常操作中,相信很多人在怎么利用Redis实现点赞功能问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么利用Redis实现点赞功能”的疑惑有所帮助!接下来...
    99+
    2023-07-02
  • 使用Redis实现点赞取消点赞的详细代码
    前言 异步实现 代码实现: private void like(long userId,int type,int textId,long entityUserId){ ...
    99+
    2022-11-13
  • AndroidFlutter实现点赞效果的示例代码
    目录前言绘制小手完整源码前言 点赞这个动作不得不说在社交、短视频等App中实在是太常见了,当用户手指按下去的那一刻,给用户一个好的反馈效果也是非常重要的,这样用户点起赞来才会有一种强...
    99+
    2022-11-13
  • Ajax实现phpcms点赞功能的示例方法
    这篇文章给大家分享的是有关Ajax实现phpcms点赞功能的示例方法的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。首先 是将后台中 模块--->新闻心情--->心情配置  去掉多余的剩一个,...
    99+
    2023-06-08
  • Redis实现排名功能的示例代码
    目录前言一.实现思路二.具体实现小结前言 之前在消费金融平台的时候,公司有一个专门给线下销售人员使用的APP,APP记录销售推广公司贷款产品赚取的佣金以及一些门店开拓和打卡的功能,后...
    99+
    2022-11-13
  • Redis笔记点赞排行榜的实现示例
    目录一、发布探店笔记二、实现查看笔记接口三、点赞功能四、点赞排行榜 1、修改点赞逻辑2、点赞排行榜功能一、发布探店笔记 探店笔记类似点评网站的评价,往往是图文结合。对应的表有两个 探店笔记表(主键、商户id、用...
    99+
    2023-01-29
    Redis笔记点赞 Redis点赞排行榜
  • Spring Cloud中怎么使用Redis实现点赞和取消点赞功能
    Spring Cloud中怎么使用Redis实现点赞和取消点赞功能,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。一、Redis 缓存设计及实现...
    99+
    2022-10-18
  • Java实现断点下载功能的示例代码
    目录介绍效果前端代码后端代码介绍 当下载一个很大的文件时,如果下载到一半暂停,如果继续下载呢?断点下载就是解决这个问题的。 具体原理: 利用indexedDb,将下载的数据存储到用户...
    99+
    2022-11-13
  • Java实现断点续传功能的示例代码
    目录一、题目描述二、解题思路三、代码详解一、题目描述 题目实现:网络资源的断点续传功能。 二、解题思路 获取要下载的资源网址 显示网络资源的大小 上次读取到的字节位置以及未读取的字节...
    99+
    2022-11-13
    Java实现断点续传 Java断点续传
  • 利用Java实现一个短视频点赞功能
    这篇文章将为大家详细讲解有关利用Java实现一个短视频点赞功能,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。 这行代码是弹出点赞的时间为18s.18秒后发生了什么呢 ?继续看&nb...
    99+
    2023-05-31
    java ava 点赞
  • Redis实现订单自动过期功能的示例代码
    前言 用户下单后,规定XX分钟后自动设置为“已过期”,不能再发起支付。项目类似此类"过期"的需求,笔者提供一种使用Redis的解决思路,结合Redis的订阅、发布和键空间通知机制(...
    99+
    2022-11-12
  • Java利用Redis实现消息队列的示例代码
    本文介绍了Java利用Redis实现消息队列的示例代码,分享给大家,具体如下:应用场景为什么要用redis?二进制存储、java序列化传输、IO连接数高、连接频繁一、序列化这里编写了一个java序列化的工具,主要是将对象转化为byt...
    99+
    2023-05-31
    java redis 消息队列
  • 基于redis实现的点赞功能设计思路详解
    前言 点赞其实是一个很有意思的功能。基本的设计思路有大致两种, 一种自然是用mysql等 数据库直接落地存储, 另外一种就是利用点赞的业务特征来扔到redis(或memcache)中, 然后离线刷回mysq...
    99+
    2022-06-04
    详解 思路 功能设计
  • 用Python登录好友QQ空间点赞的示例代码
    记得之前跟我女票说过,说要帮她空间点赞,点到999就不点了。刚开始还能天天记得,但是后来事情一多,就难免会忘记,前两天点赞的时候忽然觉得这样好枯燥啊,正好也在学Python,就在想能不能有什么方法能自动点赞...
    99+
    2022-06-04
    示例 好友 代码
  • C++实现Go的defer功能(示例代码)
    在Go语言中有一个关键字:defer,它的作用就是延迟执行后面的函数,在资源释放方面特别有用,比如下面一段C/C++的示例代码: void test() { FILE* fp ...
    99+
    2022-11-12
  • Python实现录屏功能的示例代码
    目录一、界面开发二、录屏参数设置1.设置录屏范围2.鼠标事件监听3.键盘事件监听三、录屏操作一、界面开发 #设置主界面 def set_init_window(self): ...
    99+
    2023-03-24
    Python实现录屏功能 Python录屏功能 Python录屏
  • Vue后台实现点击图片放大功能的示例代码
    目录需求代码父组件子组件dom.jsutil.jstypes.js需求 点击小图可以放大,放大后,通过手势等比例放大缩小、左右切换图、旋转、关闭。由于element-ui版本较低不支...
    99+
    2022-12-08
    Vue点击图片放大功能 Vue点击图片放大 Vue 图片放大
  • Vue实现输入框@功能的示例代码
    目录前言成员列表创建使用输入框获取光标的坐标保存光标插入文本运行结果总结前言 前几篇文章中分别介绍了如何实现聊天输入框的双向绑定、回车键发送、粘贴文本图片等功能,本着完善输入框的目的...
    99+
    2022-11-13
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作