NoSQL 数据库中的架构迁移脚本

2023-12-24

我有一个一直使用 C#、实体框架和 SQL Server 的活动项目。然而,随着 NoSQL 替代方案的可行性日益增加,我正在研究将项目切换为使用 MongoDB 的所有影响。

显然,主要的过渡障碍是由于“无模式”造成的。找到了对 C# 等语言意味着什么的很好的总结here https://mongodb.github.io/mongo-csharp-driver/2.3/reference/bson/mapping/schema_changes/在 MongoDB 官方文档中。以下是最有帮助的相关段落(加粗):

仅仅因为 MongoDB 是无模式的,并不意味着您的代码可以 处理无模式文档。最有可能的是,如果您使用的是 静态类型语言,如 C# 或 VB.NET,那么您的代码不是 灵活并且需要映射到已知的模式。

模式可以通过多种不同的方式进行更改 您的应用程序的下一个版本。

如何处理这些取决于你。有两种不同的策略: 编写升级脚本。逐步更新您的文档 被使用。最简单的策略是编写升级脚本。有 关系数据库与此方法实际上没有区别 (SQL Server、Oracle)和 MongoDB。确定需要的文件 进行更改并更新它们。

或者,在大多数关系数据库中不支持的是 增量升级。这个想法是你的文档得到更新 当它们被使用时。从未使用过的文档永远不会更新。 因此,您需要避免一些明确的陷阱 意识到。

首先,针对半数文档为版本 1 的架构进行查询 一半的文档是版本 2 可能会出错。例如,如果 您重命名一个元素,那么您的查询将需要测试旧的 元素名称和新元素名称以获得所有结果。

其次,任何增量升级代码都必须保留在代码库中,直到 所有文件均已升级。例如,如果已经有 文档的 3 个版本,[1、2 和 3],我们删除了升级代码 从版本 1 到版本 2,仍然作为版本存在的任何文档 1 不可升级。

