写点什么

一张表实现短视频"评论区"完整功能

作者:北桥苏
  • 2023-07-17
    广东
  • 本文字数:2549 字

    阅读完需:约 8 分钟

前言


现如今,不管是哪种类型的应用,评论区都少不了。从工具类的到媒体信息流类的,评论留言都是最基本的互动环节。比如抖音短视频下,针对视频每个用户都可以发表自己的观点;而针对用户的评论,其他的用户又可以对其进行评论,依次回复下去。


那么,一个视频的评论回复的表如何设计?功能如何实现呢?如标题,这里是用一张表完成,但是在我完成功能后发现拆成两个张更合适(评论表和回复表),这个后面已经改了,最后也会说一下。



效果


页面上展示是,视频下分页展示第一级的评论列表,评论下的评论是进行折叠,点击“查看全部”分页显示所有层级的评论。一张表的设计下,评论下的评论下……的评论是通过关联上一级主键的,也就是递归的方式。


但是下面的是只要是对评论进行评论都放在第一级的评论下,而递归是树形结构。虽然也能通过对树形结构数据处理拉伸到二季下,但是在底下评论特别多的情况就会体验特别差。所以针对这个我对表格加了一个面包屑字段,表结构如下,然后再分次完成评论数据的如何添加,按页面方式查询的。


表结构

CREATE TABLE `short_video_comment` (  `id` int(11) NOT NULL AUTO_INCREMENT,  `pid` int(11) DEFAULT '0' COMMENT '父级ID',  `crumbs` json DEFAULT NULL COMMENT '面包屑',  `video_id` int(11) DEFAULT '0',  `user_id` int(11) DEFAULT '0',  `commented_user_id` int(11) DEFAULT '0' COMMENT '被评论者用户ID',  `is_pubisher` tinyint(1) DEFAULT '0' COMMENT '是否作者',  `content` varchar(255) DEFAULT '' COMMENT '评论',  `state` int(1) DEFAULT '1' COMMENT '1. 显示  0. 隐藏',  `like_count` int(11) DEFAULT '0' COMMENT '点赞数',  `create_time` int(11) DEFAULT '0' COMMENT '创建时间',  `delete_time` int(11) DEFAULT '0' COMMENT '删除时间',  `update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',  PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=282 DEFAULT CHARSET=utf8mb4 COMMENT='用户评论记录表';
复制代码


如上图的 “crumbs” 字段是一个数组方式的 json,也就是添加时会记录当前评论的关系链,从最顶层 ID 到最近的上一级。而实现分页显示第二级下的所有评论,只需要把 “crumbs” 索引为 1 的 pid 作为查询条件就能找到该 id 下的所有评论,如下是查询二级评论 ID 为 285 的所有评论列表。

select * from short_video_comment where json_extract(crumbs, "$[1]") = 285
复制代码


而对于关于 crumbs 如何存入和谁回复谁,就只需要在评论添加的时候,对上一级评论 ID 进行递归查询所有上级 ID 放入 "crumbs", 被回复者就更好办了,查询上一级评论的评论者 ID(user_id),放入当前评论记录的 "commented_user_id",展示的时候只需要关联一下用户信息表就可以了,接下来就是业务代码演示了。


代码演示

▲评论添加

public static function commentAdd($videoInfo, $userId, $content, $commentInfo = []){    $commentId = 0;    $videoId = $videoInfo['id'] ?? 0;    $publisherId = $videoInfo['user_id'] ?? 0;
try { $crumbs = [0]; if ($commentInfo) { $pid = $commentInfo['id'] ?? 0; $insert['commented_user_id'] = $commentInfo['user_id'] ?? 0; $insert['pid'] = $pid; $crumbs = ShortVideoComment::getCrumbs($pid); }
$insert['video_id'] = $videoId; $insert['user_id'] = $userId; $insert['is_pubisher'] = $userId == $publisherId ? 1 : 0; $insert['content'] = $content; $insert['state'] = ShortVideoComment::STATE['SHOW']; $insert['create_time'] = time(); $insert['crumbs'] = json_encode($crumbs);
$commentId = ShortVideoComment::insertGetId($insert);
if ($commentId && $videoId) { $map[] = ['id', '=', $videoId]; ShortVideoModel::where($map)->setInc('comment_count');
$userId && self::setRating(6, $userId, $videoId); } } catch (\Exception $e) { $preFileName = str::snake(__FUNCTION__); $path = self::getClassName(); write_log("msg:" . $e->getMessage(), $preFileName . "_error", $path); }
return $commentId;}
复制代码

▲获取面包屑

public static function getCrumbs($cateId = 0, &$ids = []){    $idArr = array_merge((array)$cateId, $ids);    $info = self::where('id', $cateId)->find();    if ($info['pid'] != 0) {        $idArr = self::getCrumbs($info['pid'], $idArr);    } else {        array_unshift($idArr, 0);    }
return $idArr;}
复制代码

▲数据查询

public static function getList($map, $page = 1, $size = 30, $pid = 0){    $where[] = ['delete_time', '=', 0];    $where[] = ['state', '=', self::STATE['SHOW']];    $map = array_merge($where, $map);
$field = ['id,crumbs,pid,video_id,user_id,commented_user_id,content']; $queryObj = self::field($field) ->with([ 'user' => function ($query) { $query->withField('id, nickname, avatar, mobile'); }, 'commented_user' => function ($query) { $query->withField('id, nickname, avatar, mobile'); } ]) ->where($map);
$pid && $queryObj->whereRaw("JSON_EXTRACT(`crumbs` ,'$[1]') = $pid");
$list = $queryObj->page($page, $size) ->order('like_count desc') ->select();
return $list;}
复制代码

写在最后


        以上是初版时候根据业务设计的表格,后来的评论区完全仿照某音,所以也就对表格进行了拆分。分成了评论表和回复表,只要是对评论进行评论就是回复,这样在后面数据庞大的时候,性能会更好一点。但是如何是前期设计的就是一张表,而迭代的时候也要有某音评论的效果,可以作为解决方法尝试滴。


发布于: 刚刚阅读数: 4
用户头像

北桥苏

关注

公众号:ZERO开发 2023-05-08 加入

专注后端实战技术分享,不限于PHP,Python,JavaScript, Java等语言,致力于给猿友们提供有价值,有干货的内容。

评论

发布
暂无评论
一张表实现短视频"评论区"完整功能_北桥苏_InfoQ写作社区