了解MongoDB BSON文档大小限制

sai*_*int 143 mongodb bson

来自MongoDB的权威指南:

大于4MB的文档(转换为BSON时)无法保存到数据库中.这是一个有点武断的限制(将来可能会提出); 它主要是为了防止错误的架构设计并确保一致的性能.

我不明白这个限制,这是否意味着包含博客帖子的文档大量超过4MB并不能存储为单个文档?

这也计算嵌套文档吗?

如果我想要一个审核值变化的文档怎么办?(最终可能会增长,超过4MB限制.)

希望有人正确解释.

我刚刚开始阅读MongoDB(我正在学习的第一个nosql数据库).

谢谢.

Jus*_*ins 122

首先,这实际上是在下一个版本中提出8MB或者16MB......但是我认为从这个角度来看,来自10gen(开发MongoDB)的Eliot说得最好:

编辑: 大小已被正式 "提升"为16MB

所以,在你的博客示例中,4MB实际上是很多..例如,"世界大战"的完整解压缩文本只有364k(html):http: //www.gutenberg.org/etext/36

如果你的博客文章很长,有很多评论,我一个人不会读它:)

对于引用,如果你专用1MB,你可以轻松拥有超过10k(可能接近20k)

所以除了真正奇怪的情况外,它会很棒.在例外情况或垃圾邮件中,我真的不认为你想要一个20mb的对象.我认为无论表现如何,将15k左右的引用封装都很有意义.或者至少是特殊的外壳,如果它发生的话.

-Eliot

我认为你很难达到极限......随着时间的推移,如果你升级......你将不得不越来越担心.

限制的要点是不要耗尽服务器上的所有RAM(因为MB在查询时需要将所有文档加载到RAM中.)

因此,限制是普通系统上正常可用RAM的一定百分比......这将继续逐年增长.

关于在MongoDB中存储文件的注意事项

如果您需要存储大于16MB您的文档(或文件),可以使用GridFS API,它将自动将数据分解为段并将它们流回给您(从而避免了大小限制/ RAM的问题.)

GridFS不是将文件存储在单个文档中,而是将文件分成多个部分或块,并将每个块存储为单独的文档.

GridFS使用两个集合来存储文件.一个集合存储文件块,另一个存储文件元数据.

您可以使用此方法在数据库中存储图像,文件,视频等,就像在SQL数据库中一样.我用它甚至存储了几千兆字节的视频文件.

  • 甜蜜的耶稣,所以Mongo的论点是"16 MB对任何人都应该足够"?它不像以前那样被证明是不正确的. (45认同)
  • @savvas为什么要把所有推文都放在单个文件中?每条推文使用一个文档,将热门主题作为另一个字段放在文档上.在该主题字段上放置索引,然后使用mongo管道在该字段上聚合.一旦你调整你的方法并认为你会发现它适用于许多大数据用例,它需要调整你如何使用nosql. (6认同)
  • 很高兴您可以将所有内容存储在RAM中,但考虑效率和博客文章成语.如果读取它,你显然希望帖子在内存中.但是,当大多数人永远不会阅读第一页时,你真的希望博客文章的10页评论能够在内存中吗?当然,你可以做到这一点,如果你的数据库足够小,它可以全部适合内存,那么没问题.但是就纯效率而言,如果你能避免它,你就不希望无用位占用内存空间(这也适用于RDBMS). (3认同)
  • 你的整个数据库都有足够的RAM,这真是太棒了......通常情况下,"工作集"在RAM中,而不是整个数据库(就像在我的情况下,我有一个以上的x GB数据库,如果所有数据都超过我的RAM,但这没关系,因为工作集要小得多.)另外,如果没有限制,你可以将一个800MB的文档加载到RAM中,一个查询和一个400k文档与另一个查询,平衡你的RAM有点困难,等等所以"限制"是典型服务器RAM的百分之几(因此随着时间的推移而增长.)http://www.mongodb.org/display/DOCS/Checking+Server+Memory+Usage (2认同)
  • 这对我来说似乎太糟糕了。Mongo被认为对大数据很有用,没有这种限制。在我的项目中,我需要汇总和分组与同一趋势主题相关的推文,这可能会在20个小时的时间内导致超过20000条推文(而且很可能趋势会持续超过在我的数据库中20个小时)。拥有那么多推文并同时存储其文本是毁灭性的,并且在将一些小趋势分组之后,最终会出现大趋势例外。 (2认同)
  • @schmidlop 我现在不太记得了,但我认为这就是我所做的。但是当我在主题字段上聚合时,它为每个键创建了一个文档,并最终为最大的主题生成了大量文档。无论如何,那是去年,我几乎不记得我的实施:P (2认同)

