2012-01-13 13 views
5

この質問はNoSQLと特にmongoDB専門家のためのものです。私はプロジェクトのリレーショナルDBを設計することから始めましたが、クライアントは簡単に拡張できるDBを使用したいと考えています。これを達成するために、mongoDBを使用することに決めました。最近、NoSQLのリレーショナルモデルのマッピングに問題があります。私は、次に示すように、他のテーブルの多くの多対多の関係を持っているユーザーテーブルを持っている:NoSQLデータベースとの関係

relational DB

MongoDBのためにそれを変換するとき、私はいくつかのオプションがあります:

オプション1(ユーザーが完全な行を持つ):(ユーザーが唯一の外部キーを持つ)

users:{ 
    _id:<user_id>, 
    battles:{[battle1, battle2, ...]}, 
    items:{[item1, item2, ...]}, 
    locations:{[location1, location2, ...]}, 
    units:{[unit1, unit2, ...]}, 
} 

battles:{ 
    <battle_info> 
} 

locations:{ 
    <location_info> 
} 

units:{ 
    <units_info> 
} 

items:{ 
    <items_info> 
} 

オプション2:

users:{ 
    _id:<user_id>, 
    battles:{[battle1_id, battle2_id, ...]}, 
    items:{[item1_id, item2_id, ...]}, 
    locations:{[location1_id, location2_id, ...]}, 
    units:{[unit1_id, unit2_id, ...]}, 
} 

battles:{ 
    <battle_info> 
} 

locations:{ 
    <location_info> 
} 

units:{ 
    <units_info> 
} 

items:{ 
    <items_info> 
} 

オプション3(他のテーブル内のユーザID):私たちは他のテーブルの完全な行を追加しているよう

users:{ 
    _id:<user_id>, 
} 

battles:{ 
    <battle_info>, 
    user:{[user1_id, user2_id, ...]} 
} 

locations:{ 
    <location_info>, 
    user:{[user1_id, user2_id, ...]} 
} 

units:{ 
    <units_info>, 
    user:{[user1_id, user2_id, ...]} 
} 

items:{ 
    <items_info>, 
    user:{[user1_id, user2_id, ...]} 
} 

オプション1は、重複をたくさん持っています。私が見ている問題の1つは、特定のアイテムやバトルが更新された場合、それをユーザーのテーブルですべて見つけて更新する必要があるということです。しかし、これは、ログイン時にクライアントアプリケーションに渡すことができる完全なユーザーオブジェクトを常に持つという利点をもたらします。

オプション2は、ユーザーテーブル内に他のテーブルのmongoIdsしか持たない場合、よりリレーショナルです。このオプションの利点は、バトルやアイテムの更新には、行がコピーされずに参照されるため、コストがかからないことです。一方、ユーザーがログインすると、完全なユーザーオブジェクトで応答するすべての参照単位、戦闘、アイテム、および場所を見つける必要があります。

オプション3は、ユーザーテーブルのmongoIdsが他のテーブルに保持されているオプション2とは反対です。このオプションは私にはあまり魅力がありません。

私は本当にありがとうと思います。

編集:

基本的にこれは、複数のクライアントアプリケーションがWebサービスを介してサーバーに接続するMMORPGゲームです。私たちはクライアントにデータを保存するためのローカルデータベースを持っています。サーバーが完全なユーザーオブジェクトで応答し、クライアントアプリケーションで変更されたデータを更新または挿入できるモデルが必要です。

+0

"better"は目的の問題です。このデータへのあなたのアクセスパターンは何ですか? –

+0

基本的にこれはmmorpgゲームで、複数のクライアントアプリがwebservicesを介してサーバーに接続します。私たちはクライアントにデータを保存するためのローカルデータベースを持っています。サーバーが完全なユーザーオブジェクトで応答し、クライアントアプリケーション上で変更されたデータを更新または挿入するためのモデルが必要です – umair

+8

リレーショナルデータベースではスケーリングが可能です...違いは、保持することが予想されるデータの種類、 RDBが小規模なデータのためだけであるという誤った先入観ではなく、大きいためのmongodb –

答えて

5

まず:

さえ10genは、 "手動" 参照IDを使用することをお勧めします。 SQLでは、ほぼ1:NとM:Nの関係が同じ方法でモデル化されます。 NoSQLの哲学は、データをモデル化する方法は、データとその使用パターンに依存するということです。

第2に、私はMark Ba​​kerに同意します:スケーリングは難しく、制約を緩めることで実現します。技術的な問題ではありません。私はMongoDBのでの作業が大好きですが、他の理由(醜いSQLをコーディングする必要はありません;複雑、肥大化したORMの必要がない、など)のための

今度は、あなたのオプションを検討してみましょう:必要以上に オプション1枚のコピーより多くのデータ。あなたは多くの場合、のデータを非正規化する必要がありますが、すべてのデータを正規化する必要はありません。もしそうなら、参照されたオブジェクトをフェッチするほうが安いです。

オプション2/3非常に似ています。ここの鍵は誰ですか?同じ文書への書き込みアクセス権を持つ多くのクライアントは、ロック機構を使用したり、修飾子操作のみに制限したりする必要があります。したがって、オプション2はおそらく3より優れています。しかし、AがBを攻撃すると、ユーザーBへの書き込みも開始されるため、書き込みが安全であることを確認する必要があります。

オプション4一部非正規化:あなたのユーザーオブジェクトは、最も重要であると思われるので、これについてはどのように:

user { 
battles : [ {"Name" : "The battle of foo", "Id" : 4354 }, ... ] 
... 
} 

これは、それが簡単に表示するようになります例えばダッシュボード内のすべての詳細を知る必要がないため、ユーザーダッシュボードです。注:データ構造はプレゼンテーションの詳細に結合されます。

オプション5エッジのデータ。多くの場合、関係は同様にデータを保持する必要がある:ここで

user { 
battles : [ {"Name" : "The battle of foo", "unitsLost" : 54, "Id" : 34354 }, ... ] 
} 

unitsLostは、ユーザとの戦いに特異的であり、したがってデータは、グラフの端に座っています。バトルの名前とは対照的に、このデータは非正規化されていません。

オプション6リンカーコレクション。もちろん、そのような「エッジデータ」は巨大になり、別のコレクション(リンカーコレクション)を呼び出す可能性もあります。これにより、アクセスロックの問題を完全に排除します。

user { 
    "_id" : 3443 
} 

userBattles { 
    userId : 3443, 
    battleId : 4354, 
    unitsLost : 43, 
    itemsWon : [ <some list > ], 
    // much more data 
} 

これらは、アプリケーションの多くの詳細によって異なります。ユーザーがたくさんのクリックをした場合(つまり、きめ細かなインターフェイスがある場合)、オプション4や6のようにオブジェクトを分割するのが理にかなっています。すべてのデータが本当に1つのバッチに必要な場合、部分的な非正規化は役に立ちませんオプション2が望ましいでしょう。複数のライターの問題を覚えておいてください。

+1

詳細な回答ありがとうございます。興味深いことに、すべての多対多リレーションがNoSQLで同じ構造を持つわけではありません。私は自分の必要に応じてそれらを構造化しなければならないと思う。 – umair

1

オプション2は行く方法です。

RDBで行う場合は、ある時点で(水平方向のスケーリングを開始する必要がある場合)、SQL結合を削除してアプリケーションレベルでデータを結合する必要があります。 NoSQLのはない 1フリーサイズで、http://www.mongodb.org/display/DOCS/Database+References

関連する問題