pros: enforce the tree structure; can be used to rebuild the materialized
path if becomes inconsistent; simple to move subtrees; easy concurrent
updates
cons: the tree needs to be written in a specific order respecting
the relationships; inserting by path is harder
You must have a unique constraint on the column representing the path name
example: if you have two nodes with a name set to be "backup", then you
cannot have a path based on the name, like /system/backup because it
would map to two different nodes.
Option 1: store the full path
example: path column with a unique constraint containing the full
path from the root to the node
cons: need to update the path column on every move operation;
Option 2: store the path component
example: name column with a unique constraint together with the
parent_id
Materialized paths
best use cases: tree rarely changes and you need to do traversal queries;
the source of truth for the tree is external, and you are only reading
and replicating.
avoid: when you have a lot of writes/levels/nodes in the tree; when the
nodes chage position frequently.
pros: simple query;
cons: hard to maintain consistency, you need to update the ltree in the
whole tree everytime you move/rename a node in a transaction; write
performance