代码之家  ›  专栏  ›  技术社区  ›  Niyaz

如何实现线程注释?

  •  37
  • Niyaz  · 技术社区  · 16 年前

    reddit )

    我很想听听SO社区对如何做到这一点的意见。

    评论 桌子?

    Comment
        id
        parent_post
        parent_comment
        author
        points
    

    这个结构应该做什么改变?

    我应该如何从这个表中获取详细信息,以正确的方式显示它们?

    4 回复  |  直到 16 年前
        1
  •  17
  •   Frans Bouma    16 年前

    在数据库中存储树是一个有许多不同解决方案的主题。这取决于你是否也想检索一个子层次结构(即项目X的所有子级),或者你是否只想获取整个层次结构集,并使用字典在内存中以O(n)的方式构建树。

    您的表的优点是,通过对父帖子进行过滤,您可以一次性获取帖子的所有评论。由于您以教科书/天真的方式定义了评论的父级,因此必须在内存中构建树(见下文)。如果你想从数据库中获取树,你需要一种不同的方式来存储树: 请参阅我对基于预计算的方法的描述: http://www.llblgen.com/tinyforum/GotoMessage.aspx?MessageID=17746&ThreadID=3208 或通过 using balanced trees described by CELKO here :

    或另一种方法: http://www.sqlteam.com/article/more-trees-hierarchies-in-sql

    如果你在内存中获取层次结构中的所有内容并在那里构建树,那么由于查询非常简单:select,因此效率会更高。.from注释,其中ParentPost=@id ORDER BY ParentComment ASC

    在该查询之后,您只需使用一个字典在内存中构建树,该字典跟踪元组CommentID-Comment。现在,您遍历结果集并动态构建树:您遇到的每个注释,都可以在字典中查找其父注释,然后将当前处理的注释也存储在该字典中。

        2
  •  7
  •   Cory R. King    16 年前

    ltree PostgreSQL的模块。它应该使涉及树部分的数据库操作更快一些。它基本上允许您在表中设置一个字段,如下所示:

    ltreetest=# select path from test where path <@ 'Top.Science';
                    path                
    ------------------------------------
     Top.Science
     Top.Science.Astronomy
     Top.Science.Astronomy.Astrophysics
     Top.Science.Astronomy.Cosmology
    

    然而,它本身并不能确保任何形式的引用完整性。换言之,你可以拥有“Top.Science.Astronomy”的记录,而无需拥有“Top.Science”或“Top”的记录。但它让你做的是这样的事情:

    -- hide the children of Top.Science
    UPDATE test SET hide_me=true WHERE path @> 'Top.Science';
    

    -- nuke the cosmology branch
    DELETE FROM test WHERE path @> 'Top.Science.Cosmology';
    

    如果结合使用存储过程的传统“comment_id”/“parent_id”方法,我认为你可以两全其美。您可以使用您的“路径”快速遍历数据库中的注释树,并且仍然可以通过“comment_id”/“parent_id”确保引用完整性。我设想的是:

    CREATE TABLE comments (
    comment_id SERIAL PRIMARY KEY,
    parent_comment_id int REFERENCES comments(comment_id) ON UPDATE CASCADE ON DELETE CASCADE,
    thread_id int NOT NULL  REFERENCES threads(thread_id) ON UPDATE CASCADE ON DELETE CASCADE,
    path ltree NOT NULL,
    comment_body text NOT NULL,
    hide boolean not null default false
    );
    

    注释的路径字符串如下

    <thread_id>.<parent_id_#1>.<parent_id_#2>.<parent_id_#3>.<my_comment_id>
    

    因此,comment_id为“1”的线程“102”的根注释的路径为:

    102.1

    102.1.3

    102.1.3.31
    102.1.3.54
    

    UPDATE comments SET hide=true WHERE path @> '102.1.3';
    

    不过我不知道——这可能会增加不必要的开销。另外,我不知道ltree保养得有多好。

        3
  •  5
  •   TFD    16 年前

    您当前的设计对于小层次结构(少于1000个项目)基本上是合适的

    如果你想在某个级别或深度上获取,请在你的结构中添加一个“级别”项,并将其作为保存的一部分进行计算

    如果性能有问题,请使用体面的缓存

        4
  •  4
  •   alexpopescu    16 年前

    1. 在一个操作中获取一个线程中的所有评论
    2. 按日期或排名对帖子中的评论进行排序

    ./亚历克斯