キーバリューデータベースのネストされたアイテムを効率的にクエリするためのスキーマをどのように設計しますか?

StackOverflow https://stackoverflow.com/questions/607746

質問

MnesiaをErlangで使用していますが、この質問はcouchdbなどのすべてのキー値データベースに適用されます。

RDBMSの思考プロセスから解放しようとしていますが、できません。 この種のスキーマを効率的に実装する方法について説明します。

ユーザーレコードがあり、彼には多くのSubItemAレコードがあり、 多くのサブアイテムBレコード、したがって:

User
-SubItem A
--SubItem B
...

SubItem Bでクエリを実行する必要があります。 この入れ子?より速くなるように正規化するだけですか?

データの複製を使用している人がいるので、データは両方とも ネストされ、別々に、これはばかげていますか、これは実際に便利ですか ある場合?

役に立ちましたか?

解決

根本的な問題は、パフォーマンスがいつ十分であるかということです

すべてのSubItem Bを詳細に調べる必要があり、Bのサイズがディクショナリ全体のサイズを支配している場合、ユーザー辞書のテーブルスキャンは過度のオーバーヘッドではありません。

それで十分でない場合は、正規化して、SubItem Bを照会するときにすべてのUserおよびSubItem Aデータを読み取らないようにします。(UserId、SubItemAId、SubItemBId)などの複合キーを使用します範囲クエリを実行できるようにテーブルが順序付けられている場合は、サブアイテムBディクショナリ。

それによってユーザー/サブアイテムAのクエリパフォーマンスが完全に低下する場合、エラーが発生しやすいため、データの重複を最後の手段として検討してください。

他のヒント

CouchDbでは、各サブアイテムのビューエントリを発行するのは簡単です。これにより、これらのアイテムに非常に高速にアクセスできます。ビューエントリに入力した内容にもよりますが、おそらく親ドキュメント/サブアイテムにリンクするために必要な情報を提供できます。

Mnesiaについてはわかりませんが、CouchDBを使い始めたばかりですが、CouchDBでは、独自のカスタムインデックス(" views")を生成するので、簡単にインデックスを作成できますそれらのサブアイテム。

マップ関数の例:

function(doc) {
    for(var i in doc.subitems_a) {
        var subitem_a = doc.subitems_a[i];

        for(var j in doc.subitems_a[item_a].subitems_b) {
            var subitem_b = subitem_a.subitems_b[j];

            emit(subitem_b, doc)
        }
    }
}

これは、事実上、サブアイテムBのインデックス付きリストであり、選択すると、そのリストから切り取ってスプライスできます。

実際には、使用しているデータベースによって異なります。 CouchDBでは、Mnesiaでは他の何かが優れているのに対して、1つのことがうまく機能します。データを分割して分割する必要がありますか?どのような基準でこれを行う必要がありますか?どのくらいのデータ複製で十分ですか?

ジェフリー・ハンティンが言ったように、適切な解決策を見つけるためにいくつかの実験と分析が必要です。つまり、ほとんどの非リレーショナルデータベースは、問題を解決するために必要なツールを提供します。あなたの役目は、それぞれのトレードオフと、他のトレードオフに対して受け入れることができるトレードオフを理解することです。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top