web-dev-qa-db-ja.com

ディレクトリ/階層/ツリー構造をデータベースに保存する方法は?

ディレクトリ/階層/ツリー構造をデータベースに保存するにはどうすればよいですか?つまり、MSSQL Server。

@olavk:私の答えを見たようには見えません。私が使用する方法は、再帰クエリよりも優れています:)

p.p.s. これは 行く方法!

56
roman m

SQLデータベースに階層を保存する 多くの方法 があります。どちらを選択するかは、使用するDBMS製品とデータの使用方法によって異なります。 MSSQL2005タグを使用したので、「隣接リスト」モデルの検討を開始する必要があると思います。アプリケーションでうまく機能しない場合は、 Vadim Tropashkoの比較 をご覧ください。複数のパフォーマンス特性に焦点を当てたモデル間の違いを強調しています。

18
Troels Arvin

Sql Server 2008を使用するオプションがある場合:多分、新しい hierarchyid データ型をチェックアウトする必要があります。

8
Rockcoder

また、ParentIDモデルに比べていくつかの利点があるツリーのネストセットモデルもあります。 http://www.evanpetersen.com/item/nested-sets.html および http://falsinsoft.blogspot.nl/2013/01/tree-in-sql-を参照してくださいdatabase-nested-set-model.html

5
Lars Truijens

これは質問というよりもブックマークのようなものですが、あなたにも役立つかもしれません。 この記事の アプローチを使用して、データベースにディレクトリ/ツリー構造を保存しました。

記事にはいくつかの便利なコードスニペットもあります。

お役に立てれば。

私はそのウェブサイトとは一切関係ありません

4
roman m

SQL Server 2005を使用していますか? 再帰クエリ 階層データのクエリをよりエレガントにします。

編集:マテリアライズドパスはちょっとしたハックだと思います。パスには正規化されていない冗長データが含まれており、トリガーなどを使用してそれらを更新し続ける必要があります。例えば。ノードが親を変更する場合、サブツリー全体のパスを更新する必要があります。また、サブツリークエリは、エレガントで高速な結合ではなく、someいサブストリングマッチングを使用する必要があります。

3
JacquesB

質問は this question に似ていて、閉じられました。私は両方の質問への回答が私の追跡に非常に役立つことを発見し、最終的にはツリー構造をモデル化する5つの異なる方法を提示するMongoDBマニュアルに導きました: https://docs.mongodb.com/manual/applications/data -models-tree-structures /

MongoDBはリレーショナルデータベースではありませんが、提示されているモデルはリレーショナルデータベースやJSONなどの他の形式に適用できます。提示された賛否両論に基づいて、どのモデルが正しいかを明らかにする必要があります。

この質問の著者は、親と実体化されたパスの両方のモデルを組み合わせた solution を見つけました。深さと親を維持すると、いくつかの問題(余分なロジック、パフォーマンス)が生じる可能性がありますが、特定のニーズには明らかに利点があります。私のプロジェクトでは、マテリアライズドパスが最適に機能し、 this の記事のテクニックを使用していくつかの問題(ソートとパスの長さ)を克服しました。

2
Andrew

私は自分のプロジェクトの1つで同様の問題に直面しました。私たちには永遠に増え続ける巨大な階層がありました。私はそれを素早く横断し、いくつかの複雑な検証の後に適切なグループを見つける必要がありました。再帰クエリが唯一の実行可能なソリューションであることを知ったときに、SQL Serverに行って頭を掻くのではなく、どうすれば効率的にそれを行うことができますか。しかし、再帰クエリで可能な限り最適化があるかどうかを本当に知っていますか?階層が将来増加しないという保証はありますか?また、ある日、再帰クエリが実稼働で使用するには遅すぎることが判明したという保証はありますか?

だから、私はNeo4Jにショットを与えることにしました。これは、多くの有用なアルゴリズムが組み込まれたグラフデータベースであり、適切なドキュメントと例があり、驚くほど高速に走査されます。 Neo4Jに階層を保存し、Thriftサービス(または他の何か)を使用して階層にアクセスします。はい。SQLクエリをNeo4Jに統合するコードを記述する必要がありますが、スケーラブルで将来性のあるソリューションが得られます。

これが役立つことを願っています。

2
Marut Singh

典型的な方法は、外部キー(例:「ParentId」)を自身に持つテーブルです。

1
Sklivvz