25

マイクロブログタイプのアプリケーションがあります。ゼロ化された2つの主要な基本データベースストアは、MySQLまたはMongoDBです。

大量のデータを非正規化することを計画しています。つまり、投稿に対して行われた投票は投票テーブルに保存され、メインの投稿テーブルでもカウントが増加します。投稿に関連する他のアクションもあります(たとえば、「いいね」、投票する)。

MySQLを使用する場合、検索を高速化するために、一部のデータは固定スキーマよりもJSONに適しています。

例えば

POST_ID   |  activity_data

213423424 | { 'likes': {'count':213,'recent_likers' :
             ['john','jack',..fixed list of recent N users]} , 'smiles' : 
             {'count':345,'recent_smilers' :
             ['mary','jack',..fixed list of recent N users]}  }

アプリケーションの他のコンポーネントもあり、JSONの使用が提案されています。したがって、JSONフィールドを更新するためのシーケンスは、次のとおりです。

  1. PythonスクリプトでJSONを読み取ります。

  2. JSONを更新します

  3. JSONをMySQLに保存します。

これは、、など$pushのアトミック操作を使用したMongoDBでの単一操作でした。また、MongoDBのドキュメント構造も私のデータに適しています。$inc$pull

データストアを選択する際の私の考慮事項。

MySQLについて:

  1. 安定しておなじみ。
  2. バックアップと復元は簡単です。
  3. 一部のフィールドをスキーマレスJSONとして使用すると、将来のスキーマ変更を回避できます。
  4. 早期にmemcachedのレイヤーを使用する必要がある場合があります。
  5. JSON BLOBは、メインの投稿などの一部のテーブルでは静的になりますが、投稿の投票やいいねなどの他のテーブルでは多く更新されます。

MongoDBについて:

  1. スキーマの少ないデータをドキュメントとして保存するのに適しています。
  2. キャッシングは後の段階まで回避される可能性があります。
  3. アプリが書き込みを多用する場合がありますが、MongoDBは、安全でない書き込みが問題にならないポイントでパフォーマンスを向上させることができます。
  4. 安定性と信頼性についてはよくわかりません。
  5. バックアップと復元がどれほど簡単かわからない。

質問:

  1. データの半分がスキーマレスで、MySQLを使用している場合はJSONとして保存されている場合は、MongoDBを選択しますか?
  2. メインの投稿などの一部のデータは重要であるため、安全な書き込みを使用して保存され、カウンターなどは安全でない書き込みを使用して保存されます。このポリシーはデータの重要性に基づいており、書き込みの集中度は正しいですか?

  3. MySQLと比較して、MongoDBの監視、バックアップ、および復元はどのくらい簡単ですか?定期的なバックアップ(たとえば毎日)を計画し、災害時に簡単に復元する必要があります。アプリケーションにとって安全な賭けにするために、MongoDBで私が持っている最良のオプションは何ですか。

安定性、バックアップ、スナップショット、復元、幅広い採用Iedatabaseの耐久性は、NoSQLドキュメントストレージが私の目的をよりよく果たすことができたとしても、MySQLをRDBMS+NoSqlとして使用するように私に指示する理由です。

私が考えているデータベース設計を考慮して、MySQLとMongoDBのどちらを選択するかに焦点を当ててください。RDBMSまたはMongoDBドキュメントのいずれかを使用してデータベース設計を計画するためのより良い方法があるかもしれないことを私は知っています。しかし、それは私の質問の現在の焦点では​​ありません。

更新:MySQL 5.7以降、MySQLは豊富なネイティブJSONデータ型をサポートし、データの柔軟性と豊富なJSONクエリを提供します。

https://dev.mysql.com/doc/refman/5.7/en/json.html

4

3 に答える 3

22

だから、質問に直接答えるには...

データの半分がスキーマレスであり、MySQL を使用している場合に JSON として保存されている場合、mongodb を選択しますか?

スキーマレス ストレージは確かに MongoDB を使用する説得力のある理由ですが、ご指摘のとおり、JSON を RDBMS に格納することもかなり簡単です。MongoDB の背後にある力は、スキーマレス ストレージに対する豊富なクエリにあります。

