mongoDB是否会在每次添加新的子文档时将文档移动到新的内存位置?

mongoDB是否会在每次添加新的子文档时将文档移动到新的内存位置?,mongodb,database-design,nosql,database-performance,Mongodb,Database Design,Nosql,Database Performance,这是MongoDB数据库的性能问题 我正在读这本书 上下文是如何建模/设计带有注释的博客文章的模式,讨论的解决方案如下: { postName: "..." , comments: [ { _id: ObjectId(d63a5725f79f7229ce384e1) author: "", text: ""} // each comment , { _id: ObjectId(d63a5725f79f7229ce384e2) author: "", text: ""} /

这是MongoDB数据库的性能问题

我正在读这本书

上下文是如何建模/设计带有注释的博客文章的模式,讨论的解决方案如下:

{ postName: "..."
, comments: 
    [ { _id: ObjectId(d63a5725f79f7229ce384e1) author: "", text: ""}  // each comment 
    , { _id: ObjectId(d63a5725f79f7229ce384e2) author: "", text: ""}  // is a 
    , { _id: ObjectId(d63a5725f79f7229ce384e3) author: "", text: ""}  // subDocument
    ]
}
在这本书中,他的数据看起来不一样,但实际上就像我上面所说的,因为推入子文档列表会创建_id

指出这种嵌入方法的缺点,在第2个反论点中,他说:

第二个方面与写性能有关。随着评论逐渐添加到博客文章中,MongoDB很难预测在创建新文档时应用的正确文档填充。MongoDB需要为不断增长的文档分配新的空间。此外,它还必须将文档复制到新的内存位置并更新所有索引。这可能会导致更多的IO负载,并可能影响总体写入性能

摘录如下:

此外,它还必须将文档复制到新的内存位置

问题1:这实际上意味着什么

他指的是什么文件。。?BlogPost文档或评论文档

如果他提到BlogPost文档,看起来是这样的,那么这是否意味着每次我插入子文档时,少于16MB的全部数据都会被重写/复制到硬盘上的一个新位置

这就是mongoDB在引擎盖下的实际工作方式?有人能证实或反驳这一点吗?因为在每次写作中移动/复制整个文档似乎是一件非常重要的事情。特别是当它向16MB的上限增长时

问题2: 那么,当我更新一个简单的字段时会发生什么呢?说一个状态:真到状态:假。整个文档是否会在硬盘中移动/复制?我会说不,其他文档数据应该保留在原来的位置,并且更新应该发生在相同的内存位置,但是嗯。。再也不确定了

更新简单字段与从数组字段中添加或删除子文档之间有区别吗

我的意思是-这个数组操作在某种意义上是特殊的吗?并触发HDD上的文档副本,但简单字段和嵌套对象不触发

通过使保存它的字段为空来删除整个大型嵌套对象怎么样?这会触发硬盘拷贝吗?或者不会-因为该空间是预先分配的,因为模式是如何定义的


我很困惑。我的项目将需要每秒500次写入,我正在尝试检测这个实现方面是否会影响我。谢谢:

有关此行为的详细信息,请参阅已发布的MMAPv1存储引擎。此外,自MongoDB 3.2以来,默认的存储引擎是一个不同的系统,用于管理磁盘上的数据

也就是说:

问题1:这实际上意味着什么

MMAPv1将使用预先分配的填充因子将文档写入存储文件,该填充因子为将来添加额外数据提供了空白空间。如果文档的更新方式中填充不足,则需要将文档移动到磁盘上的新空间

实际上,可能会执行不会增加文档大小的更新,例如增加值、将状态:true更改为状态:false等,而增加文档大小的操作可能会移动文档,因为填充因子可能不足以容纳较大的文档


对MMAPv1如何管理数据文件中的文档进行了很好的说明。可以找到更多信息。

您正在讨论的许多行为都与MMAPv1存储引擎有关,它是MongoDB 3.0的默认版本。MongoDB 3.2以后的版本默认使用WiredTiger存储引擎,它在管理磁盘上的数据方面具有完全不同的行为。MMAPv1在MongoDB 4.0中也被弃用。