Ataların bir listeden bir ağaç oluşturmak için en kolay yolu

2 Cevap php

Kalbimde, ben bu süper basit bir özyinelemeli bir çözüm olması gerektiğini hissediyorum, ama ben hemen grok olamaz.

Ben bir kapatma tablo olarak SQL saklanan bir ağaç var. Ağaç gibi görünüyor: (1 (2 (3), 4)), ve dilleri MySQL, SQL ve PHP 5.3 vardır.

Kapatma tablo şudur:

+----------+------------+
| ancestor | descendant |
+----------+------------+
|        1 |          1 | 
|        2 |          2 | 
|        3 |          3 | 
|        4 |          4 | 
|        1 |          2 | 
|        1 |          3 | 
|        1 |          4 | 
|        2 |          3 | 
+----------+------------+

Ben oldukça kolay atalarını sorgulayabilirsiniz:

 SELECT descendant AS id, GROUP_CONCAT(ancestor) as ancestors FROM
 closure GROUP BY (descendant);

 +----+-----------+
 | id | ancestors |
 +----+-----------+
 |  1 | 1         | 
 |  2 | 2,1       | 
 |  3 | 3,1,2     | 
 |  4 | 4,1       | 
 +----+-----------+

Nasıl kolayca bu verilerin PHP ile bir ağaç inşa edebilirsiniz? Ben MySQL veri daha çekmek için bir akıllı sorgu kullanabilir miyim?

2 Cevap

Ilk anahtar atalarının sayısına göre SQL sonuçlarını sıralamak için. Ben çoklu-basamaklı sayıların karmaşıklığı önlemek beri PHP yaptım.

Bu, geçerli bir şekilde sokulabileceği bir düzen içinde düğümlerin bir listesini sağlar.

Array
(
    [1] => Array
        (
            [0] => 1
        )

    [4] => Array
        (
            [0] => 4
            [1] => 1
        )

    [2] => Array
        (
            [0] => 2
            [1] => 1
        )

    [3] => Array
        (
            [0] => 3
            [1] => 1
            [2] => 2
        )

)

Bu noktada, ben, anahtarları hakkında atalarının sadece listelerini umurumda değil. Ağaç ile yol mevcut düğümler kesiştiği kalan ataları arasında bulunabilir.

  function add_node($ancestors, &$tree) {
    if (count($ancestors) == 1) {
      $tree[array_pop($ancestors)] = array();
      return;
    }   
    $next_node = array_intersect($ancestors, array_keys($tree));
    $this->add_node(
        array_diff($ancestors, $next_node) , 
        $tree[array_pop($next_node)]
        );  
  }

Ben bir kapatma tablo kullandım (terim ben başka bir şey denir ne duydum / unuttum ... bana garip geliyor) ama ben doğrudan ayırt sağlar ata ve torun arasındaki "mesafe" bir 3 sütun vardı soyundan (çocuk) ve dolaylı torunları (torun vs).

Teknik listelenen tablo yönlendirilmiş Mercury grafikte veri kaydedebilir, bu nedenle w / yinelenen bölümlerde o hiyerarşik bir ağaç inşa etmek mümkün olmayabilir.

edit:

PHP sorgulama olsaydı, ben muhtemelen sadece tablonun kendisi SELECT istiyorum w / GROUP_CONCAT kullanarak o - Eğer prosedür zaten şeyler işleme gidiyoruz, öyleyse neden sadece kendi rawest de kapatma tablonun uygun alt kümesini almak değil formu?

Bir kapatma tablo (önemli ise) sipariş bilgilerini saklamak değil de unutmayın.

Bu hiyerarşik veri ağacı yönleri çok önemlidir ve veri depolamak için nasıl bir seçim varsa, nested set model koruyabilirsiniz sipariş düşünün ve bir ağaç yeniden çok daha kolaydır.