2011-01-25 12 views
3

性能向上のため、リレーショナルDBからMongoDBへの移行に興味があります。私は複数の場所に冗長化された非正規化データを格納し、アプリケーションコードなしでデータの整合性を自動的に維持できるかどうか疑問に思っています。例えばMongoDB - データの完全性を自動的に維持

私は、ユーザーのドキュメント...

User: { _id: "...", userName: "johndoe", displayName: "John Doe", TotalTasks: 3 } 

し、タスクの文書を持っている場合は、...

Task: { _id "...", title: "Finish Reports", userID: "...", userName: "johndoe", userDiplayName: "John Doe" } 

にはどうすれば自動的にユーザ名とのdisplayNameが同じとどまることを確実にすることができます適切な書類に?このユーザーに対して新しいタスクが追加または削除されたときに、TotalTask​​sが更新されるようにするにはどうすればよいですか?

+1

NoSQLの原則に従ってスキーマを再設計する必要があります。可能であれば、タスクはユーザー文書に埋め込まれなければなりません。私はあなたの質問に受け入れた答えが実際にそれに適切に答えるとは思わない。 –

答えて

4

これらの制約をサーバー側で実行することはできません。ただし、トリガーはplannedです。現在サポートされている唯一の制約は、一意のインデックスです。

+0

私はCouchDDがどのように動作するかのような、自動更新マテリアライズドビューのようなものを望んでいました。私はこれが私が見つけることができる最高のソリューションだと思います。 –

0

MongoDBで外部アプリケーションコーディングを行わずに適用することはできません。上記の質問の1つは、タスクをユーザー文書の一部にするのはなぜですか?これにより、ユーザーとタスクをアトミックに処理できるようになり、一貫性の問題が解消されます。

しかし、私が過去に行ったことは、一貫性を維持するためにMySQLとバージョンフィールドを使用することです。それぞれのアプリケーションは異なりますが、基本的な要点は次のとおりです。

1)Mongoの各ドキュメントには、MySQLに関連する行があります。 MySqlのこの行にはコレクション、ドキュメントのID、監査情報(最後に変更された人、変更された人など)が入ります。 2)ロックする必要があるドキュメントを特定し、mysqlでシリアライズ可能なトランザクションを作成します。 3)検索と更新を使用してmongoのレコードを更新し、バージョンフィールドが一致して楽観的な並行処理を実行するようにします。 4)すべてが完了したら、mysqlでトランザクションをコミットします。 5)何か問題が生じた場合は、完了したmongoのすべての操作をロールバックします。ロールバックが完了できない場合は、情報をロールバックしてメッセージキューに入れ、別のプロセスで「クリーンアップ」します。 6)mysqlトランザクションをロールバックする

これは、操作に大きなオーバーヘッドが加わるため、これは控えめに使用する必要がありますが、ユーザー - >タスクで説明したように文書を埋め込むと、あなたは実際にはいくつかの外部のケースや一括更新を除いてこれを使う必要はありません。

+0

簡単な質問:すべてのタスクをユーザー文書の一部にする場合は、ユーザーの電子メールアドレスを取得するときなど、ユーザーの属性(実際のタスクではない)が必要なたびに電子メールを送っても、Mongoが1000sものタスクを含む文書全体を取得するため、これは大きなオーバーヘッドを引き起こすことはありませんか?それとも単にクエリを実行するだけですか? – o1iver

+0

これは問題だと思うのですが、ユーザー文書のすべてのタスクのオブジェクトIDを保存するだけですが、特定のユーザーのタスクを取得するために2つのクエリを実行する必要があります。 (私はまもなくMongoと遊んだので、どちらの場合も非常に間違っているかもしれません) – o1iver

関連する問題