Xpoint
   [напомнить пароль]

Вывод древовидной структуры из БД

Существуют различные способы хранения древовидных структур в СУБД.
Наиболее простым и распостраненным является следующий способ:
Вся информация о дереве хранится в одной таблице. Одна ветвь - одна запись. Каждая ветвь содержит ссылку на родителськую ветвь.
Таблица "Tree"

NodeIDParentNodeIDNameSeq
10\1
21Node11
32Child1OfNode11
42Child2OfNode12
51Node22
65Child1OfNode21
75Child2OfNode22
85Child3OfNode23

где

  • NodeID - уникальный идентификатор ветви
  • ParentNodeID - идентификатор родителя
  • Name - название ветви
  • Seq - число, характеризующее порядок вывода дочерний ветвей в пределах одной родительской ветви.

Для вывода такой структуры в виде дерева названий, можно использовать следующий код:

#!/usr/bin/perl

BEGIN { require ".poem"; }
use lib $ENV{POEM_LIB_ROOT};

use POEM::DBC;

my $DBC = POEM::DBC->new("root");
my $items = $DBC->getRecords("SELECT NodeID AS id, ParentNodeID AS parent, name FROM Tree ORDER BY Seq");
# здесь приведен пример с абстрактным котроллером СУБД
# DBC->getRecords должен вернуть ссылку на массив хэшей
my $tree = { 0 => { id => 0, name => 'ROOT', children => [] } };
# первый проход
for my $item (@$items)
{
    my $node = exists $tree->{ $item->{id} } ? $tree->{ $item->{id} } : { children => [] };
    # добавляемся в детишки к родителю
    # а заодно автоматом создаем ноду родителя $tree->{ $item->{parent} }, если таковой еще нет
    push @{$tree->{ $item->{parent} }{children}}, $node;

    # заполняем информацией свою ноду. 
    # при этом помним, что дети добавляются в свойство-массив children этой ноды независимо 
    # либо раньше, либо позже в зависимости от порядка выборки. кодом выше
    $node->{id} = $item->{id};
    $node->{name} = $item->{name};
    $tree->{$item->{id}} = $node;
}

# второй проход - вывод
outNode($tree->{0});

sub outNode
{
   my $node = shift;
   my $level = shift;
   my $indent = ' ' x $level;
   print $indent, $node->{name}, "\n";
   for my $child ( @{ $node->{children} } ) 
   {
      outNode($child, $level + 1);
   }
}
Powered by POEM™ Engine Copyright © 2002-2005