一般论坛帖子都有回复回复的内容,这个该怎么设计比较好?

场景是用户a回复了帖子A, 用户b恢复了a的回复,这个怎么设计数据表比较合理

《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
讨论数量: 10
liyu001989

一般都是增加@某个用户的功能

要分层显示就增加个 parent_id 啥的字段记录一下回复的谁

5年前 评论

@liyu001989 如果我想知道某篇文章下的所有评论,这样岂不是很忧伤。如果在增加一个文章id,那我要查评论的关系呢,感觉这样并没有从根本性上解决。

5年前 评论
liyu001989

@davionnini 每个回复记录了 topic_id,parent_id,通过 topic_id 获取的就是某个帖子的所有评论。

“如果在增加一个文章id,那我要查评论的关系呢,感觉这样并没有从根本性上解决。” 是啥意思?没有解决什么根本问题?

5年前 评论

我想知道这一篇文章的的所有回复,和各个回复之间的关系,他们关系是有先后顺序的。
一篇文章的所有回复可以一次一次查询,就像双向链表那样,这样是否查询次数过多呢

5年前 评论
liyu001989

@davionnini replies : id,topic_id, parent_id, level 。这样的数据结构满足你的查询要求,先后顺序靠时间以及id去排序。文章的所有回复 通过 topic_id 就是一次查询出来。

看你怎么设计了,还觉得不够,考虑一下 kalnoy/nestedset013. 嵌套集合模型(无限极分类)——kalnoy/nestedset(代替 baum/baum)

5年前 评论
ruke

这样吗?
file

5年前 评论

最近做了这块内容,你可以参考一下,我把主要的代码贴出来,精简了一部分没必要的代码

表结构的设计

Schema::create('replies', function (Blueprint $table) {
            $table->increments('id');
            $table->text('content');
            $table->unsignedInteger('parent_id')->nullable()->default(0);
            $table->timestamps();
});

模型关系的定义

public function parent() {
        return $this->belongsTo(Reply::class, 'parent_id');
}

public function children()
{
        return $this->hasMany(Reply::class, 'parent_id');
}

取数据

取数据的时候你可以考虑逐条取出来,也可以先把 'parent_id' 为 0 的取出来,因为 'parent_id' 为 0 的代表的是用户对于本片文章的评论,其余的都是对于评论的评论,或者评论的评论的评论.
我在做项目的时候,选择的是先取'parent_id' 为 0 的评论,给用户一个按钮,如果用户想看这条评论的评论,再通过异步请求给服务器发请求,获取子评论,以此类推.

控制器代码

public function replies(Article $article, Request $request)
    {
        $replies = Reply::where('article_id', $article->id)
            ->withParentReply($request->parent_id)
            ->paginate(10);
        return ReplyResource::collection($replies);
    }

reply 模型中的本地作用域

public function scopeWithParentReply($query, $parent_id)
    {
      //如果参数中有 parent_id 就过滤出该 parent_id 下的子回复,如果没有就返回 parent_id 为0 的,也就是顶级回复
       return $parent_id ? $query->where('parent_id', $parent_id) : $query->where('parent_id', 0);
    }

ReplyResponse 中的代码

public function toArray($request)
    {
        return [
            'id' => $this->id,
            'content' => $this->content,
            'parent_id' => $this->parent_id,
        ];
    }

另一种方式取数据

可以递归的将子子孙孙的一次性取出,ReplyResponse 中的代码如下

public function toArray($request)
    {
       return [
            'id' => $this->id,
            'content' => $this->content,
            'parent_id' => $this->parent_id,
            //这里递归调用ReplyResource::collection()
            'replies' => ReplyResource::collection($this->children),

        ];
    }
5年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!