## Archive for September 24th, 2009

## Adjacency list vs. nested sets: PostgreSQL

This series of articles is inspired by numerous questions asked on the site and on **Stack Overflow**.

What is better to store hierarchical data:

nested setsmodel oradjacency list(parent-child) model?

First, let's explain what all this means.

### Adjacency list

Hierarchical relations (not to be confused with hierarchical data model) are `0-1:0-N`

transitive relations between entities of same domain.

For instance, ancestor-descendant relation is:

- Transitive:
- If
**A**is an ancestor of**B**and**B**is an ancestor of**C**, then**A**is an ancestor of**C**

- If
- Antisymmetric:
- If
**A**is an ancestor of**B**, then**B**is never an ancestor of**A**

- If
- Irreflexive:
**A**is never an ancestor to itself

`0-1:0-N`

**A**can have zero, one or many children.**A**can have zero or one parents.

These relations can be represented by an ordered directed tree.

Tree is a simple directed graph (that with at most one directed edge between two different vertices) and relational model has means to represent simple graphs.

Two vertices are considered related (and therefore their primary keys forming a row in the table) if and only if they are connected with an edge.

This table along with the table defining the vertices identifies a graph completely by defining pairs of vertices connected by the edges. Each record in the table defines a pair of adjacent vertices, that's why this representation is called **adjacency list**.

Adjacency lists can represent any simple directed graphs, not ony hierarchy trees. But due to the fact that this structure is most commonly used to define the parent-child relationships, the terms parent-child model

and adjacency list model

have almost become synonymous. However, they are not: adjacency list model is much wider and parent-child model is one of its implementations.

Now, since we have a tree here which implies `0-1:0-N`

relationship between the vertices, we can define the relation as a *self-relation*: the table defines both the entity and the relationship. Parent is just a one attribute among other attributes with a `FOREIGN KEY`

reference to the table itself.

Since multple items can have no parents (and therefore be the roots of their trees), it's sometimes useful to convert this tree into an arborescence: make a single fake root that considered a parent of all entries that have no actual parent.

This is a nice and elegant model, but until recently it had one drawback: it could not be used with **SQL**.

Read the rest of this entry »