「FKを親に置く」メソッド があります。つまり、各レコードはその親を指します。
読み取りアクションは難しいが、保守は非常に簡単です。
そして、「ディレクトリ構造キー」メソッドがあります:
0001.0000.0000.0000 main branch 1
0001.0001.0000.0000 child of main branch one
etc
これは非常に読みやすいですが、保守が困難です。
他の方法とその短所/長所は何ですか?
いつものように、最善の解決策はありません。各ソリューションにより、さまざまなことが簡単または難しくなります。最適なソリューションは、どの操作を最も多く行うかによって異なります。
parent-idを使用した単純なアプローチ:
長所:
実装が簡単
大きなサブツリーを別の親に簡単に移動できます
挿入は安い
SQLで直接アクセスできる必要なフィールド
短所:
ツリー全体を取得するのは再帰的であるため、費用がかかります
すべての親を見つけることも高価です(SQLは再帰を知りません...)
変更された先行予約ツリー走査(開始点と終了点の保存):
長所:
ツリー全体を取得するのは簡単で安価です
すべての親を見つけるのは安い
SQLで直接アクセスできる必要なフィールド
ボーナス:親ノード内の子ノードの順序も保存します
短所:
各ノードでのパスの保存:
長所:
すべての親を見つけるのは安い
ツリー全体を取得するのは簡単です
挿入は安い
短所:
ツリー全体を移動するのは高価です
パスを保存する方法によっては、SQLで直接操作することはできないため、変更する場合は常にフェッチして解析する必要があります。
データが変更される頻度に応じて、最後の2つのいずれかを選択します。
これは、非再帰関数(通常は1行のSQL)を使用してデータベースからツリーを取得する方法ですが、更新するのが少し難しくなります。
Sitepointの記事のセクション2 データベースへの階層データの保存 詳細.
階層データ構造を保存する「黄金の方法」は、階層データベースを使用することです。たとえば、HDBなど。これは、ツリーを非常にうまく処理するリレーショナルデータベースです。より強力なものが必要な場合は、LDAPが役立ちます。
SQLデータベースは、この抽象的なトポロジには適していません。
リレーショナルデータベースを使用してツリー構造を構築するのは難しいとは思いません。
ただし、この目的にはオブジェクト指向データベースの方がはるかに優れています。
オブジェクト指向データベースの使用:
parent has a set of child1
child1 has a set of child2
child2 has a set of child3
...
...
オブジェクト指向データベースでは、この構造を非常に簡単に構築できます。
リレーショナルデータベースでは、親に対する外部キーを維持する必要があります。
parent
id
name
child1
parent_fk
id
name
child2
parent_fk
id
name
..
基本的に、ツリー構造を構築している間に、これらのすべてのテーブルを結合する必要があります。または、テーブルを反復処理できます。
foreach(parent in parents){
foreach(child1 in parent.child1s)
foreach(child2 in child1.child2s)
...