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 w
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:
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:
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
... | ...