0

我正在建立一个评论系统,一个评论可以有很多回复。

如果我要在 mysql 中实现这个,我会建立一个comments表,并有列:

  • comment_id,
  • parent_comment_id.

其中父评论 id 为 0 表示评论,是父评论 id 表示回复。因此,如果我正在寻找对某个评论的回复,我会寻找必须parent_comment_id与我正在寻找的评论相匹配的评论。

这对我来说似乎是多余的,因为它需要我遍历整个comments表才能找到评论是否有回复(特别是对于大数据),如果我有一个密钥库数据库,我将有一个密钥评论 id,其中包含按日期排序的回复列表。

那么你认为哪种方法更适合这个问题呢?

另外,我想将问题概括为任何一对多关系,以将其作为列表存储在密钥库数据库中。如果您推荐使用密钥库数据库,您会推荐哪一个来处理大数据?(我不想为此使用 redis,因为它是在内存中的,我怀疑对评论的回复需要经常访问)。

感谢您的回复。

4

4 回答 4

3

关系数据库应该可以很好地处理这个“邻接列表”模型。

首先,不要parent_comment_id在“root”注释中使用0,使用NULL。然后,您可以构建一个 FOREIGN KEY,parent_comment_idcomment_id防止您错误地将回复附加到不存在的评论。

它需要我浏览整个评论表才能找到评论是否有回复

假设您已索引parent_comment_id(如果您在上面创建了 FK,InnoDB 会自动执行此操作),查找对给定评论的第一级回复将需要索引范围扫描。要了解索引范围扫描及其高效的原因,您首先需要了解SQL 索引的剖析

找到第二级需要另一个范围扫描等。不幸的是,MySQL 不支持递归查询,它允许您在单个数据库往返中完成所有这些,但它应该仍然相当有效。

如果您已经进行了测量并得出结论这是一个问题,那么还有其他表示层次结构的策略(具有不同的权衡),例如“嵌套集”和“闭包”。看看Bill Karwin 的这个演讲

于 2013-02-03T11:24:24.030 回答
2

您可以创建表格并使其更加灵活。

评论 => comment_id, the_comment, count_replays

comments_replay => parent_id, the_comment

当有评论重播时,count_replays 会有更新。

现在如果有重播,你可以做 if 语句,然后才请求它们。

于 2013-02-03T13:13:46.213 回答
2

赞成布兰科的回复。父字段上的索引很好。在这种情况下,NULLS 比零工作得更好。另外,参照完整性约束对您的帮助大于对您的伤害。

几个额外的点。

如果您使用方法而不是现有的邻接列表方法,您将能够搜索由回复和回复等组成的整个子树,而不仅仅是立即回复。这可能很有用。

其次,有一种称为“森林”的数据结构。这是一个包含一组树的表,其中每棵树都具有作为其根的,在本例中是一个没有父级的注释。网络搜索应该为您提供一些关于设计讨论森林的好文章,其中每个讨论都以评论开始,每个讨论都是回复树。很多人设计的正是这种情况。

于 2013-02-03T13:02:33.757 回答
2

事实上,大多数关系数据库不必通过所有评论来找出哪些是给定评论的回复。毕竟这些类型的查询非常频繁并且非常优化。还可以考虑在parent_comment_id. 同样,这仅在您拥有单一级别的亲子关系时才有效。如果您可能有评论轮流评论,那么另一种存储数据的方式可能会更好地为您服务。

于 2013-02-03T09:42:22.727 回答