2009-05-16 13 views
1

現在、さまざまなコンピテンシーを含む分類されたMySQLテーブルを持つWebサイトを構築中です。ネストされたセットモデルが最適化されていることがわかりました。しかし、重大な問題があります。ネストされたセットモデルはソートを許可していないため、実際にはその可能性が必要です。 私は(ソートのいずれかの種類なしが)この機能がサポートとして、出力データは、配列(ID、名前、深さ)になりたい:PHP:ネストされたセットからデータをソート

function tree() 
{ 
    $query = 'SELECT node.id, node.name, (COUNT(parent.name) - 1) AS depth FROM test_competence AS node, test_competence AS parent WHERE node.lft BETWEEN parent.lft AND parent.rgt GROUP BY node.name ORDER BY node.lft'; 
    $result = mysql_query($query) or die(mysql_error()); 

    while($data = mysql_fetch_assoc($result)) 
    { 
     $returnarray[] = $data; 
    } 

    return $returnarray; 
} 

私は機能を開始したが、持ってきましたどのように続けるかわからない:

function tree_sorted() 
{ 
    //Get data 
    $query = 'SELECT node.id, node.name, node.parent, (COUNT(parent.name) - 1) AS depth FROM test_competence AS node, test_competence AS parent WHERE node.lft BETWEEN parent.lft AND parent.rgt GROUP BY node.name ORDER BY node.lft'; 
    $result = mysql_query($query) or die(mysql_error()); 

    //Fetch gotten data 
    while($data = mysql_fetch_assoc($result)) 
    { 
     $fetched[$data['depth']][$data['id']] = array($data['name'], $data['parent']); 
    } 

    //Sort fetched data 
    foreach($fetched as $i => $row) 
    { 
     asort($row); 
     $sorted[$i] = $row; 
    } 

    //Merge sorted data (???) 
    foreach($sorted as $i => $arr) 
    { 
     foreach($arr as $x => $row) 
     { 
      $returnarray[] = array('id' => key($row), 'name' => $row[0], 'depth' => $x); 
     } 
    } 

ご協力いただければ幸いです。私はネストされたセットからデータをソートするためのさまざまな方法を探ってきましたが、良い結果はありません。

ありがとうございます。

EDIT:正しい方法だと感じているuasort()関数でいくつか試しましたが、まだ問題は残ります。

+0

ちょっとしたことですが、暗黙的なものではなく、明示的なJOINをSQLにお勧めします。 – staticsan

答えて

0

実際に大量のトラフィックが予想されない限り、ネストされたセットモデルを使用しているときは、実際には必要ありません。私は正確に階層が必要なのか分かりませんが、その前にキャッシュを持つ単純な親子テーブルが不十分であるかどうかを確認することをお勧めします。

繰り返しますが、これはもちろん、アプリケーションに依存し、パフォーマンスの問題について心配しています。

+1

私たちの場合に役立つのは単なるパフォーマンスだけではありません。ネストされたセットモデルは、クエリのレベル数を制限する共通の親テクニック(各レベルは左結合が必要です。この場合、レベル数は各能力において非常に異なる可能性があります)と比較して、無制限レベルのカテゴリをサポートします。 – Ivar

0

ネストされたセットツリーデータは定義上既にソートされているため、暗闇で刺すと、データをソートするために別のフォーマット(通常はフラットなもの)に変換する必要があるように聞こえます。これを達成する最も簡単な方法は、データを操作して、フラットなデータセットを作成することです。

SQLにはいくつかのオプションがあります。私が正しい用語を持っているならば、左のIDによる注文は、あなたの順序でのトラバーサルを取得します。これは通常、リストにまとめたときに意味をなさないように、セットツリーをリストするときに人々が望むものです。私は、SQLのORDER BY句を試しています。例えば、depthパラメータで並べ替えると、レベルオーダートラバーサルが得られます。それをnode.nameと組み合わせてみてください。

+0

ありがとう、私はそれを試みます。 – Ivar

1

ツリー内にノードのセットを並べ替える必要があり、ツリー内のレベルを無制限に維持する必要がある場合は、あらかじめツリーのトラバーサルを使用することをおすすめしますか?

実装の例については、http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/を参照してください。

各ノードの左右の値を維持することが重要です。各ノードの深さの列を維持することもできます。これにより、ツリーのどのレベルにあるかがわかります。これらの左右の値を使用して、ツリー内のノードをその順序でソートし、深度値を使用して、ツリーのレベル数。

このアプローチの唯一の欠点は、ノードの構造を変更するときに、これらの値を積極的に維持する必要があることです。

関連する問題