简洁版本
是“最简单的策略是编写升级脚本”。对于 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。