来自MongoDB的权威指南:
大于4MB的文档(转换为BSON时)无法保存到数据库中。这是一个有点武断的限制(将来可能会提出);它主要是为了防止错误的架构设计并确保一致的性能。
我不明白这个限制,这是否意味着包含博客帖子的文档大量超过4MB并不能存储为单个文档?
这也计算嵌套文档吗?
如果我想要一个审核值变化的文档怎么办? (最终可能会增长,超过4MB限制。)
希望有人正确解释。
我刚刚开始阅读MongoDB(我正在学习的第一个nosql数据库)。
谢谢。
首先,这实际上是在下一个版本中被提升为8MB
或16MB
......但是我认为从这个角度来看,来自10gen(开发MongoDB)的Eliot说得最好:
编辑:大小已被officially'提升'到16MB
所以,在你的博客示例中,4MB实际上是很多..例如,“世界大战”的完整解压缩文本只有364k(html):http://www.gutenberg.org/etext/36
如果你的博客文章很长,有很多评论,我一个人不会读它:)
对于引用,如果你专用1MB,你可以轻松拥有超过10k(可能接近20k)
所以除了真正奇怪的情况外,它会很棒。在例外情况或垃圾邮件中,我真的不认为你想要一个20mb的对象。我认为无论表现如何,将15k左右的引用封装都很有意义。或者至少是特殊的外壳,如果它发生的话。
-Eliot
我认为你很难达到极限......随着时间的推移,如果你升级......你将不得不越来越担心。
限制的要点是你不要耗尽服务器上的所有RAM(因为你需要在查询时将文档的所有MB
s加载到RAM中。)
因此,限制是普通系统上正常可用RAM的一定百分比......这将继续逐年增长。
关于在MongoDB中存储文件的注意事项
如果您需要存储大于16MB
的文档(或文件),您可以使用GridFS API,它会自动将数据拆分成段并将它们传回给您(从而避免了大小限制/ RAM的问题。)
GridFS不是将文件存储在单个文档中,而是将文件分成多个部分或块,并将每个块存储为单独的文档。
GridFS使用两个集合来存储文件。一个集合存储文件块,另一个存储文件元数据。
您可以使用此方法在数据库中存储图像,文件,视频等,就像在SQL数据库中一样。我用它甚至存储了几千兆字节的视频文件。
社区中的许多人对性能的警告不会有任何限制,请参阅此评论以获得一个充分理由的论点:https://jira.mongodb.org/browse/SERVER-431?focusedCommentId=22283&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-22283
我认为,首席开发人员对这个问题很顽固,因为他们认为这是一个重要的“功能”。他们不会很快改变它,因为他们的感情受到伤害,任何人都质疑它。人格和政治的另一个例子是在开源社区中贬低产品,但这并不是一个严重的问题。
在这里发布一个澄清答案给那些由谷歌指导的人。
文档大小包括文档中的所有内容,包括子文档,嵌套对象等。
所以一份文件:
{
_id:{},
na: [1,2,3],
naa: [
{w:1,v:2,b:[1,2,3]},
{w:5,b:2,h:[{d:5,g:7},{}]}
]
}
最大尺寸为16meg。
Sbudocuments和嵌套对象都计入文档大小。
我还没有看到限制的问题,该限制不涉及存储在文档本身中的大文件。已经存在各种数据库,这些数据库在存储/检索大文件方面非常有效;它们被称为操作系统。数据库作为操作系统上的层存在。如果出于性能原因使用NoSQL解决方案,为什么要通过在应用程序和数据之间放置数据库层来为访问数据添加额外的处理开销?
JSON是一种文本格式。因此,如果您通过JSON访问数据,如果您有二进制文件,尤其如此,因为它们必须使用uuencode,十六进制或Base 64进行编码。转换路径可能看起来像
二进制文件<> JSON(编码)<> BSON(编码)
将路径(URL)放入文档中的数据文件并将数据本身保存为二进制文件会更有效。
如果你真的想在你的数据库中保留这些未知长度的文件,那么你可能最好将这些文件放在GridFS中,并且在访问大文件时没有冒险消除你的并发性。
BSON文档的嵌套深度:MongoDB支持不超过100级的BSON文档嵌套。
也许在非关系数据库中存储博客文章 - >评论关系并不是最好的设计。
无论如何,您应该将评论存储在单独的博客文章中。
[编辑]
请参阅以下评论以进一步讨论。
根据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')
}
]