0

これは私が使用しているクラスです:https ://gist.github.com/2174233

2つのテーブルがあります。1つのテーブルにはユーザーが含まれ、もう1つのテーブルにはクロージャが含まれます。

メソッドを使用get_children()すると(たとえば、ルートまたは別の親から)、階層の最初のレベルのみが表示されます。どの値をlvl 列に保存する必要がありますか?

これは私が持っているクロージャーテーブルの定義です:

 CREATE TABLE closures (
     id         INT(11) NOT NULL AUTO_INCREMENT,
     ancestor   INT(11) NOT NULL,
     descendant INT(11) NOT NULL,
     lvl        INT(11) NOT NULL,

     PRIMARY KEY (id)
 )

クロージャテーブルに保存するデータの例を次に示します。

INSERT INTO `closures` (`id`, `ancestor`, `descendant`, `lvl`) 
VALUES (1, 1, 20, 0),
       (4, 20, 26, 0),
       (5, 26, 25, 0);

最後はlvl列ですが、どの値がそこにあるのかわかりません。使い方を教えてください。

私が保存しなければならない構造には3つのレベルがあります:ルート->20ノード->26ノードですが、それは私に20ノードである最初のレベルの子だけを与えます。

4

1 に答える 1

3

SQLアンチパターンの本を手に入れることをお勧めします。第2章では、カテゴリツリーを実装するための推奨される方法の1つとしてクロージャテーブルを取り上げています。

そうは言った。クロージャーテーブルが少し奇妙に見えます。idそこの列には意味がありません。代わりに、祖先と子孫の値の一意のペアから作成された複合主キーが必要です。

また、ノード自体は挿入していません。2つの異なるノード間の接続のみです。「クロージャーテーブルを使った木のレンダリング」を読むと、このテーマに光を当てることができるかもしれません。

推測では、INSERTステートメントは次のようになります(少なくとも私の結論):

INSERT INTO closures(ancestor, descendant, lvl) 
VALUES (1,  1,  null),
       (20, 20, null),
       (26, 26, null),
       (28, 28, null),
       (1,  20, 1),
       (20, 26, 2),
       (26, 25, 3);

理解しなければならないのは、クロージャーテーブルはツリーを格納していないということです。代わりに、使用しているデータ構造は有向グラフです。このようなもの:

ここに画像の説明を入力してください

ご覧のとおり、このグラフには3つのルートノード(3、5、7)があります。また、ノード10は、開始するルートノードに応じて、深さのレベルが異なることに注意してください。

[3,10,1]と[11,10,2]の2つのクロージャで定義されます。つまり、11番目のノードからの接続ではレベル2になり、3番目のノードから開始すると1番目のレベルのアイテムになります。

つまり、クロージャテーブルを使用している場合、各カテゴリには、それぞれ異なるレベルの深さの複数の親カテゴリを含めることができます


追加(@ypercubeによる):

「レベル」または「深さ」の列についての私の理解は、祖先から子孫までの「距離」(進むために必要なステップ)を格納するということです。これはノードの絶対レベルではないため、クロージャテーブルを使用して、ツリーグラフよりも複雑なものを格納できます。祖先から子孫への複数のパスがあり、それぞれが異なるステップ(パス)を持っている場合もあります。

さらに、Nullは0である必要があり、さらにいくつかの行が必要です。

したがって、データは次のようになります。

INSERT INTO closures(ancestor, descendant, lvl) 
VALUES ( 1,  1,  0), (20, 20, 0), (26, 26, 0), (25, 25, 0),
                     ( 1, 20, 1), (20, 26, 1), (26, 25, 1),
                                  ( 1, 26, 2), (20, 25, 2),
                                               ( 1, 25, 3) ;
于 2012-07-08T03:02:39.317 に答える