3

という名前のテーブルがありますtableid行の識別子を表すtypeという名前INT(11)のフィールドがあり、他のフィールドがありますが、この問題には関係ないと思います。

という名前の別のテーブルがありますtable_children。外部キーと呼ばparentれるタイプで名前が付けられたフィールドがあります。これには、外部キーとも呼ば れる typeという名前の別のフィールドがあります。この表は、行間の親子関係を示しています。INT(11)table.idchildINT(11)table.idtabletable

これはおそらく設定です。

table   table_children
id      parent child
0       0      1
1       1      2
2       1      3
3       3      4
4

最小数のリクエストでidのすべての子孫のを取得するにはどうすればよいですか? ここでの0答えは1、、、、2です。34

ご協力ありがとうございました。

4

3 に答える 3

3

MySQL でこれを行う最も簡単な方法は、すべてのパスをツリーに格納し、推移的なクロージャを作成することです。

table_children
parent child
0      0
1      1
2      2
3      3
4      4
0      1
0      2
0      3
0      4
1      2
1      3
1      4
3      4

これで、次のようにクエリできます。

SELECT t.*
FROM table_children c
JOIN table t ON c.child = t.id
WHERE c.parent = 0;

以下も参照してください。

于 2013-01-18T16:55:37.033 に答える
0

MySQL は再帰クエリで動作するように設計されていないため、これを処理するストアド プロシージャを作成しました。私の DBA StackExchange 投稿を参照してください:階層フィールドの最上位レベルを検索: CTE ありとなしの比較

私は次の関数を書きました

  • GetParentIDByID
  • GetAncestry
  • GetFamilyTree
于 2013-01-18T16:03:32.257 に答える
0

データが現在設定されている方法では、すべての子孫を取得する効率的な方法があります。次のようなクエリを実行します。

SELECT child FROM table_children WHERE parent in (x, y, z);

ここで、x、y、および z はすべて、前の反復で取得された子供です。行がなくなるまでクエリを繰り返します。これには、ツリーの深さと同じ数のクエリが必要です。

ただし、ツリーを DB に保存する方法を変更することにオープンな場合は、MPTT (Modified Pre-order Tree Traversal) と呼ばれる別の方法があり、1 回のクエリでサブツリー全体をフェッチできますが、更新はよりトリッキーです。 . 挿入の余分な複雑さが、アプリケーションにとって効率的な検索の利点との適切なトレードオフになるかどうかを判断する必要があります。

ここにMPTT を説明する優れた記事があります。

于 2013-01-18T16:06:55.607 に答える