1

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

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

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

  • 旧索引无法覆盖新数据,因此需要处理新旧字段的新索引
  • 应用程序应该负责处理文档的两种表示形式

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

我看到两种主要方法:

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

那么问题来了:有什么好的方法可以解决这个问题,尤其是在没有应用程序停机的情况下?

4

1 回答 1

1

如果您不能有停机时间,那么唯一的选择就是“即时”进行迁移:

  1. 更改应用程序,以便在保存新文档时创建新字段,但从旧字段中读取。
  2. 使用脚本/查询更新您的集合以在集合中添加新字段。
  3. 在该字段上创建新索引。
  4. 更改应用程序,使其从新字段中读取。
  5. 删除不必要的索引并从文档中删除旧字段。

无论您使用什么数据库,更改实时数据库上的模式都不是一件容易的事。它总是需要一些前瞻性的思考和仔细的计划。

索引是痛苦的吗?

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

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

编辑

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

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

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

于 2014-06-27T20:45:27.627 回答