PostgreSQL的Ltree模块是否适合线程注释?

时间:2009-03-02 20:36:33

标签: database postgresql tree comments hierarchy

我正在考虑在我的应用程序中使用PostgreSQL的Ltree module来帮助处理线程注释。我一直在讨论它用于线程评论。我认为这对于需要更新节点及其子节点的情况有帮助,例如当您想要隐藏注释及其回复时。

我在想它(或类似的东西)如果它与传统的邻接列表(“comment_id”/“parent_comment_id”)相结合会很有用。

在开始使用ltree之前,我想知道一些事情:

  1. 您或者您是否使用过ltree?是人们可以称之为“生产就绪”吗?
  2. 如果是这样,你用它来解决什么问题?它做得好吗?
  3. 你觉得它适合一个人吗? 线程评论系统?
    1. 如果您使用它,您对路径的“文本”部分使用了什么?您是否设置了类似DMOZ示例的东西,他们使用“Top.Astronomy.Cosmology”或基于类似主键“1.403.29.5”的内容?
    2. 有更好的方法吗?我使用嵌套列表方法有点紧张 - 我读过的所有内容都表明,不是所有的都是热门的UPDATES或INSERTS(你不需要重新排序整个事情吗?)。我也不是CS专业,这种数据结构是我将来可能忘记的。是否有人使用嵌套列表进行评论或类似的东西?
  4. 如果有任何帮助,这里是我正在考虑的架构:

    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
    );
    

    ltree使用的“path”列如下所示:

    <thread_id>.<parent_comment_id_#1>.<parent_comment_id_#2>.<my_comment_id>
    

    在路径中使用主键有什么问题吗?我应该在路径中包含节点自己的主键吗?如果我这样做,将一个唯一索引作为约束是否有意义?

3 个答案:

答案 0 :(得分:6)

  1. 是和是;
  2. 知识库中的部分层次结构(其中一个实现);
  3. 是;
  4. 其中一个表的定义:

                                                       Table "knowledgebase.section"
               Column           |           Type           |                                  Modifiers
    ----------------------------+--------------------------+-----------------------------------------------------------------------------
     section_sid                | integer                  | not null default nextval('knowledgebase.section_section_sid_seq'::regclass)
     section                    | character varying        | not null
     description                | character varying        |
     path                       | ltree                    | not null
     is_active                  | boolean                  | not null default true
     role_sid                   | integer                  | not null
     last_modified_by           | integer                  | not null
     creation_datetime          | timestamp with time zone | not null default now()
     last_modification_datetime | timestamp with time zone | not null default now()
     is_expanded                | boolean                  | not null default false
     section_idx                | tsvector                 |
    Indexes:
        "section_sid_pkey" PRIMARY KEY, btree (section_sid)
        "section_section_key" UNIQUE, btree (section)
        "idxsection_idx" gist (section_idx)
        "path_gist_idx" gist (path)
    Foreign-key constraints:
        "last_modified_by_fkey" FOREIGN KEY (last_modified_by) REFERENCES "user"."role"(role_sid) ON UPDATE CASCADE ON DELETE RESTRICT
        "role_sid_fkey" FOREIGN KEY (role_sid) REFERENCES "user"."role"(role_sid) ON  UPDATE CASCADE ON DELETE RESTRICT
    Triggers:
        section_idx_update BEFORE INSERT OR UPDATE ON knowledgebase.section FOR EACH ROW EXECUTE PROCEDURE tsearch2('section_idx', 'section')
    

    “path”列使用主键作为标签。

    该表当前内容的示例(关于主键和“路径”列):

      section_sid | path
     -------------+-------
               53 | 34.53
               56 | 56
               55 | 29.55
               35 | 35
               54 | 34.54
               37 | 30.37
              ... | ...
    

答案 1 :(得分:4)

我建议任何人在SQL中实现层次关系阅读Joe Celko's Trees and Hierarchies in SQL for Smarties

仅使用parent_id时,遍历任意深度的父子链接可能效率非常低。该书描述了使这种访问快速进行的技术。

在这一系列文章中也可以免费找到一种策略(我碰巧使用):

答案 2 :(得分:2)

PostgreSQL版本8.4将通过WITHWITH... RECURSIVE表达式将公用表表达式功能引入核心。如果您正在修改旧代码,您可能要等到8.4发布,因此您不必担心Ltree和新核心语法之间的任何不兼容性。如果您正在使用旧代码,或者不想等待8.4,那么您可能希望确保编写可轻松转换为新语法的代码,尤其是在您更改旧模式或设计新模式时之一。

另见: