2

私は次の問題を抱えています: 隣接リストをイメージングします。

SELECT * FROM pages as ps  ORDER BY COALESCE(child_of,page_id), page_id LIMIT x,y

 public static function tree(&$arr, $id = NULL) {

    $result = array();

    foreach ($arr as $a) {

        if ($id == $a['child_of']) {

            $a ['children'] = self::tree($arr, $a['page_id']);

            $result[] = $a;
        }

    }

    return $result;
}

これまでのところ、とても良いです-別の「フラットナー」で、必要な場所に到達しています. さて、ここにトリックがあります。これは「ページ付けされた」結果で機能し、起こりうること (実際に起こること) は、親が 1 つのサブセットにあり、子が別のサブセットにある可能性があるということです。上記の再帰では、子が親が見つからないツリーにたどり着かないことは明らかです。

どうすればそれを解決できますか?助けていただければ幸いです。

4

2 に答える 2

1

A good read to start with is Hierarchical Data In MySQL (which I used to be able to find on the MySQL.com website, arghh)

Read It?

Here's how it could be done with the adjacency list model. But only for a known fixed amount of nesting (four nesting levels for this example).

I would find out which of my pages are root pages (of the tree). Then select only those with a query. Put the LIMIT x,x in this select statement.

After that, the following statement: (or something like it)

string query = "
    SELECT t1.name AS lev1, t2.name as lev2, t3.name as lev3, t4.name as lev4
    FROM category AS t1
    LEFT JOIN category AS t2 ON t2.parent = t1.category_id
    LEFT JOIN category AS t3 ON t3.parent = t2.category_id
    LEFT JOIN category AS t4 ON t4.parent = t3.category_id
    WHERE t1.name IN('ELECTRONICS', '<some other name>');
";

Could return something like this:

+-------------+----------------------+--------------+-------+
| lev1        | lev2                 | lev3         | lev4  |
+-------------+----------------------+--------------+-------+
| ELECTRONICS | TELEVISIONS          | TUBE         | NULL  |
| ELECTRONICS | TELEVISIONS          | LCD          | NULL  |
| ELECTRONICS | TELEVISIONS          | PLASMA       | NULL  |
| ELECTRONICS | PORTABLE ELECTRONICS | MP3 PLAYERS  | FLASH |
| ELECTRONICS | PORTABLE ELECTRONICS | CD PLAYERS   | NULL  |
| ELECTRONICS | PORTABLE ELECTRONICS | 2 WAY RADIOS | NULL  |
| etc...      | etc...               | etc...       |       |
+-------------+----------------------+--------------+-------+

The trick is to use only the root names of the query with limit (or ID's if you want) in the IN() statement of the query.

This should perform pretty good still (in theory).

The principle of the above query could also be used to find out how many descendants are in a root of a tree (with a little GROUP BYand COUNT() magic ;) Also, you could find out which of your pages are roots with this principle (though I would save that in the tabledata for performance reasons)

If you want a dynamic amount of nesting (for nearly endless scaling), implementing a nested set would be the way to go.

于 2011-07-13T16:51:30.133 に答える
1

リレーショナル テーブルの階層データ。

現在のデータベース レイアウトでは、常にすべてのノードを取得するか、JOINSネスト レベルと同じ数のノードを実行して、すべてを適切に並べ替えることによってのみ、問題を解決できます (並べ替えの方法は、この基本的な問題を少し少なくするだけです)。重要)。

「いいえ」と尋ねる前に、これを行うべきではありません。

もう 1 つの方法は、まったく異なるモデルを選択して階層を作成することです。

  • ネストされたセット
  • すべてのノード間の上位/下位関係。

スライド 48 以降を参照してください。ここに

于 2011-07-13T14:21:13.713 に答える