9

SQL クロージャ テーブルに頭を悩ませているので、見つけたいくつかの例を理解するための助けが必要です。

sample_items次の階層データで呼び出されるテーブルがあるとします。

id   name                   parent_id
1    'Root level item #1'   0
2    'Child of ID 1'        1
3    'Child of ID 2'        2
4    'Root level item #2'   0

ツリー構造は事実上次のようになります。

id
| - 1 
|   | - 2
|       | - 3
| - 4

ツリーのクエリ (特定の ID のすべての子孫を検索するなど) を容易にするために、この優れた SO 投稿 で Bill Karwin によって説明されている方法sample_items_closureを使用して呼び出されるテーブルがあります。また、必要に応じて直接の子または親を照会するためのオプションの列も使用します。この方法を正しく理解していれば、クロージャー テーブルのデータは次のようになります。path_length

ancestor_id   descendant_id   path_length
1             1               0
2             2               0
1             2               1
3             3               0
2             3               1
1             3               2
4             4               0

のすべての行には、それ自体とそのすべての先祖の両方sample_itemsのエントリがテーブルに含まれています。sample_items_closureこれまでのところ、すべてが理にかなっています。

ただし、他のクロージャー テーブルの例を調べているときに、ルート レベル (ancestor_id 0) にリンクし、パスの長さが 0 である行ごとに追加の祖先を追加するものに出くわしました。上記と同じデータを使用すると、次のようになります。クロージャーテーブルは次のようになります。

ancestor_id   descendant_id   path_length
1             1               0
0             1               0
2             2               0
1             2               1
0             2               0
3             3               0
2             3               1
1             3               2
0             3               0
4             4               0
0             4               0

より良いコンテキストを提供するために、そのサイトで使用されている選択クエリを、私の例に合うように変更したものを次に示します。

SELECT `id`,`parent_id` FROM `sample_items` `items`
  JOIN `sample_items_closure` `closure`
  ON `items`.`id` = `closure`.`descendant_id`
  WHERE `closure`.`ancestor_id` = 2

この方法に関連する 2 つの質問があります。

質問1:

各子孫をルート レベル (id 0) にリンクする追加の行が追加されるのはなぜですか?

質問2:

前の祖先の path_length + 1 ではなく、これらのエントリの path_length が 0 になるのはなぜですか? 例えば:

ancestor_id   descendant_id   path_length
1             1               0
0             1               1
2             2               0
1             2               1
0             2               2
3             3               0
2             3               1
1             3               2
0             3               3
4             4               0
0             4               1

おまけの質問:ツリーの完全な構造が既にクロージャ テーブルで表現されているのに、一部の例にまだ隣接リスト (私の例では のparent_id列) が含まれているのはなぜですか?sample_items

4

1 に答える 1

0

CTEを使用できます。それらはまさにこれらのユースケース向けに作成されており、あなたのケースに近い多くの素晴らしい例があります.

于 2018-08-22T13:42:10.623 に答える