抖音评论系统的实现思路

                抖音大家都刷过。点开抖音的一个视频的评论,他会有一个根评论,根评论下面会有子评论,子评论中还有有对子评论的评论。具体如下图:

                                

        通过上面的图片可以直观的看见,这三种类型的评论。然后评论是根据时间的倒叙排列的。肯定还有会分页查询。用户点开评论,首先看到的是根评论。点开根评论,可以看见当前根评论对应的子评论。 大概的功能就是这些。

        一,需要实现的大致的功能点:

                1.根评论,及根评论下子评论的嵌套。

                2.评论用户基本信息的获取(用户图像,用户昵称)

                3.对子评论的评论的展现。(a用户回复b用户的子评论)

                4.用户的点赞,及点踩

                5.评论的展示顺序(根据时间顺序,还是评论的热度)

        二,数据库库表结构的设计:

        两张表,一张根评论表,一张子评论表。

建表语句如下:

CREATE TABLE sys_sub_comments (
    id INT AUTO_INCREMENT PRIMARY KEY COMMENT '评论的唯一标识符',  -- 主键 id,唯一标识每个评论
    userId INT NOT NULL COMMENT '评论者的用户 ID',               -- 评论者的用户 ID
    workId INT NOT NULL COMMENT '作品 ID(如视频或文章等)',      -- 作品 ID,指评论对应的作品
    content TEXT NOT NULL COMMENT '评论内容',                     -- 评论的内容
    targetUserId INT COMMENT '评论的目标用户 ID(如针对特定用户的评论)',  -- 评论的目标用户 ID
    parentCommentId INT DEFAULT NULL COMMENT '父评论 ID,用于层级关系,NULL 代表根评论',  -- 父评论 ID,用于表示评论的层级,NULL 代表没有父评论
    createdAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '评论的创建时间',  -- 评论的创建时间
    updatedAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '评论的更新时间'  -- 评论的最后更新时间
) COMMENT = '评论表,存储用户对作品的评论信息,支持层级评论';


CREATE TABLE sys_comments (
    id INT AUTO_INCREMENT PRIMARY KEY COMMENT '评论的唯一标识符',  -- 主键 id,唯一标识每个评论
    userId INT NOT NULL COMMENT '评论者的用户 ID',               -- 评论者的用户 ID
    workId INT NOT NULL COMMENT '作品 ID(如视频或文章等)',      -- 作品 ID,指评论对应的作品
    content TEXT NOT NULL COMMENT '评论内容',                     -- 评论的内容
    createdAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '评论的创建时间',  -- 评论的创建时间
    updatedAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '评论的更新时间'  -- 评论的最后更新时间
) COMMENT = '评论表,存储用户对作品的评论信息,支持层级评论';
        三,评论查询主要逻辑 

                1.根评论 查询逻辑

                        返回的vo对象结构:                               

	/**
	 * 根评论vo
	 *
	 */ 
 
/**
 * 商品根评论实体
 */
@Data
@NoArgsConstructor
public class CommentVO {
 
	Integer id;
 
	Integer goodsId;
 
	/**
	 * 评论用户信息
	 */
	UserSimpleVO userInfo;
  
	String content;
  
	String type;
 
	Timestamp createdAt;

}

        主要代码逻辑:

                首先根据作品id,分页查出当前页的评论:

SELECT * FROM sys_comments WHERE workId = 'root' ORDER BY create_time DESC LIMIT 20 OFFSET 1;

                根据userId获取当前页,所有评论用户的信息:

SELECT * FROM sys_user WHERE userId in (idList);

                主要代码如下:

//根据作品id,分页查询作品评论       
List<Comment> comments = commentService.selectByGoodsId(googsId,pageNumber,pageCount);
       if (ObjectUtils.isEmpty(comments)){
           return new ArrayList<>();
       }
        // 统计用户id,并进行去重
        List<Long> userIds = comments.stream().map(Commetn::getUserId)
                .distinct()
                .collect(Collectors.toList());
       //key是用户id,值是用户信息
       Map<Long, UserInfo> userInfos = userService.selectByIds(userIds);
        List<CommentVo> commentVos = new ArrayList<CommentVo>();
        //进行对应评论用户信息的填充
        for (Comment comment : comments) {
            CommentVo commentVo = new CommentVo();
            //进行原有属性的拷贝
            BeanUtils.copyProperties(comment,commentVo);
            //设置用户相关信息
            UserInfo userInfo = userInfos.get(comment.getUserId);
            commentVo.setUserInfo(userInfo);
            commentVos.add(commentVo);
        }
        return commentVos;

                2.子评论查询的主要逻辑

                        返回的vo对象结构: 相较于根评论,多了一个被评论者用户信息