JSON フィールドの更新に関する図の小さな欠陥を指摘するとしたら、それは単に現在の値を取得し、ドキュメントを更新してからデータベースにプッシュするだけの問題ではありません。プロセスはすべてトランザクションでラップする必要があります。データベースの非正規化を開始するまで、トランザクションはかなり単純な傾向があります。次に、賛成票を記録するのと同じくらい簡単なことで、スキーマ全体のテーブルをロックできます。

MongoDB では、トランザクションはありません。しかし、操作はほとんどの場合、アトミックな更新を可能にする方法で構造化できます。これには通常、SQL パラダイムからの劇的な変化が伴いますが、私の意見では、オブジェクトをテーブルに強制的に入れようとするのをやめれば、それはかなり明白です。少なくとも、他の多くの人々があなたが直面するのと同じ問題に遭遇しており、Mongo コミュニティはかなりオープンで、彼らが克服した課題について声を上げる傾向があります。

メインの投稿などの一部のデータは重要であるため、安全な書き込みを使用して保存され、カウンターなどは安全でない書き込みを使用して保存されます。このポリシーはデータの重要性と書き込み集中度に基づいていますか?

「安全な書き込み」とは、書き込みのたびに自動「getLastError()」をオンにするオプションを意味すると思います。getLastError() が呼び出されるタイミングをきめ細かく制御できる DBCollection の非常に薄いラッパーがあります。ただし、私たちのポリシーは、データが「重要」であるかどうかに基づいているのではなく、クエリに続くコードが、次の読み取りで変更がすぐに表示されることを期待しているかどうかに基づいています。

一般的に言えば、これはまだ不十分な指標であり、代わりに同じ動作のために findAndModify() に移行しました。getLastError() を明示的に呼び出す場合は、重複している可能性のある _id を使用して insert() する場合など、データベースが書き込みを拒否する可能性が高い場合です。

mysql と比較して、Mongodb の監視、バックアップ、および復元はどれくらい簡単ですか? 定期的なバックアップ (たとえば毎日) を計画し、災害が発生した場合に簡単に復元する必要があります。アプリケーションにとって安全な賭けにするために、mongoDb で私が持っている最良のオプションは何ですか?

残念ながら、まだ復元する必要がなかったため、バックアップ/復元ポリシーが有効かどうかについて話すことはできません. バックアップに関する MongoDB の推奨事項に従っています。@mark-hillick は、それらを要約する素晴らしい仕事をしてくれました。レプリカ セットを使用しており、MongoDB のバージョンを移行し、新しいレプリカ メンバーを導入しました。これまでダウンタイムはなかったので、ここまでうまく話せるかどうかわかりません。

安定性、バックアップ、スナップショット、復元、より広い採用、つまりデータベースの耐久性が、MySQL を RDBMS+NoSql として使用する理由です。NoSQL ドキュメント ストレージの方が私の目的には適しています。

したがって、私の経験では、MongoDB はスキーマのないデータのストレージを提供し、一連のクエリ プリミティブを豊富に備えているため、トランザクションをアトミック操作に置き換えることができます。10 年以上の SQL の経験を捨てるのは大変でしたが、私が遭遇したすべての問題は、コミュニティまたは 10gen によって直接対処されました。データが失われたり、ダウンタイムが発生したりしたことはありません。

簡単に言うと、MongoDB は、クエリ、メンテナンス、スケーラビリティ、および信頼性の点で、私がこれまでに使用した中で最高のデータ ストレージ エコシステムです。明らかにリレーショナルなアプリケーションで SQL 以外を良心的に使用できない場合を除いて、私は MongoDB を使用するためにあらゆる努力をします。

私は 10gen で働いていませんが、働いている人たちにはとても感謝しています。

于 2012-10-22T22:25:57.233 に答える
13

比較についてコメントするつもりはありません (私は 10gen で働いており、そうするのが適切だとは思いません) が、特定の MongoDB の質問に答えて、より適切な決定ができ​​るようにします。

バックアップ

