Cum pot genera o structură arborescentă dintr-un tabel într-o bază de date?

voturi
1

Am încercat să genereze o structură arborescentă dintr-un tabel într-o bază de date. Tabelul este stocată plat, cu fiecare înregistrare, fie cu un PARENT_ID sau 0. Scopul final este de a avea o cutie de selectare a generat și o serie de noduri.

Codul am până acum este:

function init($table, $parent_id = 0) 
{

    $sql = SELECT id, {$this->parent_id_field}, {$this->name_field} FROM $table WHERE {$this->parent_id_field}=$parent_id ORDER BY display_order;

    $result = mysql_query($sql);

    $this->get_tree($result, 0);

    print_r($this->nodes);
    print_r($this->select);
    exit;
}

function get_tree($query, $depth = 0, $parent_obj = null)
{   
    while($row = mysql_fetch_object($query))
    {   
        /* Get node */
        $this->nodes[$row->parent_category_id][$row->id] = $row;

        /* Get select item */
        $text = ;
        if($row->parent_category_id != 0) {
            $text .=     ;
        }
        $text .= $row->name;
        $this->select[$row->id] = $text;

        echo $depth $text\n;

        $sql = SELECT id, parent_category_id, name FROM product_categories WHERE parent_category_id=.$row->id. ORDER BY display_order;

        $nextQuery = mysql_query($sql);
        $rows = mysql_num_rows($nextQuery);

        if($rows > 0) {
            $this->get_tree($nextQuery, ++$depth, $row);
        }            
    }
}

Este aproape de lucru, dar nu destul. Poate cineva să mă ajute-l duce?

Întrebat 10/03/2009 la 15:47
sursa de către utilizator
În alte limbi...                            


3 răspunsuri

voturi
1
    $this->nodes[$row->parent_category_id][$row->id] = $row;

Această linie distruge comanda prin display_order. Schimba-l

    $this->nodes[$row->parent_category_id][] = $row;

Problema mea viitoare este partea $ row-> parent_category_id de asta. Nu ar trebui să fie doar $ row-> PARENT_ID?

EDIT: Oh, nu am citit sursa ta destul de strâns. Scapă de clauza WHERE. Citiți întregul tabel dintr-o dată. Ai nevoie pentru a posta procesul de copac a doua oară. Mai întâi citiți baza de date într-o listă de matrice. Apoi, va procesa matrice recursiv pentru a face dvs. de ieșire.

matrice dvs. ar trebui să arate așa:

 Array(0 => Array(1 => $obj, 5 => $obj), 
       1 => Array(2 => $obj),
       2 => Array(3 => $obj, 4 => $obj),
       5 => Array(6 => $obj) );

 function display_tree() {
      // all the stuff above
      output_tree($this->nodes[0], 0); // pass all the parent_id = 0 arrays.
 }

 function output_tree($nodes, $depth = 0) {
     foreach($nodes as $k => $v) {
         echo str_repeat(' ', $depth*2) . $v->print_me();
         // print my sub trees
         output_tree($this->nodes[$k], $depth + 1);
     }
 }

 output:
 object 1
   object 2
     object 3
     object 4
 object 5
   object 6
Publicat 10/03/2009 la 15:56
sursa de către utilizator

voturi
0

Cred că e această linie aici:

if($row->parent_category_id != 0) {
    $text .= "    ";
}

ar trebui să fie:

while ($depth-- > 0) {
    $text .= "    ";
}

Sunteți numai că crestarea o dată, nu numărul de ori trebuie Indentat.

Și această linie:

$this->get_tree($nextQuery, ++$depth, $row);

ar trebui să fie:

$this->get_tree($nextQuery, $depth + 1, $row);

Rețineți că ar trebui să urmeze, probabil, sfatul în celălalt răspuns, deși, și apuca întreaga masă la o dată, și apoi procesul-l dintr-o dată, pentru că, în general, pe care doriți să reducă la minimum rotund excursii la baza de date (există câteva cazuri de utilizare în cazul în care modul în care o faci este mai optimă, cum ar fi în cazul în care aveți un copac foarte mare, și selectăm o mică parte din ea, dar mă îndoiesc că este cazul aici)

Publicat 10/03/2009 la 17:21
sursa de către utilizator

voturi
4

Ai aproape sigur, nu ar trebui să continue în jos calea curentă. Metoda recursiv pe care încercați să utilizați va ucide aproape sigur performanța în cazul în care arborele dvs. devine tot mai puțin mai mare. Probabil ar trebui să fie în căutarea la o structură imbricată în locul unei liste de adiacenta dacă aveți de gând lectură copac frecvent.

Cu un set imbricate, puteți regăsi cu ușurință întregul copac imbricate corect cu o singură interogare.

Vă rugăm să consultați aceste întrebări pentru discuții aa de copaci.

Este posibil pentru a interoga un tabel de structură arborescentă în MySQL într-o singură interogare, la orice adâncime?

Implementarea unei structuri de date ierarhice într-o bază de date

Care este cel mai eficient mod / elegant, pentru a analiza o masă plană într-un copac?

Publicat 10/03/2009 la 18:00
sursa de către utilizator

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more