这个评论系统设计碉堡了

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
简介: 先赞后看,南哥助你Java进阶一大半官网给出了Facebook评论系统的高级设计图,Facebook的评论竟然是支持实时刷新的。也就是说用户不用刷新帖子,只要帖子有新的评论就会自动推送到用户端,这里Facebook使用的便是每天在全球有设备在使用的WebSocket技术。我是南哥,一个Java学习与进阶的领路人。相信对你通关面试、拿下Offer进入心心念念的公司有所帮助。

先赞后看,南哥助你Java进阶一大半

geeksforgeeks.org官网给出了Facebook评论系统的高级设计图,Facebook的评论竟然是支持实时刷新的。也就是说用户不用刷新帖子,只要帖子有新的评论就会自动推送到用户端,这里Facebook使用的便是每天在全球有超过20亿设备在使用的WebSocket技术。

在这里插入图片描述

我是南哥,一个Java学习与进阶的领路人。

相信对你通关面试、拿下Offer进入心心念念的公司有所帮助。

⭐⭐⭐本文收录在《Java学习/进阶/面试指南》:https://github/JavaSouth

1. 评论系统设计

1.1 评论表如何设计

评论系统的表要这么设计,每条评论的id标识要么是根评论id、要么是回复评论id。如果是根评论,那parent_comment_id字段就为空;而回复别人的评论,parent_comment_id字段指向根评论id。

CREATE TABLE `comments` (
  `comment_id` INT AUTO_INCREMENT PRIMARY KEY,  -- 评论唯一ID
  `user_id` INT NOT NULL,                       -- 用户ID
  `content` TEXT NOT NULL,                      -- 评论内容
  `parent_comment_id` INT DEFAULT NULL,         -- 如果是回复,则指向原始评论ID
  `post_id` INT NOT NULL,                       -- 被评论的帖子或内容ID
  `like_count` INT DEFAULT 0,                   -- 点赞数量
  `create_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,  -- 评论创建时间
);

我们还要给评论加上点赞数,南哥给大家看看抖音的评论设计。

用户可以给每条评论打上点赞,所以我们应该再设计一个点赞表。其实抖音这种评论模式叫嵌套式评论结构,嵌套式评论注重用户对话交流,用户可以很方便地查看一个对话里的所有回复,我们看下抖音评论里有着展开10条回复的按钮。

在这里插入图片描述

其他评论模式设计还有平铺式评论结构,像微信朋友圈,或者Github的issue都是平铺式评论结构。这种设计更适合用户关注重点在发布的内容本身,而不是对话。大家有没发现微信朋友圈的特点是对话比较少点,点赞反而更多。

来看看点赞表设计。

CREATE TABLE `comment_likes` (
  `user_id` INT NOT NULL,                       -- 点赞用户ID
  `comment_id` INT NOT NULL,                    -- 被点赞的评论ID
  `liked_timeMESTAMP DEFAULT CURRENT_TIMESTAMP,  -- 点赞时间
);

1.2 评论数据存储

抖音每天产生视频几百万、上千万,每个视频的评论高的甚至有上万条评论,要怎么样的数据查询设计才能支持每天亿级的评论?

南哥先假设我们用MySQL作为实际的数据存储,这么高的并发肯定不能让查询直接冲击数据库 。再分库分表也是没用。

在这里插入图片描述

Elasticsearch官网这么宣传它的产品:

Elasticsearch 极其快速,快到不可思议

当用户发表评论时,我们首先把评论写入MySQL数据库,再使用异步机制把评论同步到Elasticsearch中。当在用户请求查询评论时,优先从 Elasticsearch 中进行查询。

// 评论存储到MySQL、Elasticsearch
public void storeComment(Comment comment) {
   
    // 将评论存入 MySQL
    commentRepository.save(comment);

    // 异步将评论同步到 Elasticsearch
    CompletableFuture.runAsync(() -> {
   
        elasticsearchService.indexComment(comment);
    });
}

1.3 事务控制

大家想一想以上设计,有哪些需要进行事务控制?

例如comment_likes点赞表的插入和comment评论表的更新,用户为某一个评论点赞,会在comment_likes表插入一条新记录,同时会更新comment表的点赞数量。

但是,从用户需求的角度来看,用户并不在意点赞数的强一致性和实时性,这点不使用事务也可以接受。

我曾经和老外程序员在论坛聊过,他说他们的点赞后端分布式服务用的本地缓存,即使每一个服务的本地缓存相对不太一致,对系统完全没有影响。

// 事务控制
@Transactional
public void likeComment(int commentId, int userId) {
   
    // 插入一条点赞记录
    commentLikesRepository.insert(userId, commentId);

    // 更新评论表中的点赞数量,假设有一个专门的方法来处理这个更新
    commentRepository.incrementLikeCount(commentId);
}

