我正在考虑在我的应用程序中使用PostgreSQL的Ltree module来帮助处理线程注释。我一直在讨论它用于线程评论。我认为这对于需要更新节点及其子节点的情况有帮助,例如当您想要隐藏注释及其回复时。
我在想它(或类似的东西)如果它与传统的邻接列表(“comment_id”/“parent_comment_id”)相结合会很有用。
在开始使用ltree之前,我想知道一些事情:
如果有任何帮助,这里是我正在考虑的架构:
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>
在路径中使用主键有什么问题吗?我应该在路径中包含节点自己的主键吗?如果我这样做,将一个唯一索引作为约束是否有意义?
答案 0 :(得分:6)
其中一个表的定义:
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将通过WITH
和WITH... RECURSIVE
表达式将公用表表达式功能引入核心。如果您正在修改旧代码,您可能要等到8.4发布,因此您不必担心Ltree和新核心语法之间的任何不兼容性。如果您正在使用旧代码,或者不想等待8.4,那么您可能希望确保编写可轻松转换为新语法的代码,尤其是在您更改旧模式或设计新模式时之一。
另见: