3

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

私は RDBMS の思考プロセスから抜け出そうとしていますが、この種のスキーマを効率的に実装する方法について頭を悩ますことはできません。

User レコードがあり、彼には多数の SubItemA レコードがあり、これには多数の SubItem B レコードがあるとします。

User
-SubItem A
--SubItem B
...

サブアイテム B に対してクエリを実行する必要があります。このようにネストされている場合に実行するのは効率的ですか? より速くなるように正規化する必要がありますか?

データの重複を使用して、データがネストされ、分離されていると聞いたことがありますが、これはばかげているのでしょうか、それとも場合によっては実際に役立つのでしょうか?

4

4 に答える 4

3

根底にある問題は、パフォーマンスが十分に優れているのはいつですか?

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

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

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

于 2009-03-03T19:36:07.003 に答える
1

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

于 2009-03-04T17:51:19.383 に答える
1

Mnesia についてはよくわかりません。CouchDB を使い始めたばかりですが、CouchDB では、独自のカスタム インデックス (「ビュー」) を生成するため、それらのサブにインデックスを簡単に構築できると理解しています。アイテム。

マップ関数の例:

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 の索引付けされたリストであり、選択したとおりにそのリストから切り取って接合することができます。

于 2009-03-04T17:55:01.247 に答える
0

実際には、使用しているデータベースに依存すると思います。CouchDB では 1 つのことがうまく機能し、Mnesia では別のことがうまくいきます。データを分割してシャーディングする必要がありますか? どのような基準でそうすべきですか?どの程度のデータ複製で十分ですか?

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

于 2009-05-08T03:36:03.530 に答える