[解決済み】MongoDBがv4以前にACID準拠でなかったことの本当の意味は?
質問
私はデータベースの専門家ではなく、正式なコンピュータサイエンスのバックグラウンドもないので、ご容赦ください。 私は、どのような 実世界 を使用した場合に起こる可能性のある否定的な事柄。 v4以前のMongoDBバージョン でなかったもの。 ACID に準拠している。 これは、ACID非対応のデータベースにも適用されます。
MongoDBは、以下のようなことができるそうですね。 アトミック操作 しかし、伝統的なロックと複雑なトランザクションはサポートしていません。 また、データベーストランザクションの重要性も理解しています。例えば、データベースが銀行用で、すべてが同期している必要がある複数のレコードを更新している場合、停電があった場合にトランザクションを初期状態に戻し、信用が購入と等しくなるようにしたい、等々です。
しかし、MongoDBの話になると、データベースが実際にどのように実装されているかという技術的な詳細を知らない私たちは、次のような発言を投げかけるようになります。
MongoDBはMySQLやPostgresよりずっと高速ですが、100万分の1の確率で、"正しく保存されない"ことがあります。
この「正しく保存されない」というのは、こういう理解のことです。MongoDB に書き込んだ瞬間に停電になった場合、特定のレコード(たとえば 10 個の属性を持つドキュメントでページビューをトラッキングしている場合)には、ドキュメントの 1 つに 5 個の属性しか保存されていない可能性があります... つまり、ページビューカウンターは時間とともに "slightly" ずれていくのです。 つまり、時間の経過とともに、ページビューカウンターは少しずつずれていくことになります。 というのも、特別に mongodbアトミック操作 この操作はアトミックであることが保証されていません。
そこで質問ですが、MongoDBが"save correctly"しない場合があるのはいつ、なぜなのか、正しい解釈は何でしょうか。 ACIDのどの部分を満たさないのか、どんな状況なのか、そしてその0.001%のデータが外れたときにどうやって知ることができるのか? これはどうにかして直せないのでしょうか? もしそうでなければ、これは、あなたの
users
というのも、レコードが保存されないことがあるからです。 でも、1/1,000,000のユーザーは、もう一度サインアップしてみる必要があるかもしれませんね。
私はただ、MongoDBのようなACID非準拠のデータベースでネガティブなことがいつ/なぜ起こるのか、そして理想的には標準的な回避策(データをクリーンアップするバックグラウンドジョブの実行や、このためにSQLのみを使用するなど)があるかどうかをリストアップしたいと思っています。
解決方法は?
MongoDBで失うもののひとつに、マルチコレクション(テーブル)トランザクションがあります。 MongoDB のアトミック修飾子は、ひとつのドキュメントに対してしか使えません。
もし、ある商品を在庫から取り除くのと同時に、誰かの注文に追加する必要があるのなら、それはできません。 在庫と注文という2つのものが同じドキュメントに存在しない限り(おそらく存在しないでしょう)。
私が取り組んでいるアプリケーションでも、これとまったく同じ問題に遭遇し、2つの解決策から選択することになりました。
1) ドキュメントをできる限り構造化し、できる限りアトミック修飾子を使用する。残りのビットについては、同期していない可能性のあるレコードをクリーンアップするためにバックグラウンドプロセスを使用する。 例えば、インベントリからアイテムを削除し、アトミックモディファイアを使って同じドキュメントのreservedInventory配列に追加しています。
これにより、(顧客によって予約されたため)在庫がないことを常に把握することができます。 顧客がチェックアウトするとき、私はreservedInventoryからアイテムを削除します。 これは標準的なトランザクションではなく、顧客がカートを放棄する可能性があるため、放棄されたカートを見つけ、予約された在庫を利用可能な在庫プールに戻すためのバックグラウンド処理が必要です。
これは明らかに理想的ではありませんが、大規模なアプリケーションの中でmongodbが完璧にニーズに合わない唯一の部分です。 それに、今のところ完璧に動作しています。 これは多くのシナリオで可能ではないかもしれませんが、私が使っているドキュメント構造のため、うまくフィットしています。
2)トランザクションデータベースをMongoDBと併用する。 絶対に必要なものにはMySQLを使ってトランザクションを提供し、MongoDB(または他のNoSQL)には得意なことをさせるというのが一般的です。
もし1の解決策が長期的にうまくいかない場合は、MongoDBとMySQLの組み合わせについてさらに調査するつもりですが、今のところ1の解決策が私のニーズに合っています。
関連
-
[解決済み] 3を挿入すると「ORA-01438: この列で許容される指定精度より大きい値」と表示される。
-
[解決済み】使用されるSELECT文は列の数が異なる(REDUX!)
-
[解決済み】ORA-01791: SELECTされた式ではない
-
[解決済み] ''付近の構文が正しくない
-
[解決済み] INSERT ステートメントが FOREIGN KEY 制約と競合する - SQL Server
-
[解決済み] SQLクエリで2つの列から値を引き算する
-
[解決済み] 列名または提供された値の数がテーブル定義と一致しません。
-
[解決済み] SQLでchar値をmoneyに変換できない
-
[解決済み] オペランド型の衝突:uniqueidentifierはintと互換性がない
-
[解決済み] MongoDBのリレーションシップ:埋め込みか参照か?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】2つの列を分割する方法は?
-
[解決済み】一括読み込みデータ変換エラー(指定されたコードページに対して型の不一致または無効な文字)1行目4列目(年)について)
-
[解決済み】SQL Server: 無効なカラム名
-
[解決済み] DELETE文の競合REFERENCE制約
-
[解決済み] ORA-00920: 無効な関係演算子
-
[解決済み] SQL Server - INNER JOIN WITH DISTINCT
-
[解決済み] ORA-00918: 列があいまいに定義されています」を解決する方法
-
[解決済み] PostgreSQL - json 型の等値演算子を識別できませんでした。
-
[解決済み] マルチパート識別子をバインドできなかった
-
[解決済み] VBA - ADODB.CommandTextの実行