MongoDB BSONドキュメントのサイズ制限について


153

MongoDBから決定的なガイド:

4MBを超えるドキュメント(BSONに変換した場合)は、データベースに保存できません。これはやや恣意的な制限です(将来的には引き上げられる可能性があります)。これは主に、スキーマ設計の不良を防ぎ、一貫したパフォーマンスを確保するためです。

私はこの制限を理解していません。これは、たまたま4MBを超える大量のコメントを含むブログ投稿を含むドキュメントを単一のドキュメントとして保存できないことを意味しますか?

また、ネストされたドキュメントもカウントされますか?

値の変更を監査するドキュメントが必要な場合はどうすればよいですか。(最終的には4MBの制限を超えて大きくなる可能性があります。)

誰かがこれを正しく説明してくれることを願っています。

MongoDB(私が学んでいる最初のnosqlデータベース)について読み始めたところです。

ありがとうございました。


5
これは、これがBSON形式ではなく、MongoDB格納ドキュメントサイズの制限であることを明確にする必要があると思います。
alexpopescu

2
ただし、「BSON :: InvalidDocument:ドキュメントが大きすぎます:BSONドキュメントは4194304バイトに制限されています」というメッセージを表示するために、4MBを超える巨大なドキュメントを保存しようとしました。もしそうなら、警告/エラーメッセージで誤解を招くようなものではありませんか?
Nik So

18
シェルのdb.isMaster().maxBsonObjectSize/(1024*1024)+' MB'コマンドを使用して、最大BSONドキュメントサイズを簡単に見つけることができますmongo
AhmetB-Google、2011年

5
16 MBを超えるレコードをダンプできず、その上にクラッド操作を構築できるスキーマレスnosqlの目的は何ですか。
Rizwan Patel

私は最初の引用がそれをすべて言うと思います...悪いスキーマ設計を防ぐために制限が設けられています。たとえば、多くのコメントが含まれる投稿がある場合、ブログエントリコレクションとコメントコレクション、または変更コレクションが必要になります。mongo / nosqlの設計では、ドキュメントのネットワークとして大規模なものが可能ですが、開発者はそれらを意味のある部分に分割する必要があります。サイズ制限が設定されていない場合、他の問題が発生します。4MBの制限は大丈夫だったと思います。16MB、すごい!しかし、16MBのドキュメントを書いている場合、それはデザインに何か他の問題があることの手がかりです。
まつげ

回答:


126

最初に、これは実際には次のバージョン8MBまたは16MB... で上げられていますが、これを展望に入れて考えると、10genのEliot(MongoDBを開発した人)が最適です。

編集: サイズは正式に「引き上げ」られています16MB

したがって、ブログの例では、実際には4MBが大量です。たとえば、「War of the Worlds」の完全な非圧縮テキストは、わずか364k(html)です。http://www.gutenberg.org/etext/36

あなたのブログの投稿がそのように多くのコメントで長くなるなら、私はそれを読むつもりはありません:)

トラックバックの場合、1MBを割り当てると、1万バイト以上(おそらく2万バイト近く)になる可能性があります。

本当に奇妙な状況を除いて、それは素晴らしい働きをします。例外的なケースやスパムの場合は、とにかく20MBのオブジェクトが必要だとは思いません。トラックバックを15k程度に制限することは、パフォーマンスに関係なく、大いに意味があると思います。それが起こるなら、少なくとも特別なケース。

-エリオット

私はあなたが限界に到達するためにかなり難しいと思うと思います...そして、時間が経つにつれて、アップグレードすると...あなたはますます心配する必要がなくなります。

制限の主なポイントは、サーバー上のすべてのRAMを使い果たしないようにすることです(MBクエリを実行するときにドキュメントのすべてのRAMをRAMにロードする必要があるため)。

したがって、制限は、一般的なシステムで通常使用可能なRAMの数%です...これは、年々成長し続けます。

MongoDBへのファイルの保存に関する注意

サイズが大きいドキュメント(またはファイル)を保存する必要16MBがある場合は、GridFS APIを使用して、データを自動的にセグメントに分割し、それらをストリームに戻します(これにより、サイズ制限/ RAMの問題を回避します)。

ファイルを単一のドキュメントに保存する代わりに、GridFSはファイルを複数の部分またはチャンクに分割し、各チャンクを個別のドキュメントとして保存します。

GridFSは2つのコレクションを使用してファイルを格納します。1つのコレクションはファイルチャンクを格納し、もう1つのコレクションはファイルメタデータを格納します。

この方法を使用すると、SQLデータベースと同じように、画像、ファイル、ビデオなどをデータベースに保存できます。これを使用して、数ギガバイトのビデオファイルを保存することもできます。


