ディレクトリ階層/ツリーをKey-Valueデータベース(私の場合はMongoDBですが、それらのいずれか)に格納するためのクリーンで効率的な方法は何ですか?
たとえば、ツリー構造
- Cars
+ Audi
+ BMW
- M5
+ Ford
- Color
+ Red
- Apple
- Cherry
+ Purple
- Funny
私が現在使用しているメソッドでは、各オブジェクトはその親にリンクしています
{
dir: "red"
parent-dir: "color"
}
これにより、ツリーの任意の側面を挿入して並べ替えることが非常に効率的/高速になります(たとえば、Redとそのすべての子をCarsディレクトリに移動する場合)。
しかし、この方法は、特定のディレクトリのすべてのサブディレクトリとその子を再帰的に処理したい場合には役に立ちません。解析を効率的にするために、たとえば構造を持つことができます
{
dir: "red"
children: "audi, bmw, ford"
}
{
dir: "bmw"
children: "m5"
}
しかし、ツリーを変更したい場合は、たくさんのオブジェクトに触れて変更する必要があります。
KVストアにディレクトリ構造を保存する他の方法はありますか?
現在使用しているメソッドは 隣接リストモデル と呼ばれます。
階層データを(リレーショナル)データベースに格納する別のモデルは、 入れ子集合モデル です。その SQLデータベースでの実装はよく知られています 。 変更されたプレオーダーツリートラバーサルアルゴリズムに関するこの記事 も参照してください。
非常に単純な方法:オブジェクトごとにパスを格納できます。これらを使用すると、NOSQLデータベースのツリーを簡単にクエリできます。
{ path: "Color", ... }
{ path: "Color.Red", ... }
{ path: "Color.Red.Apple", ... }
{ path: "Color.Red.Cherry", ... }
ノードが削除または名前変更されるときは、いくつかのパスを更新する必要があります。しかし、一般的に、この方法は有望に見えます。区切り文字として特殊文字を予約する必要があります。ストレージスペースのオーバーヘッドはごくわずかです。
編集:このメソッドは マテリアライズドパスと呼ばれます
最後に、 NOSQLデータベースの階層データのさまざまな方法の比較 です。
私はNOSQLの経験があまりないので、これは決定的な答えではありませんが、次のようにアプローチします。
私はおそらくあなたが持っているあなたの最初のアプローチを使うでしょう:
{
dir: 'dir_name',
parent_dir: 'parent_dir_name'
}
次に、map-reduceを設定して、ディレクトリの子をすばやくクエリします。 MongoDBのmap-reduce機能はまだ開発ブランチでのみ利用可能であり、私はまだそれを使用していませんが、CouchDBでは(そして、いくつかの変更を加えて、MongoDBで)次のようなことができます。
map:
function(doc) {
emit( doc.parent_dir, doc.dir );
}
reduce:
function(key, values) {
return( values );
}
これにより、各親ディレクトリのサブディレクトリのリストが表示されます。