7

Oracle を使用する場合、connect by階層クエリの作成に使用できるキーワードがあります。現在、プロジェクトで MySQL を使用していますが、MySQL に代替手段があるかどうかを知りたいconnect byですか?

私はグーグルを試しましたが、今のところ役に立ちません。私が達成しようとしているのは、1 つのクエリでデータベースからツリーをフェッチすることです。関連する 2 つのテーブルがあります。

areasarea_to_parent_join。後者には 2 つの ID が含まれており、1 つはarea_idで、もう 1 つは ですparent_id。つまり、基本的に自己結合であり、そのモデルを使用してグラフを作成できます。実際、現在はツリーの作成にのみ使用されていますが、これは将来変更される可能性があります。しかし、どちらの場合でも、私が持ちたいのは単なるスパニング ツリーです。

編集: areas 1.000.000 を超えるレコードがある可能性があり、スペースを大量に消費するオプションのほとんどが実行不可能になります。

4

2 に答える 2

10

コメントで述べたように、mysql には近道はありません。

しかし!

データベース構造を変更する可能性がある場合は、ツリー状の階層を処理するためのより優れた設計を展開できます。

Bill Karwinのこの TUTORIALに従う場合( HEREは、そのスライドショー チュートリアルを参照する元の回答です)、階層構造をモデル化するために使用される 4 つの方法を見つけることができます。

  1. アディエンシー一覧
  2. パスの列挙
  3. ネストされたセット
  4. 閉鎖表

さて、考えられる最良のモデルは 4 番目のモデルです (他の 3 つのモデルの説明は読者に任せます)。これには基本的に 2 つのテーブルが必要です。1 つは要素用、もう 1 つはパス用です。パス テーブル (クロージャ テーブル自体) には、各ノードからすべての子孫 (直接の子だけでなく!) へのすべてのパスを格納します。

ツリー内の直接の子を簡単に照会できるため、各行のパスの長さも保存することをお勧めします。

このソリューションがより多くのスペースを必要とする場合でも、全体的なパフォーマンスが最高であり、非常に使いやすいです。再帰クエリにまったく依存せず、データセット全体の参照整合性を付与します!

たとえば、ノード #4 のすべての子を取得するには、次のようにします。

select a.*
from nodes a
join paths b
on a.node_id = b.descendant
where b.ancestor = 4

別の例: ノード #11 のすべての祖先を取得する

select a.*
from nodes a
join paths b
on a.node_id = b.ancestor
where b.descendant = 11

ノード #6 のサブツリーを削除する必要があります

delete from paths where descendant in
(select descendant from paths where ancestor = 6)
于 2013-10-02T08:26:12.033 に答える
1

私のアプリケーションでは、サブツリー全体を要求する必要はほとんどありません。したがって、o2 の大きな問題から逃れるために、私は 3 層の関連付け/クロージャ テーブル ルックアップを使用します - テーブルに祖先を入力し、子孫は子、親、および祖父母のみに使用します。入力したものを取得することを認識してください。つまり、ストアド プロシージャなしでツリー全体をクエリしないでください。

于 2015-03-26T16:46:11.950 に答える