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

发布于 2024-07-14 08:20:47 字数 1353 浏览 8 评论 0 原文

我正在考虑在我的应用程序中使用 PostgreSQL 的 Ltree 模块 来提供帮助带有线索评论。 我已经关注它有一段时间了,用于线程评论。 我认为这对于需要更新节点及其子节点的情况会有所帮助,例如当您想要隐藏评论及其回复时。

我认为 ltree (或类似的东西)如果与传统的邻接列表(“comment_id”/“parent_comment_id”)结合起来会很有用。

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

  1. 您是否使用过 ltree? 这就是所谓的“生产就绪”吗?
  2. 如果有,您用它解决了什么问题? 做得好吗?
  3. 你认为它很适合 线程评论系统?
  4. 如果您使用过它,您使用什么作为路径的“文本”部分? 您是否设置了类似 DMOZ 示例的内容,他们使用“Top.Astronomy.Cosmology”,还是基于主键“1.403.29.5”之类的内容?
  5. 有更好的方法吗? 我对使用嵌套列表方法有点紧张——我读过的所有内容都表明更新或插入并不那么热(你不需要重新排序整个事情吗?)。 我也不是CS专业的,这种数据结构是我将来可能会忘记的东西。 有人使用嵌套列表进行评论或类似的东西吗?

如果它有任何帮助,这是我正在考虑的模式:

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 使用的“路径”列看起来像:

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

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

I'm considering using PostgreSQL's Ltree module in my application to help with threaded comments. I've been eying it for a while to use for threaded comments. I figure it would help with cases where you need to update a node and its children, like when you want to hide a comment and its replies.

I'm thinking ltree (or something like it) it would be useful if it was coupled with a traditional adjacency list ("comment_id"/"parent_comment_id").

Before taking the plunge into using ltree, I'm wondering a few things:

  1. Are you, or have you, used ltree? Is it what one might call "production ready"?
  2. If so, what problems did you use it to solve? Did it do a good job?
  3. Do you think it is a good fit for a
    threaded comment system?

    1. If you used it, what did you use for the "text" part of the path? Did you set up something like the DMOZ example they use "Top.Astronomy.Cosmology" or base it on something like the primary key "1.403.29.5"?
    2. Is there a better way to do this? I'm a bit nervous using a nested list approach--everything I've read suggests that it isn't all to hot with UPDATES or INSERTS (don't you have to reorder the whole thing?). I'm also not a CS major and that kind of data structure is something I might forget in the future. Is anybody using nested lists for comments or something like it?

If it is of any help, here is the schema I'm considering:

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

The "path" column, used by ltree, would look something like:

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

Is there anything wrong with using the primary keys in the path? Should I be including the node's own primary key in the path? If I did, would it make sense to put a unique index on it to serve as a constraint?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

月下客 2024-07-21 08:20:47
  1. 是的,是的;
  2. 知识库中各部分的层次结构(实现之一);
  3. 是的;

相关表之一的定义:

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

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

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

  section_sid | path
 -------------+-------
           53 | 34.53
           56 | 56
           55 | 29.55
           35 | 35
           54 | 34.54
           37 | 30.37
          ... | ...
  1. Yes and yes;
  2. Hierarchy of sections in a knowledge base (one of the implementations);
  3. Yes;

The definition of one of the tables in question:

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

The "path" column uses the primary key as a label.

A sample of the current contents of that table (regarding the primary key and the "path" column):

  section_sid | path
 -------------+-------
           53 | 34.53
           56 | 56
           55 | 29.55
           35 | 35
           54 | 34.54
           37 | 30.37
          ... | ...
淡淡の花香 2024-07-21 08:20:47

我建议任何在 SQL 中实现层次关系的人阅读Joe Celko 为聪明人编写的 SQL 中的树和层次结构

仅使用parent_id 时,遍历任意深度的父子链接可能会非常低效。 本书描述了可以快速访问的技术。

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

I recommend anyone implementing hierarchical relationships in SQL read Joe Celko's Trees and Hierarchies in SQL for Smarties.

Traversing arbitrary depth parent child links can be very inefficient when using just a parent_id. The book describes techniques that make this access fast.

One strategy (which I happen to use) can also be found for free in this series of articles:

国际总奸 2024-07-21 08:20:47

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

另请参阅:

Version 8.4 of PostgreSQL will be bringing Common Table Expressions functionality into the core with WITH and WITH... RECURSIVE expressions. If you're modifying old code, you may want to wait until 8.4 is released, as then you won't have to worry about any incompatibilities between Ltree and the new core syntax. If you're working with old code, or do not want to wait for 8.4, you will probably want to make sure you write code that is easily translatable to the new syntax, especially if you're changing an old schema or designing a new one.

See also:

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文