Django与MongoDB结合使用是否使迁移成为过去?

20

由于MongoDB没有模式,这是否意味着当我们更改模型时不需要进行迁移?

在非关系数据库中,迁移过程是什么样子的?

3个回答

17

我认为这是一个非常好的问题,但回答会基于你使用的库和对“迁移”的期望而有所分散。

让我们看一下一些常见的迁移操作:

  • 添加字段:在Mongo中很容易实现。只需添加一个字段即可完成。
  • 删除字段:理论上,您并不会真正绑定到模式(schema)上,因此这里的“删除”是相对的。如果您删除了“属性”,并且不再加载该字段,则该字段是否存在于数据中并不重要。因此,如果您不关心“清理”数据库,则删除字段不会影响数据库。如果您关心清理数据库,则基本上需要针对数据库运行巨大的for循环。
  • 修改字段名称:这也是一个困难的问题。当您重命名一个字段时,“where(在哪里)”重命名它?如果您希望DB反映新字段名称,那么您基本上必须在DB上执行一个巨大的for循环。为了安全起见,您可能需要“添加”数据,然后推送代码,最后“取消设置”旧字段。

一些注意事项

然而,在ActiveRecord对象与字段名称结合的概念有点偏颇。ActiveRecord对象实际上提供了将对象属性映射到实际数据库字段的映射。

在典型的关系型数据库管理系统(RDBMS)中,字段名的“大小”并不重要。但是,在Mongo中,字段名实际上占用数据空间,这在性能方面有很大的影响。

现在,如果您使用某种形式的“数据对象”,比如ActiveRecord,为什么您会尝试将完整的字段名称存储在数据中呢?DB应该将所有字段按字母顺序存储,并在Object一侧提供一个映射。因此,一个文档可以有8个字段/属性,而DB名称将是“a”,“b”...“j”,但Object名称将是可读的内容,如“名称”,“价格”,“数量”。

我提到这个问题是因为它给修改字段名称增加了另一个难点。如果你正在实现一个映射,那么修改字段名称实际上并不会导致迁移。

更多注意事项

如果您想在删除时执行迁移,那么必须在部署之后进行。您还需要认识到,这样做并不会节省当前的磁盘空间。

Mongo预分配空间,除非进行数据库修复,否则实际上不会“归还”该空间。因此,如果您删除了一些文档中的字段,这些文档仍然占用相同的磁盘空间。如果以后移动文档,则可能会重新获取空间,但是只有当文档增长时才会移动文档。

如果您从许多文档中删除大型字段,则应进行修复或查看新的原地compact命令。


2

没有万能的解决方案。在非关系型数据库中,添加或删除字段更容易(只需不使用不需要的字段或使用新字段),而在传统数据库中重命名字段更容易(通常需要在无模式数据库中更改大量数据)。数据迁移取决于任务,两种类型的数据库都可以胜任。


我认为在最新的Mongo上甚至还不存在字段重命名。 - Joshua Partogi
1
$rename现在已经存在于MongoDB中。 - Druska

1
非关系型数据库的迁移过程是什么样子的?
这取决于您是否需要更新所有现有数据。在许多情况下,您可能不需要触及旧数据,例如添加一个新的可选字段。如果该字段还具有默认值,则如果您的应用程序可以正确处理缺少字段,您也可能不需要更新旧文档。但是,如果您想在新字段上构建索引以进行搜索/过滤/排序,则需要将默认值添加回旧文档中。
类似于字段重命名(在关系型数据库中很简单,因为您只需要更新目录而不需要触及任何数据)在MongoDB中是一项重大任务(您需要重写所有文档)。
如果您需要更新现有数据,则通常必须编写迁移函数,逐个迭代所有文档并逐个更新它们(尽管此过程可以共享并并行运行)。对于大型数据集,这可能需要很长时间(和空间),并且您可能会错过事务(如果您最终遇到了崩溃的迁移,该迁移已经完成了一半)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接