【问题标题】:Tree structure in... forest. How to retrieve tree by forest id?森林中的树结构。如何通过森林 ID 检索树?
【发布时间】:2013-09-08 20:12:22
【问题描述】:

问题本身可能写错了,所以如果有人知道如何定义它,请编辑问题。


结构

仅重要的列。

cmets

  • comment_id
  • comment_parent_id
  • user_id
  • comment_text

帖子

  • post_id
  • user_id
  • post_text

cmets_to_post (cmets_to_foos, cmets_to_bars, ...)

  • comment_id
  • post_id (foo_id, bar_id, ...)

comments_to_post 与 cmets 的连接只有在 comments 上的 comment_parent_idNULL 时,因为所有其他评论都只是其他评论的子项。


我正在努力处理查询,结果将给我分配到特定帖子(post_id)的 cmets 及其子项。

我尝试从comments 中选择并加入comments_to_post 其中post_id = ? 但难怪我只有带有NULL comment_parent_id 的cmets,因为只有它们通过comments_to_post 连接。

如何在结果中添加子项 cmets?


示例数据:

cmets

comment_id comment_parent_id
1          NULL
2          1
3          1
4          NULL
5          4

帖子

post_id
10
20

cmets_to_posts

comment_id post_id
1          10
4          20

预期结果

... where post_id = 10

comment_id
1
2
3

【问题讨论】:

  • 向我们展示一些相关数据和您想要的结果。
  • 我会在 cmets 表中添加一个 post_id 字段,以便您可以删除 cmets_to_post 表。它使您免于递归搜索...
  • @MartyMcVry,那么我应该为我想要有 cmets 的每个表添加列吗?在实际示例中,这将是 5 列。
  • 你确定你需要在 cmets 上建立一个树层次结构吗?拥有一个post_comment_number 会更容易,它将为每个帖子的第 1、2、3、... 评论分配编号 1、2、3、...。除非您也需要 cmets 发表评论。
  • @ypercube,是的,我确定。我喜欢在 YouTube 上呈现 cmets 的想法。列出您回复的评论的可能性。

标签: mysql


【解决方案1】:

您应该将字段post_id 添加到表comments(在这种情况下您不需要表comments_to_posts)。只有在这种情况下,您才能通过一个数据库请求选择所有 cmets 和子 cmets。

另外,如果你想在树结构中拥有一些数据(cmets、菜单等),我建议你阅读http://en.wikipedia.org/wiki/Nested_set_model。这是解决这个问题的一种非常有趣和优雅的方法。

【讨论】:

  • this page 也解释了相同的方法。
  • @Sanja,我了解嵌套,我了解连接表,但我试图在一个查询中连接这两种方法。而你刚刚毁了我的世界,说不可能,你现在快乐吗?但是,说真的,如果帖子、新闻、文章等都可以使用 cmets 怎么办?我应该将所有这些作为参考直接添加到 cmets 表中吗?作为 post_id、news_id、article_id 是否有可能为 NULL?
  • 在这种情况下,我将添加 2 列:parent_id、parent_type 并在它们上创建一个索引。在这种情况下,如果您要添加一些也具有 cmets 的新类别(例如,问题),则无需添加新列。
  • @Sanja,一列上有多个外键是不可能的。所以parent_id不能链接到帖子、新闻、文章……,即使它依赖于parent_type
  • 我没有说外键。只添加一个索引来加快数据库请求。您可以在多个列上创建索引。
【解决方案2】:

更新-

您可以在没有UNION 的情况下执行此操作,如下所示。请注意,这两种方法都只适用于单级评论线程。

SELECT c.*
FROM comments_to_post ctp , comments c
WHERE ctp.post_id = 1
  AND ( c.comment_id = ctp.comment_id OR c.comment_parent_id = ctp.comment_id)

先获取父级 cmets,然后获取子级,然后将它们全部 UNION。见DEMO fiddle

SELECT c.*
FROM comments_to_post ctp , comments c
WHERE ctp.post_id = 1
  AND c.comment_id = ctp.comment_id

UNION ALL

SELECT c.*
FROM comments_to_post ctp , comments c
WHERE ctp.post_id = 1
  AND ctp.comment_id = c.comment_parent_id
ORDER BY comment_id

【讨论】:

    猜你喜欢
    • 2016-07-31
    • 2011-07-26
    • 2012-10-27
    • 2016-10-28
    • 1970-01-01
    • 2016-10-08
    • 2019-10-23
    • 2011-11-28
    • 2016-07-05
    相关资源
    最近更新 更多