Philipp Knüsel wrote:

SanjayK schrieb:

Since SQLite is perfect for use in single-user desktop utility applications
and since such applications typically store hierarchial data (tree) in a
single table, it would be nice to have support for special features like
connect by of oracle.
See:   http://www.adp-gmbh.ch/ora/sql/connect_by.html
--
View this message in context: http://www.nabble.com/Managing-trees-in-the-database-t1135555.html#a2974277
Sent from the SQLite forum at Nabble.com.


Depending on your goals, this concept might give you another solution:

http://dev.mysql.com/tech-resources/articles/hierarchical-data.html

As the code examples are for mysql, you need to adapt it a bit.

HTH

Philipp

The following is an implementation of the materialized path method of storing trees in an SQL database. I have used this method in the past with fairly large trees (about 30K nodes and around 10 levels). I find it works quite well and it's a lot simpler to understand than the nested set approach. For the types of queries I'm doing it usually results in simpler queries as well.

It adds one variable length text field to each record to store the path. It uses triggers to automatically maintain this path and implement cascaded deletes.

It might be suitable for your needs as well.


   -- Sample materialized path implementation of a tree in SQL
   --
   -- The materialized path is a string containing the path to the node
   -- represented by the node ids along the path separated by / characters.
   -- This string is easy to search using the LIKE comparison function
   -- to check for path characteristics. All the methods that apply to the
   -- adjacency list representation can also be used with this format.
   -- The path string is maintained automatically by triggers. Any node
   -- inserted with a NULL parent_id is the root of a new tree.

   create table tree (
     id        integer primary key,
     parent_id integer references tree,
     data      text,
     path      text        -- materialized path
   );
-- set path to node when it is inserted
   create trigger tree_in after insert on tree
   begin
       update tree set path =
           case when parent_id isnull then '/'
else (select path from tree where id = new.parent_id) || parent_id || '/'
           end
       where id = new.id;
   end;

   -- delete subtree below node when a node is deleted
   create trigger tree_del before delete on tree
   begin
       delete from tree where id in
           (select id from tree
           where path like old.path || old.id || '/%');
   end;

   -- example
   insert into tree (id, parent_id, data) values (1, NULL, 'parent');
   insert into tree (id, parent_id, data) values (NULL, 1, 'son');
   insert into tree (id, parent_id, data) values (NULL, 1, 'daughter');
   insert into tree (id, parent_id, data) values (NULL, 2, 'grandchild');
   select * from tree;

   -- find all root nodes
   select * from tree where parent_id isnull;

   -- find all leaf nodes
   select * from tree where id not in (select parent_id from tree);

   -- find all nodes in the sub tree below node
   select * from tree
where path like (select path || id || '/%' from tree where id = :node_id);

   -- find all nodes along the path to node
   select * from tree
   where (select path || id || '/' from tree where id = :node_id)
       like path || id || '/%'
order by path;
   -- find all nodes on level 3 or 4
   select * from tree
   where path like '/%/%/' or path like '/%/%/%/';

HTH
Dennis Cote



Reply via email to