MongoDB:正在索引痛苦吗?

时间:2014-06-27 16:40:53

标签: mongodb indexing schemaless

总的来说,我想知道查询(并因此索引)无模式数据结构的最佳实践是什么? (即文件)

假设我使用MongoDB来存储和查询集合中的确定性数据结构。此时所有文档都具有相同的结构,因此我可以轻松地为我的应用程序中的任何查询创建索引,因为我知道每个文档都有索引所需的字段。

更改结构并尝试将新文档保存到数据库后会发生什么?假设我将FirstName和Lastname两个字段加入FullName。因此,该集合包含非确定性数据。我在这里看到两个问题:

  • 旧索引无法覆盖新数据,因此需要新索引来处理新旧字段
  • 应该负责处理文件的两个陈述

当db中有许多更改导致许多版本的文档结构时,这可能会导致一个大问题。

我看到两种主要方法:

  • 懒惰的迁移。这意味着每个文档按需迁移(即仅在从集合加载后)到最终结构,然后存储回到集合。这种方法实际上并没有解决问题,因为它在任何时候都承认不确定性。
  • 强迫迁移。这与RDBMS迁移的方法相同。当应用程序未运行时,将在一个时间点对所有文档执行迁移。主要的骗局是应用程序的停机时间。

所以问题是:有没有什么好方法可以解决问题,特别是没有app停机时间?

1 个答案:

答案 0 :(得分:1)

如果您无法停机,那么唯一的选择是“即时”进行迁移:

  1. 更改应用程序,以便在保存新文档时创建新字段,但从旧字段中读取。
  2. 使用脚本/查询更新您的集合,以在集合中添加新字段。
  3. 在该字段上创建新索引。
  4. 更改应用程序,使其从新字段中读取。
  5. 删除不必要的索引并从文档中删除旧字段。
  6. 无论您使用何种数据库,更改实时数据库上的架构绝非易事。它总是需要一些前瞻性思维和精心规划。

      

    正在索引疼痛?

    索引不是一种痛苦,但过早的优化是。在添加索引之前,您应该始终测试并检查您是否确实需要索引,并在拥有索引时检查它们是否正确使用。

    如果您在创建索引时担心实时系统上的性能问题,那么您应该考虑使用副本集并进行滚动维护(简而言之:从复制中删除辅助节点,在它们上创建索引,将它们重新复制到复制中然后为所有后续副本集成员重复该过程。)

    修改

    我所描述的基本上是一个将模式迁移到新模式的过程,同时临时支持两个版本的文档。

    在第1步中,您基本上添加了对多个版本文档的支持。当您从之前的版本字段中读取数据时,您正在更新现有文档,即创建新字段。第2步是可选的,因为您可以在保存文档时逐步更新文档。

    在第4步中,您将从应用程序代码中删除对以前版本的支持,并迁移到新版本。最后,在步骤5中,您将从实际的MongoDB文档中删除以前的版本字段。