SQL 生态系统中用于管理/创建此类初始化或升级脚本的工具非常成熟(例如实体框架迁移 https://msdn.microsoft.com/en-us/library/jj591621(v=vs.113).aspx)

虽然有类似的工具 https://github.com/emirotin/mongodb-migrations and 自制脚本 https://derickrethans.nl/managing-schema-changes.html可用于 NoSQL 世界中的此类升级(尽管有些人认为不应该 https://stackoverflow.com/questions/1961013/are-there-any-tools-for-schema-migration-for-nosql-databases),对于“何时”和“如何”运行这些升级脚本似乎缺乏共识。Some https://blog.coinbase.com/how-we-do-mongodb-migrations-at-coinbase-47f18110d17f部署后建议。不幸的是,当尝试读取 C# 模型已更改的现有数据时,这种方法(当不与增量更新结合使用时)可能会使应用程序处于不可用状态。

If

"最简单的策略是编写升级脚本。 https://mongodb.github.io/mongo-csharp-driver/2.3/reference/bson/mapping/schema_changes/"

对于 C# 等静态 .NET 语言来说,这确实是最简单/推荐的方法,NoSql 数据库中是否有针对这些语言的代码优先模式迁移的现有工具?还是 NoSql 生态系统还没有成熟?

如果您不同意 MongoDB 的建议,那么更好的实现是什么?您能否提供一些参考/示例,让我在哪里可以看到正在使用的实现?


简洁版本

是“最简单的策略是编写升级脚本”。对于 C# 等静态 .NET 语言来说,这确实是最简单/推荐的方法吗?

不。您可以这样做,但这不是 NoSQL 的优势。使用 C# 并不会改变这一点。

NoSql 数据库中是否有针对这些语言的代码优先模式迁移的现有工具?

据我所知。

还是 NoSql 生态系统还没有成熟?

它是无模式的。我不认为这是成熟度的目标或衡量标准。

Warnings

首先,我相当怀疑,在一般情况下,将现有的关系模型推向 NoSql 是否会解决比它产生的问题更多的问题。

SQL 用于处理关系和数据集,noSQL 的目标是处理非关系数据:具有很少和/或软关系的“孤岛”。两者都擅长自己的目标,但擅长的事情不同。它们不可互换。如果没有在数据重新设计、团队思维和应用程序逻辑变化方面做出认真的努力,可能会使大多数先前的技术设计决策失效,并影响架构系统属性,甚至可能影响用户体验。

显然,这对你的情况可能有意义,但绝对是在提交之前计算投资回报率.

处理架构变更

假设您确实有充分的理由进行切换,并且模式更改管理是其中的关键,我建议不要对抗 NoSQL 的无模式本质,而是拥抱它。接受您的数据将具有不同的模式。

不要执行升级脚本

..除非您知道您的应用程序数据集永远不会显着增长或变化。您引用的其他 SO 帖子 https://stackoverflow.com/a/3007620/331325解释得很好。你刚才不能指望能够长期做到这一点因此无论如何你都需要一个B计划。不妨从它开始,并且仅使用架构更新脚本(如果对于特定情况确实是更简单的事情)。

我可能会补充一点,一个好的 NoSQL 优化数据模型通常针对单项查找和写入进行优化,并且与 SQL 相比,批量更新可能要重得多,即要更新单个字段,您可能必须重写更大的字段文档的一部分+可能会处理一些引入的非规范化,以减少 noSQL 中的查找需求(它甚至可能不是事务性的)。因此,在测量升级停机时间时,NoSql 中的“大”可能会比您预期的要小得多并且发生的速度更快。

同时支持多个模式

实际上,期望具有不同的并发“活动”模式版本,因为反正没有强制执行这就是您首先切换到 NoSQL 时所选择的核心功能。

理想情况下,在 noSQL 思维方式中,您的逻辑应该能够处理满足特定流程要求的任何输入数据。它应该取决于所需的输入,而不是您的存储模型(这对于依赖管理来降低复杂性也具有普遍意义)。也许逻辑只取决于单一类型文档中的一些属性。如果其他一些字段发生更改或添加了一些额外的数据,只要它们与要完成的给定特定工作无关,它就不应该中断。当然它不应该关心其他模型类型是否发生了变化。这种方法通常意味着处理一些软价值包(JSON/动态/字典/等)。

即使存储模型是无模式的,每个业务逻辑流程也对输入模型(模式子集)有期望,并且应该验证它可以与给定的内容一起工作。沿模型保留模式版本号在更棘手的情况下也有帮助。

作为一名 C# 人员,我个人避免直接使用动态模型,而更喜欢创建一个强类型对象来包装每个动态存储类型。为了避免管理 N 个并发模式版本模型(差异最小)并不断升级逻辑层以支持新的模式版本,我会将其实现为所有当前支持的架构版本的超集对于给定的实体并实现您需要的任何接口。当然,您可以添加 N 个抽象层;)一旦某些旧模式版本最终从数据中淘汰,您就可以简化模型并获得强类型支持以覆盖所有依赖项。

另外,这对于逻辑层应该有一个后备或反应计划输入模型是否不符合执行预期逻辑的要求。这取决于应用程序何时何地可以自动升级、接受丢弃、部分重置或必须定向到一些更棘手的修复队列(如果没有自动程序可以削减它,则需要手动修复)或必须完全拒绝请求,因为不兼容。

是的,存在跨不同版本的模型集进行查询的问题,因此您也应该始终考虑这些情况。您可能需要调整查询逻辑以分别查询不同版本并合并结果(或者在可接受的情况下接受部分结果)。

当然,肯定需要考虑权衡。

那么,迁移?

一个缺点(如果您考虑迁移工具集的可用性)是您没有一个真正的模式来自动生成模型,或者它会随着迁移而变化C# 模型是真实来源模式您目前正在支持。实际上,与代码优先的思维方式非常相似,但没有迁移。

您可以实现一个传入模型管道,该管道会在读取模型时自动升级模型,从而减少支持上游所需的架构版本数量。我想说这已经是最接近迁移的了。我不知道有什么工具可以自动为您执行此操作,并且我不确定我是否希望这样做。需要考虑一些权衡,例如,某些使用数据的客户端可能会以不同的时间线进行升级等。升级到最新版本可能并不总是您想要的。

结论

NoSQL 根据定义不是 SQL。两者都很酷,但期望等效或可互换肯定会遇到麻烦。

您仍然需要考虑和管理 NoSQL 中的模式,但如果您想要一种真正强制且有保证的模式,那么请考虑 SQL。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

NoSQL 数据库中的架构迁移脚本 的相关文章

随机推荐

  • 速度模板和 JavaScript

    我尝试将 javascript 添加到我的速度模板中 table tr td Name td td currency CurrencyName td tr tr td Jual td td div currency Buy div td t
  • openstacksdk如何更改当前用户密码

    我找到了CLI or API请求方法 它们对我有用 如下所示 source etc kolla admin openrc sh openstack user password set password newpsw original pas
  • 我如何使用 python 请求登录 instagram?

    你好 我正在尝试使用 python requests 库登录 Instagram 但是当我尝试时 Instagram 将我变成了 错误请求 有谁知道我该如何解决这个问题 我寻找解决这个问题的方法 但没有找到任何东西 请帮忙 谢谢 它正在工作
  • 错误:RenderBox 未布局,断言失败:第 1940 行 pos 12:“hasSize”

    我无法修复这个错误 RenderBox 未布局 RenderPointerListener 2b92a relayoutBoundary up9 需要绘制需要合成位更新 package flutter src rendering box d
  • 如何从单个父进程创建两个进程

    我知道我需要使用 fork 但这只会创建一个子进程 我是否只是从子进程中再次调用 fork 另外 我需要它们通过信号或管道进行通信 这更容易实现 并且我需要知道什么才能做到这一点 函数等 要创建第二个进程 请调用fork 再次 无论是在父级
  • Google Auth 在 Blazor 中获取访问令牌时出错

    我目前有一个带有 Blazor WASM 的 ASP Net Core Web Api 它可以使用组件 RemoteAuthenticatorView 成功登录 Google OAuth 我现在的目的是将我拥有的令牌传递给 Web api
  • 生成范围 (1,n) 但不在列表 (i,j) 中的数字

    如何生成在范围内的随机数 1 n 但不在某个列表中 i j 示例 范围是 1 500 列表是 1 3 4 45 199 212 344 注意 列表可能未排序 拒绝抽样 http en wikipedia org wiki Rejection
  • 使用 tslint 时如何忽略 *.d.ts 文件?

    我想将 tslint 添加到我的工作流程中 我通过以下方式安装它 npm install tslint tslint config ms recommended save dev And my tslint json好像 extends t
  • 如何序列化ArrayList中的对象?

    我想序列化一个数组列表Item但它不起作用 my Item类扩展Stuff类并有一些子类 我的所有类都实现了可序列化 我有这部分 try Serialize data object to a file ObjectOutputStream
  • Lua:获取网页

    我想获取一个网页并以字符串形式获取结果 但我不知道该怎么做 我在网上搜索并没有找到如何操作 我只想用Lua套接字 http w3 impa br diego software luasocket其中带有一个http子模块 http w3 i
  • 与 sklearn.neighbors.NearestNeighbors 的输出混淆

    这是代码 from sklearn neighbors import NearestNeighbors import numpy as np X np array 1 1 2 1 3 2 1 1 2 1 3 2 nbrs NearestNe
  • 如何安装CodeRush和Resharper? CodeRush 快捷方式丢失

    我正在尝试同时安装 CodeRush 和 ReSharper 安装 ReSharper 后 我的 CodeRush 快捷方式消失了 有谁知道如何在安装了 Resharper 的情况下恢复我的 CodeRush 短裤 这是我当前的设置 1 V
  • 当用户单击输入密码时,如何使用系统内置密码屏幕来验证我的应用程序

    我正在将 TouchID 集成到我的应用程序中 如何使用 输入密码 选项显示系统内置密码屏幕来验证我的应用程序 请任何人解释一下如何处理 Objective C 中的 LAErrorUserFallback 情况 你不能这样做 您可以做的是
  • Lambda 表达式无法工作,被终止

    使用 lambda 表达式编写 java 8 程序 它没有被执行 而是在 lambda 表达式处终止 没有例外 import java util ArrayList import java util List import java uti
  • 将一个或多个系数设置为特定整数

    我正在使用标准 lm 模型 并且希望将一个或多个变量的系数设置为特定整数 例如 我希望天气和价格变量的系数分别为 647 和 15 我正在使用带有标准公式的 lm 函数 到目前为止我发现的最接近的东西是glm中的offset函数 或者sys
  • Angular2路由器可以激活,带参数吗?

    我已经看到了关于这个具体问题的一些问题 我最近只从事 Angular2 项目 无论如何 我现在遇到了一个问题 在已弃用的路由器中 我在路由的数据部分添加了我的用户角色 我覆盖了 routerOutlet 以便我可以在激活路由之前检查此值 目
  • 最佳实践:创建免费版和付费版时如何处理iOS App的代码差异?

    我想在 App Store 上发布我的 iOS 应用程序的两个版本 一种是付费的 另一种是免费的 到目前为止 我的付费应用程序代码已经完成 现在我想为免费应用程序的 iAd 和 InAppPurchase 添加更多代码 维护这两个版本的最佳
  • 使用 Pandas 和 spaCy 进行标记化

    我正在开发我的第一个 Python 项目 并且拥有相当大的数据集 数十万行 我需要对 5 个文本列 每个 单元格 有多个文本句子 进行一些 nlp 聚类 分类 并且一直在使用 pandas 来组织 构建数据集 我希望对所有 nlp 使用 s
  • 在 Windows 7 64 位上安装 Hg-Git

    我正在尝试安装一段时间Hg Git 插件 http hg git github com 到我的 Windows 7 操作系统 我遇到了一些困难 例如安装 Python 和其他实用程序中描述的这个博客 http blog sadphaeton
  • NoSQL 数据库中的架构迁移脚本

    我有一个一直使用 C 实体框架和 SQL Server 的活动项目 然而 随着 NoSQL 替代方案的可行性日益增加 我正在研究将项目切换为使用 MongoDB 的所有影响 显然 主要的过渡障碍是由于 无模式 造成的 找到了对 C 等语言意