Re: Storing a tree - Mailing list pgsql-general

From Thomas T. Thai
Subject Re: Storing a tree
Date
Msg-id Pine.NEB.4.21.0111120827420.24297-100000@ns01.minnesota.com
Whole thread Raw
In response to Re: Storing a tree  (gravity <tinus@deephosting.com>)
List pgsql-general
On Mon, 12 Nov 2001, gravity wrote:

> On Thu, Nov 08, 2001 at 01:31:10PM +0100, Antonio Fiol Bonn?n wrote:
> > Hello,
> >
> > I have found a problem today to which I am unable to find the solution.
> > I write to this list looking for help.
>
> try this for something different:
>
> http://www.utdt.edu/~mig/sql-trees/

How I'm doing a tree structure in SQL is ... I'll just cut/paste my notes:

---
Fast SQL tree or hierarchy structure where you have varying levels of parent
and child relationships. Typical use include Internet portal category
listings, family tree, filesystem structure, or organization
classifications by company, division, and departments.

     TOP                     One big advantage of using this method is
      |                      you can search starting at any node andall
      +---O 01               it's branches or subnodes by using one query.
      |   |                  In addition getting the path by traversing
      |   +---O 0101         back to the top can be done with just one
      |   |   |              query instead of many recursive queries.
      |   |   +---O 010101
      |   |   |              The left diagram shows the relationship
      |   |   +---O 010102   between each node and their associated paths.
      |   |                  Here we are using 2 chars for each node. This
      |   +---O 0102         gives us a max of (using base 36) 36 * 36
      |                      immediate childs per node. Since SQL CHAR
      +---O 02               fields have a max of 255 chars, we can have
      |                      a max depth of 255 / 2 = 127. By varying the
      +---O 03               char width of each node, we can increase or
                             decrease the depth at the cost or value of
the number of child per depth. CHAR field type gives us the possibility of
using indexes on the column. If we for-go the indexes, we could use TEXT
fields for more depths and childs.

With this approach, you can easily move, delete any branch in that tree or
move it else where. Another interesting thing is given a node or path,
you can trace back all the way to the top using just one query. First
you'd break down the path by generations using substring (in PHP, Perl,
C) and select using the IN clause. For example:

Assume a table like:

CREATE SEQUENCE next_cat_id;

CREATE TABLE "categories" (
        "rec_id" int4 DEFAULT nextval('next_cat_id') PRIMARY KEY,
        "path" varchar(10) DEFAULT '' NOT NULL,
        "name" varchar(64) DEFAULT '' NOT NULL
);

Find the trail from current node to the TOP, we first break down the node

  Node 010102  => (01, 0101, 010102)

Then when you

  SELECT branch, name FROM tree
  WHERE branch IN (01, 0101, 010102)
  ORDER BY branch ASC

You'd get back results in order from the oldest parent to the youngest
child. Then pull the result as an array into your app and walk it to the
top to show the trail.

If you want to select all immediate child under a node:

  SELECT branch, name FROM tree
  WHERE branch IS LIKE '01__'

If you want to move a branch to another branch:

  UPDATE tree
  SET $pathField = ('$toPath' || ";
  SUBSTRING(path, CHARACTER_LENGTH('$fromPath') + 1))
  WHERE path LIKE '$fromPath%'"

To delete all the nodes under a branch '01':

  DELETE FROM tree WHERE path IS LIKE "01%"

Another nice thing is that you can seach for what ever, you can use the
" IS LIKE '$parentNode%' and search from that node to it's deepest child.

---



pgsql-general by date:

Previous
From: Stephan Szabo
Date:
Subject: Re: Trigger documentation problem
Next
From: Jorge Sarmiento
Date:
Subject: Re: psql -f backup.out || file too big - SOLVED