我正在建立一个评论系统,评论可以有很多回复。
如果我要在mysql中实现它,我会构建一个comments
表,并有列:
comment_id
,parent_comment_id
。 评论的父评论ID为0,并且是回复的父评论ID。因此,如果我正在寻找某个评论的回复,我会查找parent_comment_id
的评论,以匹配我正在寻找的评论。
这对我来说似乎是多余的,因为它需要我通过整个comments
表来查找评论是否有回复(特别是对于大数据),如果我有一个密钥库数据库,我会有一个注释ID的密钥,里面会是按日期排序的回复列表。
您认为哪种方法更适合此问题?
此外,我想将问题概括为将任何一对多关系存储为密钥库数据库中的列表。如果您建议使用密钥库数据库,那么您建议使用哪一个大数据? (我不想使用redis,因为它在内存中,我怀疑评论的回复需要经常访问)。
感谢您的回复。
答案 0 :(得分:3)
关系数据库应该处理这个“邻接列表”模型。
首先,不要在“root”注释的parent_comment_id
中使用0,使用NULL。然后,您可以构建从parent_comment_id
到comment_id
的外键,以防止您错误地将回复附加到不存在的评论中。
这将要求我浏览整个评论表,以确定评论是否有回复
假设您已将parent_comment_id
编入索引(如果您创建了上述FK,则为InnoDB did automatically),找到对给定评论的第一级回复将需要索引范围扫描。要了解索引范围扫描及其效率的原因,首先需要了解Anatomy of an SQL Index。
找到第二级需要另一个范围扫描等。不幸的是,MySQL不支持递归查询,它允许你在单个数据库往返中完成所有这些,但它应该仍然相当有效。
如果您已经预先形成度量并得出结论认为是一个问题,那么还有其他策略来表示层次结构(具有不同的权衡),例如“嵌套集”和“闭包”。看看this presentation by Bill Karwin。
答案 1 :(得分:2)
事实上,大多数关系数据库都不必通过所有评论来找出哪些是给定评论的回复。在所有这些类型的查询非常频繁且非常优化之后。另请考虑在parent_comment_id
上构建索引。再次,只有你有一个单一的parenship水平才有效。如果您的评论可能会被评论,那么存储数据的另一种方式可能会为您提供更好的服务。
答案 2 :(得分:2)
对Branko的回复进行投票。父字段上的索引是好的。在这种情况下,NULLS的工作效果优于零。加上参照完整性约束对你的帮助会比你伤害更多。
一些额外的观点。
如果您使用nested-sets方法而不是现有的邻接列表方法,您将能够搜索由回复和回复等回复构成的整个子树,而不仅仅是立即回复。这可能很有用。
其次,有一种称为“森林”的数据结构。这是一个包含一组树的表,其中每棵树都以其根为根,在这种情况下是没有父项的注释。网络搜索应该为您提供一些关于设计讨论森林的好文章,其中每个讨论都以评论开头,每个讨论都是一个回复树。很多人都设计了这种情况。
答案 3 :(得分:2)
您可以创建表格并使其更灵活。
comments => comment_id,the_comment,count_replays
comments_replay => parent_id,the_comment
当有重播评论时,count_replays会有更新。
现在你可以做if语句,如果有重放,只有请求它们。