/**
	 * 子评论vo
	 *
	 */ 
 
/**
 * 商品子评论实体
 */
@Data
@NoArgsConstructor
public class SubCommentVO extents CommentVO  {

    //被评论者用户信息
    private UserInfo targetUserInfo;
}

                主要代码逻辑:

                        根据父评论id筛选出,对应的子评论。 

SELECT * FROM sys_sub_comments WHERE parentCommentId= 'commentId' ORDER BY create_time DESC LIMIT 20 OFFSET 1;

                        根据用户id,获取对应的用户信息

SELECT * FROM sys_user WHERE userId in (idList);

                        代码逻辑:

//根据作品id,分页查询作品评论       
List<SubComment> subComments= SubCommentService.selectByParentCommetnId(parentCommetnId,pageNumber,pageCount);
       if (ObjectUtils.isEmpty(comments)){
           return new ArrayList<>();
       }
        // 统计用户id(包括评论用户id和被评论用户id)
        List<Long> userIds = SubComments.stream()
                ..flatMap(subComment -> Arrays.stream(new long[]{subComment.getUserId1(), subComment.getTargetUserId()}))
                .distinct()
                .collect(Collectors.toList());
       //key是用户id,值是用户信息
       Map<Long, UserInfo> userInfos = userService.selectByIds(userIds);
        List<CommentVo> subCommentVos = new ArrayList<CommentVo>();
        //进行对应评论用户信息的填充
        for (SubComment subComment : subComments) {
            SubCommentVo  = new SubCommentVo();
            //进行原有属性的拷贝
            BeanUtils.copyProperties(subComment ,subCommentVo);
            //设置用户相关信息
            UserInfo userInfo = userInfos.get(subComment.getUserId());
            subCommentVo.setUserInfo(userInfo);
            //设置目标评论者的用户信息
            UserInfo targetUserInfo = userInfos.get(subComment.getTargetUserInfo());
            subCommentVo.setTargetUserInfo(targetUserInfo);
            subCommentVos.add(subComment );
        }
        return subCommentVos;

                对于插入操作来说,都是常规操作,这里不做过多的说明。

        四,关于评论系统数据库的选择               

MySQL 和 MongoDB 都是流行的数据库系统,但它们在架构、使用场景和性能方面有显著的区别。

MySQL

优点

  • 关系型数据库:结构化数据,支持强大的 SQL 查询功能,适用于复杂的事务处理。
  • ACID 支持:确保数据的一致性、隔离性、持久性,适合需要严格事务管理的应用。
  • 成熟稳定:经过多年优化,社区支持广泛,文档和工具丰富。

缺点

  • 扩展性差:水平扩展复杂,处理大量并发和大规模数据时会遇到性能瓶颈。
  • 灵活性差:表结构必须事先定义,数据模式变化较为繁琐。

适用场景

  • 需要严格事务一致性和复杂查询的应用,如金融、电子商务、企业管理系统等。
MongoDB

优点

  • 文档型数据库:数据以 JSON 风格的 BSON 文档存储,灵活的模式设计,适合快速变化的应用。
  • 水平扩展:内建分片功能,支持横向扩展,适合大数据量和高并发场景。
  • 高性能:针对大量读写操作进行了优化,适合大规模应用。

缺点

  • 缺乏 ACID 支持:虽然 MongoDB 3.x 以后支持事务,但相比 MySQL,事务支持较弱。
  • 查询语言较弱:对于复杂查询,性能和表达能力不如 SQL,限制了某些类型的数据操作。

适用场景

  • 快速迭代的项目、实时数据分析、大数据处理、内容管理系统、物联网等。
总结:
  • MySQL:适合结构化数据,事务要求高的应用,如银行、电商系统等。
  • MongoDB:适合数据模式不固定,需求快速迭代和大数据量处理的应用,如日志记录、社交平台、大数据分析等。

        数据库的选择,根据平台的用户量,以及平台未来的增长量进行进行选择。

点点关注,点点赞呀,持续更新有用的知识............

                         

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值