Overview
Each row stores the IDs of all its ancestors, root to self, in a path column such as /1/7/42/. All descendants of node 7 are WHERE path LIKE '/1/7/%', with no recursive query. Pick it for read-heavy trees such as categories and comment threads where subtree lookups dominate and moves are rare.
Rules
- Moving a node rewrites the path of every descendant. For frequently restructured trees, use an adjacency list with recursive CTEs or a closure table.
- Index
path. A B-tree servesLIKE 'prefix%'only under the C locale or withtext_pattern_ops(btree-index). - The database cannot check that a path matches the real parent-child links. Keep a
parent_idforeign-key alongside it, or validate with a trigger. - Depth for
/1/7/42/-style paths is the separator count minus one:length(path) - length(replace(path, '/', '')) - 1. - The
ltreeextension offers a typed path with ancestor and descendant operators and index support.
SELECT * FROM comments WHERE path LIKE '/1/42/%' ORDER BY path;Related
- btree-index: prefix scans on the path column.
- foreign-key: the adjacency-list alternative.
- secondary-index: index cost on write-heavy trees.
- postgres-indexes: operator classes and
ltree. - postgres: hierarchy options.