ここのドキュメントは非常に詳細で、多くの側面をカバーしています。

  • ブロックレベルのメソッド (LVM は非常に簡単で、多くの人がこれを行っています)
  • ジャーナリングあり/なし
  • EBS スナップショット
  • 一般的なスナップショット
  • レプリケーション (技術的にはバックアップではありませんが、多くの人が冗長性とバックアップのためにレプリカ セットを使用しています - これは推奨されていませんが、実行されています)

最近まで、MongoDB に相当するものはありませんでしmylvmbackupたが、いい人が書きました :) 彼の言葉で

これまでの初期の段階: これは単なる美化されたシェル スクリプトであり、さらに多くのエラー チェックが必要です。しかし、すでにそれは私にとってうまくいっているので、喜びを分かち合いたいと思いました. バグレポート、パッチ、提案を歓迎します。

ここからコピーを入手してください。

復元する

mongodumpここに完全に文書化されており、mongorestore はここにあります。

mongodumpインデックスは含まれませんが、system.indexes コレクションが含まれているため、bson ファイルを復元するときに mongorestore がインデックスを再構築できます。bsonファイルは実際のデータですが、mongoexport/mongoimportタイプセーフではないため、何でもかまいません(技術的に言えば):)

モニタリング

ここに文書化されています。

私は Cacti が好きですが、私の知る限り、Cacti テンプレートは MongoDB の変更に追いついていないため、古い構文に依存しているため、2.0.4 以降では問題があると思います。

Nagios はうまく機能しますが、それは Nagios であるため、好きか嫌いかのどちらかです。多くの人々が Nagios を使用しており、それは彼らに素晴らしい可視性を提供しているようです.

Zappix を見ている人の話を聞いたことがありますが、使用したことがないのでコメントできません。

さらに、外部でホストされている無料の MMS を使用することもできます。MongoDB インスタンスはエージェントを実行し、それらのエージェントの 1 つが (python コードを使用して) https 経由で mms.10gen.com と通信します。MMS を使用して MongoDB インスタンスのすべてのパフォーマンス統計を表示します。これは、ドリルダウン機能を提供するだけでなく、高レベルの全体像から非常に有益です。インストールは簡単で、ハードウェアを実行する必要はありません。多くの顧客がそれを実行しており、一部の顧客は Cacti/Nagios でそれを補完しています。

MMS に関するヘルプ情報は、ここにあります(非常に詳細で包括的なドキュメントです)。

于 2012-10-17T16:08:01.820 に答える
5

json を保存した mysql ソリューションの欠点の 1 つは、json データを効率的に検索できないことです。すべてをmongodbに保存すると、jsonを含むすべてのデータに対してインデックスやクエリを作成できます。

Mongo の書き込みは非常にうまく機能し、実際に mysql と比較して失われるのはトランザクションのサポートだけであり、したがってマルチパート セーブをロールバックする機能です。ただし、アトミック操作で変更をコミットできる場合は、データの安全性の問題はありません。レプリケートされている場合、mongo は、スレーブが最終的にマスターをミラーリングするように、「最終的に一貫した」約束を提供します。

Mongodb は、外部キーなどの特定の db コンストラクトのネイティブな強制またはカスケードを提供しないため、それらを自分で管理する必要があります (mongo の強みの 1 つである構成などによって)、または dbref を使用することによって。

トランザクションのサポートと堅牢な「安全な」書き込みが本当に必要であり、それでも nosql によって提供される柔軟性が必要な場合は、ハイブリッド ソリューションを検討することをお勧めします。これにより、mysql をメインのポスト ストアとして使用し、mongodb を「スキーマレス」ストアとして使用できます。ハイブリッド mongo/rdbms ソリューションについて説明しているドキュメントへのリンクは のとおりです。

2019 年 5 月 28 日更新

この回答が投稿されてから、MySQL と Mongodb の両方に多くの変更が加えられたため、それらの間の長所と短所はさらに曖昧になりました。この更新は元の質問にはあまり役に立ちませんが、新しい読者がもう少し最新の情報を入手できるようにするために行っています。

MongoDB がトランザクションをサポートするようになりました: https://docs.mongodb.com/manual/core/transactions/

MySql は、json フィールドのインデックス作成と検索をサポートするようになりました: https://dev.mysql.com/doc/refman/5.7/en/json.html

于 2012-10-22T21:21:17.543 に答える