2

任意のサイズに拡張できる、階層的に編成された一連のデータがあります。ツリー全体を取得する必要がありますが、SQL だけでそれを行う方法がわかりません。私の現在の解決策は、一時テーブルを作成し、再帰関数を使用してツリーのブランチを連続してクエリし、結果を一時テーブルに格納してから、再度クエリを実行して目的の結果を生成することです。

私の質問は、私がやっていることは本質的に結合が正しいことですか? 中間テーブルを作成し、結果に対してクエリを実行します。結合でそれを行う方法があるはずですが、MySQL のドキュメントでは、有限の深さまでのツリーの部分の取得のみがカバーされています。これを行う方法はありますか?私はPHPでこれをやっています。

4

2 に答える 2

15

MySQL は再帰クエリをサポートしていません。

Bill Karwin のプレゼンテーションをご覧になることをお勧めします。そこでは、階層データを格納するための 4 つの異なるモデルを比較し、それぞれの長所と短所を調べています。

  • 隣接リスト
  • パス列挙
  • ネストされたセット
  • 閉鎖表

スライド 48 は、各モデルでの特定の種類のクエリの相対的な難易度を示しています。あなたの質問から、隣接リスト (現在使用しているモデル) のパフォーマンスが 4 つのうち最も低い「クエリ サブツリー」に最も関心があるように思えます。

または、テーブル内のすべてのデータのように、ツリー全体を選択するだけの場合は、単純なクエリ SELECT * FROM yourtableを使用して、クライアントでツリー構造を再構築できます。

于 2010-09-13T20:33:56.147 に答える
1

さらにデータが必要です..テーブルは単一のツリーのみを表していますか、それとも複数のツリーを表していますか? 単一のツリーの場合は、テーブルからすべてを選択して、メモリ内にツリー構造を構築できます。複数のツリーの場合は、各ツリー要素に treeID を追加して、要素が属するツリーを再設定することを検討できます。

ツリーのブランチを選択する場合は、連続した整数の「ソート ランク」と左右のノードへのリンクを含む要素を格納し、最も左のノードと最も右のノードの整数範囲内のすべてのノードを選択することを検討できます。 .

このストレージ モデルの詳細については、隣接リストを参照してください。データストレージは非常に安価であるため、ハイブリッド隣接リスト/親ノードリンクを作成することもできますが、ソートリンクを更新し続けるオーバーヘッドが増える可能性があります...

于 2010-09-13T20:35:50.760 に答える