mar*_*r75 32

社区中的许多人对性能的警告不会有任何限制,请参阅此评论以获得一个充分理由的论点:https://jira.mongodb.org/browse/SERVER-431? focusCommentId = 22283 & page = com.atlassian.jira.plugin. system.issuetabpanels:评论,一个tabpanel#评论- 22283

我认为,首席开发人员对这个问题很顽固,因为他们认为这是一个重要的"功能".他们不会很快改变它,因为他们的感情受到伤害,任何人都质疑它.人格和政治的另一个例子是在开源社区中贬低产品,但这并不是一个严重的问题.

  • 我完全同意你的意见,现在它也破坏了嵌入文档的目的,因为大多数嵌入式文档现在都可以轻松超越限制.Esp包含其中的文档数组 (4认同)
  • 6 岁的线程坏死。我对您具体的不良用例/设计示例深表怀疑。此外,该示例更能说明为什么需要验证输入而不是数据库单个文档大小限制。使应用程序将其嵌套文档拆分为另一个集合中的单个文档或开始一个新的“延续”文档(我已经多次使用解决方案在此限制内工作)对性​​能几乎没有影响,但对代码复杂性影响很大。文档 DB 的全部意义在于数据局部性。 (2认同)
  • 感谢mongoDB文档为捍卫这一决定所做的相同的数学运算,但是您的单个用例和思想实验远没有定论。我不得不提出复杂的冗余设计来解决以下事实:mongo确实会受到任意限制(没有深层嵌套或重复的条目,顺便说一句)。按照您的逻辑,任何数据库都不应包含超过16MB的总容量,因为可以使用较少的存储空间来表示某些任意文本。这显然是愚蠢的。 (2认同)

Sam*_*aye 27

在这里发布一个澄清答案给那些由谷歌指导的人.

文档大小包括文档中的所有内容,包括子文档,嵌套对象等.

所以一份文件:

{
    _id:{},
    na: [1,2,3],
    naa: [
        {w:1,v:2,b:[1,2,3]},
        {w:5,b:2,h:[{d:5,g:7},{}]}
    ]
}
Run Code Online (Sandbox Code Playgroud)

最大尺寸为16meg.

Sbudocuments和嵌套对象都计入文档大小.


Chr*_*dge 5

我还没有看到限制的问题,该限制不涉及文档本身中存储的大文件。已经存在各种各样的数据库,它们在存储/检索大文件方面非常有效;它们被称为操作系统。数据库作为操作系统上的一层存在。如果出于性能原因使用NoSQL解决方案,为什么要通过在应用程序和数据之间放置数据库层来增加对数据访问的额外处理开销?

JSON是一种文本格式。因此,如果您要通过JSON访问数据,则对于拥有二进制文件的情况尤其如此,因为二进制文件必须以uuencode,十六进制或Base 64进行编码。转换路径可能类似于

二进制文件<> JSON(已编码)<> BSON(已编码)

将路径(URL)放在文档中的数据文件中,并将数据本身保存为二进制,会更有效。

如果您确实希望将这些未知长度的文件保留在数据库中,那么最好将它们放在GridFS中,并且不存在在访问大文件时冒并发性的风险。


use*_*536 5

BSON文档的嵌套深度: MongoDB支持BSON文档的嵌套层次不超过100个。

更多信息