1.4 点赞数加入Redis

点赞数相比评论来说,量更加巨大,用户点赞时直接落到MySQL数据库肯定不合理,服务器扛不住也没必要扛。

假如点赞数没有进行事务控制。南哥打算这样处理,用户点赞后,后端服务接受到点赞请求,把用户内容、点赞数放到Redis里,这里采用Redis五大基本类型之一:Map。

// Map结构
comment_like_key = [comment_id_6:like_count = 66, comment_id_7:like_count = 77]

我们需要查询点赞数时直接从高性能内存数据库Redis查询。

当然这还没完,MySQL数据库和Elasticsearch的点赞量需要去同步更新,我们设置定时任务每个一段时间完成数据同步任务。上文的comment_likes点赞记录表同样需要记录,把点赞放到Redis时进行异步添加点赞记录即可。

// 定时任务数据同步任务
@Scheduled(fixedRate = 10000)
public void syncLikes() {
   
    // 从 Redis 中读取最新的点赞数据
    Map<Integer, Integer> likes = redisService.fetchAllLikes();

    // 同步到 MySQL 和 Elasticsearch
    likes.forEach((commentId, likeCount) -> {
   
        commentRepository.updateLikeCount(commentId, likeCount);
        elasticsearchService.updateLikeCount(commentId, likeCount);
    });
}

戳这,《JavaSouth》作为一份涵盖Java程序员所需掌握核心知识、面试重点的神秘文档。

我是南哥,南就南在Get到你的点赞点赞。

在这里插入图片描述

创作不易,不妨点赞、收藏、关注支持一下,各位的支持就是我创作的最大动力❤️

相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
相关文章
|
6月前
|
SQL 数据库 数据安全/隐私保护
在线商城系统设计
在线商城系统设计
|
6月前
|
监控 安全 网络安全
宝鸡陇县中学弱电系统集成设计方案_kaic
宝鸡陇县中学弱电系统集成设计方案_kaic
|
6月前
|
存储 安全 前端开发
ONLY在线商城系统设计与实现
ONLY在线商城系统设计与实现
|
6月前
|
传感器 测试技术 数据处理
单片机开发|基于单片机的婴儿睡眠监测系统设计
单片机开发|基于单片机的婴儿睡眠监测系统设计
【单片机课程设计】汽车盲区检测系统
【单片机课程设计】汽车盲区检测系统
158 0
|
传感器 存储 网络协议
基于51单片机的智能营养秤系统设计与实现
当前系统采用了STC89C52单片机作为主控芯片,预置了多种食材的营养成分数据。用户只需要使用矩阵键盘输入食材编号,将需要称重的食材放置在重力传感器上进行依次称重,系统就可以自动计算出所有食材的各类营养含量总值,并通过液晶屏显示出来。同时,系统根据预设的营养指标,对不达标或超标的食材进行对应的声光提示,提醒用户注意饮食健康。
91 0
|
Scala UED Kotlin
准死证网上便民系统设计
人有生必有死,有准生证必然就有准死证,随着老龄化程度加剧,死亡管制势在必行,一起来通过准死证系统了解scala的新特性吧
124 0
|
安全 数据安全/隐私保护
【微机原理资料分享】基于8086家具门安全控制系统设计(仿真、程序、报告)
安全人员使用主密码更新当天的密码。按M按钮激活此模式。系统闪烁输入密码LED,要求人员输入密码。主密码是16位数的值。只给管理员一次输入密码的机会。如果经过验证,重试/更新LED发光。如果身份验证失败,则发出警报。当重试/更新LED发光时,用户必须输入当天的密码。这是12位数的值。一旦这个值已被系统接受,密码更新的LED发光。 ●用户进入房间时必须按O键,输入密码LED提示用户输入密码。用户也可以使用C/AC选项。如果第一次尝试失败,RETRY LED发光。允许用户重新输入密码,在身份验证门打开一段时间后1分钟。失败时发出警报。 ●要关闭警报,必须按下A按钮。输入密码LED发光提示用户输入
137 0
【微机原理资料分享】基于8086家具门安全控制系统设计(仿真、程序、报告)
|
芯片
电赛校赛-三相逆变电源设计(模拟部分)
电赛校赛-三相逆变电源设计(模拟部分)
321 0
电赛校赛-三相逆变电源设计(模拟部分)
|
传感器 机器人 定位技术
机器人系统设计
国际标准化组织(ISO) 机器人定义: 1、机器人的动作机构具有类似于人或其它生物体的某些器官(肢体、感受等)的功能 2、机器人具有通用性,工作种类多样,动作程序灵活易变; 3、机器人具有不同程度的智能性,如记忆、感知、推理、决策、学习等; 4、机器人具有独立性,完整的机器人系统在工作中可以不依赖于人的干预。
机器人系统设计