2
データベース全体に十分なRAMがあることは素晴らしいことです。通常、「ワーキングセット」はデータベース全体ではなくRAMにあります(私の場合、x GBのデータベースが複数あるため、合計するとRAMを超えてしまいます。ただし、ワーキングセットははるかに小さいため、問題ありません。また、制限がない場合は、1つのクエリと400kのドキュメントを使用して800MBのドキュメントをRAMにロードし、RAMのバランスを少し難しくする、などもできます。 。したがって、「制限」は一般的なサーバーRAMの数%です(そのため、時間の経過とともに増加します) 。mongodb.org/display/DOCS/Checking+Server+Memory+Usage
Justin Jenkins

3
すべてをRAMに格納できるのは素晴らしいことですが、効率とブログ投稿のイディオムを考慮してください。あなたは明らかにそれが読まれた場合に投稿をメモリに入れたいと思います。しかし、ほとんどの人が最初のページを超えて読んだことがないときに、ブログの投稿に対する10ページのコメントをメモリに保存したいのでしょうか。もちろん、それを実行できます。データベースが小さく、すべてメモリに収まる場合は、問題ありません。しかし、純粋な効率の点では、それを回避できれば(そしてRDBMSも同様)、無駄なビットがメモリ領域を占有することを望まないでしょう。
AlexGad 2011

50
甘いイエス、モンゴの主張は「誰にとっても16 MBで十分だ」ということでしょうか。それは過去に正しくないことが証明されたようなものではありません。
ロバートキリスト

2
これは私にはあまりにも悪いようです。Mongoはビッグデータに役立つはずであり、そのような制限はありません。私のプロジェクトでは、同じトレンドのトピックに関連するツイートを集計してグループ化する必要があります。これにより、20時間の期間でツイートが2万回を超える可能性があります(さらに、私のdbで20時間)。たくさんのつぶやきとそれらのテキストを同時に保存することは壊滅的であり、いくつかの小さなトレンドをグループ化した後、それは大きなトレンドでは例外に終わります。
Savvas Parastatidis

7
@savvasなぜすべてのツイートを単一のドキュメントに入れるのですか?ツイートごとに1つのドキュメントを使用し、トレンドトピックをドキュメントの別のフィールドとして配置します。そのトピックフィールドにインデックスを設定し、mongoパイプラインを使用してそのフィールドに集約します。メソッドを調整して、それが多くのビッグデータのユースケースでうまく機能することがわかると思ったら、nosqlで作業する方法をある程度調整する必要があります。
schmidlop

32

コミュニティの多くは、パフォーマンスに関する警告で制限なしを好みます。正当な理由がある議論については、このコメントを参照してください:https : //jira.mongodb.org/browse/SERVER-431? focusedCommentId=22283 & page=com.atlassian.jira.plugin 。 system.issuetabpanels:comment-tabpanel#comment-22283

私の考えでは、リード開発者はこの問題について、初期の段階で重要な「機能」であると判断したため、頑固です。誰かがそれを疑問視したことで彼らの気持ちが傷ついたので、彼らはすぐにそれを変えるつもりはありません。個性と政治がオープンソースコミュニティの製品を損なうもう1つの例ですが、これは実際に問題となる問題ではありません。


5
私はあなたに完全に同意します。また、ほとんどの埋め込みドキュメントが制限を簡単に超えられるようになるため、埋め込みドキュメントを作成する目的が無効になります。内部にドキュメントの配列が含まれるEsp
Sharjeel Ahmed '15

@ marr75それは今修正されたと言います、修正されましたか?
2016

1
つまり、制限が16MBに引き上げられましたが、これは「問題」の長期的な修正にはなりません。IMO制限をなくす必要があります。
marr75 2016年

2
6歳の糸のネクロ。私はあなたの特定の悪い使用例/設計例に確信が持てません。また、その例は、データベースの単一ドキュメントのサイズ制限よりも、入力を検証する必要がある理由を示すのに優れています。アプリケーションにネストされたドキュメントを別のコレクションの個別のドキュメントとして分割するか、新しい「継続」ドキュメントを開始させる(この制限内で作業するために数回使用したソリューション)と、パフォーマンスにはほとんど影響がありませんでしたが、コードの複雑さに大きな影響がありました。ドキュメントDBの全体のポイントは、データの局所性です。
marr75

4
mongoDBドキュメントがこの決定を擁護するために行っているのと同じ計算についてお礼を言いますが、単一のユースケースと思考実験は決定的なものにはほど遠いものです。mongoによってヒットされる任意の制限があるという事実を回避するために、複雑で冗長な設計を考案する必要がありました(深くネストされたエントリや重複したエントリなしで)。一部の任意のテキストはより少ないストレージを使用して表現できるため、ロジックでは、データベースに合計16MBを超える必要はありません。これは明らかにばかげています。
marr75

31

Googleからここに誘導された人のために、ここに説明の回答を投稿します。

ドキュメントサイズには、サブドキュメント、ネストされたオブジェクトなど、ドキュメント内のすべてが含まれます。

だからのドキュメント:

{
    _id:{},
    na: [1,2,3],
    naa: [
        {w:1,v:2,b:[1,2,3]},
        {w:5,b:2,h:[{d:5,g:7},{}]}
    ]
}

最大サイズは16メガです。

Sbudocumentとネストされたオブジェクトはすべて、ドキュメントのサイズにカウントされます。


BSONで表現できる単一の最大の構造は、皮肉にも、最もコンパクトです。MongoDBはsize_t内部で(64ビット)配列インデックスを使用するという事実にもかかわらず、16 MBのドキュメントサイズ制限は、せいぜい200万のNULLを含む単一の配列自体を含むドキュメントを表すことができます。
amcgregor

謝罪、2つ目のコメントを追加して、別の重要な詳細に対処/明確化します。ドキュメントサイズには、ドキュメント内のすべてが含まれ、キーも含まれると言います。たとえば、{"f": 1}は2バイト未満です{"foo": 1}。注意を怠ると、これは急速に増加しますが、最新のディスク上の圧縮は役立ちます。
amcgregor

6

ドキュメント自体に保存されている大きなファイルを含まないという制限の問題はまだ見ていません。大きなファイルを格納/取得するのに非常に効率的なさまざまなデータベースがすでに存在します。それらはオペレーティングシステムと呼ばれます。データベースは、オペレーティングシステムのレイヤーとして存在します。パフォーマンス上の理由でNoSQLソリューションを使用している場合、アプリケーションとデータの間にDBレイヤーを配置することによって、データへのアクセスに追加の処理オーバーヘッドを追加したいのはなぜですか?

JSONはテキスト形式です。したがって、JSONを介してデータにアクセスしている場合、uuencode、16進数、またはBase 64でエンコードする必要があるため、バイナリファイルがある場合は特にそうです。変換パスは次のようになります。

バイナリファイル<> JSON(エンコード)<> BSON(エンコード)

ドキュメント内のデータファイルへのパス(URL)を配置し、データ自体をバイナリで保持する方が効率的です。

本当に長さが不明なこれらのファイルをDBに保持したい場合は、これらのファイルをGridFSに配置し、大きなファイルにアクセスするときに同時実行性を停止するリスクを負わない方がよいでしょう。


1
「大きなファイルの格納/取得に非常に効率的なデータベースがすでにさまざまにあります。それらはオペレーティングシステムと呼ばれます。」; blog.mongodb.org/post/183689081/…を
redcalx 2015


2

おそらく、ブログの投稿->コメントの関係を非リレーショナルデータベースに保存することは、実際には最良の設計ではありません。

とにかく、ブログの投稿にはコメントを別のコレクションに保存する必要があります。

[編集]

詳細については、以下のコメントを参照してください。


15
私はまったく同意しません。あなたのブログの記事の文書内のコメントは、それは非常に一般的な使い方です... MongoDBの中で完全に問題ないはずです(私は生産により一つの場所よりも、それを使用し、それは非常によく動作します。)
ジャスティン・ジェンキンス

2
おそらく私は私の答えに過度に厳格でした。ブログの投稿と関連するコメントをMongoDBまたは同様のデータベースに保存しても問題はありません。それは人々がドキュメントベースのデータベースが与える能力を使い過ぎる傾向があるということ以上です(最も根本的な例はすべてのデータを「ブログ」と呼ばれる単一のドキュメントに保存することです)
Mchl

3
@Mchel:「ブログ」は良くありませんが、コメントを別のコレクションに保存することは同じ理由で同じように悪いです。コメント配列のある投稿は、文書データベースの正規の例のようなものです。
Matt Briggs

6
@SoPeople:投稿内にコメントを保存することは、ドキュメント指向DBの標準的な例のようなものです。(1つのドキュメント内にWikiテキスト全体を格納するように)私がSOと書けば、完全にMongoDBで実行されます。これらのSOエントリのいずれも、4MB を合理的に超えることはありません。Craigslistは、MongoDBへの彼らの歴史の巨大なDB移行を行っています。彼らはドキュメントの数がその制限を超えただけであり、主要な開発者はドキュメント自体が実際に無効にされたことを示唆しました(いくつかのバグの結果)。繰り返しになりますが、4メガはいくつかの小説です。
ゲイツ副社長

3
@Gates VP、別のフルテキストエンジンを使用することに同意します。メタデータ検索について考えていました。Bookドキュメントのセットがあり、1982年に発行されたすべてのブックを検索したい場合はどうでしょうか。各本に+ 100kbのテキストがある場合、最初の20冊​​の本のタイトルを表示するためだけに数メガバイトを転送する必要はありません。
mikerobi

0

https://www.mongodb.com/blog/post/6-rules-of-thumb-for-mongodb-schema-design-part-1によると

ブログ投稿が16Mbのドキュメント制限を超える可能性がある場合は、コメントを別のコレクションに抽出し、コメントからブログ投稿を参照して、アプリケーションレベルの結合を行う必要があります。

// posts
[
  {
    _id: ObjectID('AAAA'),
    text: 'a post',
    ...
  }
]

// comments
[
  {
    text: 'a comment'
    post: ObjectID('AAAA')
  },
  {
    text: 'another comment'
    post: ObjectID('AAAA')
  }
]
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.