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:
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?
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
... | ...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With