ChatGPT解决这个技术问题 Extra ChatGPT

是否可以使用 EF 迁移更新生产数据库?

根据 this blog post,大多数使用 EF 迁移的公司应该不会使用 EF 迁移更新生产数据库的数据库架构。相反,博客文章的作者建议在部署过程中使用 Schema 更新脚本。

我已经使用 Schema 更新脚本几年了,虽然它们可以工作,但我计划在未来使用 EF 迁移,原因如下:

更快的部署,更少的停机时间

更简单的部署过程

现有数据的迁移比使用 T-SQL 更容易

等待应用更改的更易于理解的语法(具有干净 C# 语法的 DbMigration 类与传统环境中笨拙的 T-SQL 迁移脚本)。

如果新软件版本的部署失败,则有一个简单快捷的旧数据库模式降级路径

我能想到禁止使用 EF 迁移生产数据库的一个原因是,如果数据库架构仅由 DBA 而不是开发人员更改。但是,我既是 DBA 又是开发人员,所以这对我来说并不重要。

那么,使用 EF 更新生产数据库有哪些风险?

编辑:我想补充一点,正如solomon8718 已经建议的那样,我总是将生产数据库的新副本拉到我的登台服务器上,并在将它们应用到生产服务器之前测试要在登台服务器上应用的 EF 迁移。 IMO 这对于生产系统的任何模式更新都是必不可少的,无论我是否使用 EF 迁移。

@Ewan:除非您使用的是自动迁移(我不是),否则您确实会得到与 T-SQL 模式迁移脚本非常相似的东西,作为生成的 DbMigration 类的一部分。您可以详细查看每个更改。 IMO 它也比 T-SQL 更容易检查有效性,因为它比 SQL 语法更容易理解。
梅森:我不想在这里宣传任何意见,我想问一些我可能错过的观点,因为我不明白我链接到的博客文章在说什么。看起来,在你之前为我的帖子点赞的 7 个人也同意这是一个有趣的话题,尤其是那些甚至为它加星的四个人。
@AdrianGrigore,我可以看到你来自哪里,但我认为这个问题的措辞应该不同。 “有什么好的理由”听起来确实像是一个主观问题。也很难回答;我认为您永远无法明确回答“否”,但“是的,这里有一些原因……”可能会使用取决于特定风险策略的主观原因。更好的提问方式可能是“使用 EF 更新生产数据库有哪些风险?”为了记录,我也对答案感兴趣。
撤回我的近距离投票,因为它似乎符合帮助中心中包含的the information,其中在某些情况下允许提出主观问题。
我不在生产中使用 Code First / Migrations 的主要原因是您的用户需要某些权限。这显然是许多环境中的主要安全风险。如果您对此感到满意或乐于暂时授予这些权限,那为什么不呢?

D
DrewJordan

好吧,无论如何我都会尝试回答。我会说不,没有理由不在生产中使用 Code First 迁移。毕竟,如果你不能一路走下去,这个易于使用的系统又有什么意义呢?

我看到的最大问题是您已经注意到的任何系统都可能遇到的所有问题。只要整个团队(包括 DBA,如果适用)都参与其中,我认为允许 EF 通过迁移来管理架构并不复杂,因此比传统的基于脚本的管理更不容易出错。在生产系统上执行迁移之前,我仍然会进行备份,但无论如何你都会这样做。

也没有说 DBA 不能从 Visual Studio 执行迁移。仍然可以使用数据库级别的权限锁定访问权限,并且他/她可以在执行实际操作之前查看迁移(如果需要,使用 -Script 以有用的 SQL 导出格式)。然后它们仍然处于控制之中,但您可以使用代码优先迁移。地狱,他们甚至可能最终喜欢它!

更新:由于提出了 SPROC 和 TVF,我们也在迁移中处理它们,尽管它们实际上是通过使用 Up() 中的 DbMigration.Sql() 调用的直接 SQL 语句完成的,而在 {3 } (您也可以将 CreateStoredProcedureDropStoredProcedure 用于简单的 SPROC,但我认为您仍然必须在 SQL 中定义主体本身)。我想你可以说这是一个警告;目前还没有一种方法可以完全用 C# 编写完整、全面的数据库。但是,您可以使用包含 SQL 脚本的迁移来管理整个架构。我们从这个过程中发现的一个好处是,您可以将 C# 配置文件用于架构对象名称(例如,生产与开发的不同服务器名称)和一个简单的 String.Format,并结合配置文件本身的 XML 转换。


为了创建 SP 和函数,我们使用 DbMigration.Sql() 在本地可以正常工作。尽管在部署 (VSTS) 之后会创建 SP,但不会创建迁移记录。检查 drop/sql 表明插入存在。本地一切都很好,并且创建了迁移记录。有任何想法吗?不太热衷于在所有 azureDB 上手动添加它们......
M
MplsAmigo

是的,有充分的理由不使用 Code First Migrations 等自动化系统来更改生产数据库。但与往常一样,规则也有例外。

已经提到的一个原因是访问权限,这将与您组织的变更管理规则和安全策略直接相关。另一个原因是您对迁移工具本身的信任程度。我们确定该工具没有错误吗?如果工具在中途失败会发生什么?你确定你有最新的备份和一个在需要时回滚的过程吗?更改脚本可能会执行意外或低效的脚本。我遇到过这样的情况,其中生成的 sql 将数据复制到临时表中,删除原始表,然后重新创建原始表以添加新列,如果您不小心(或故意)更改列出现的顺序,或者当您重命名表时。如果涉及数百万条记录,这可能会导致严重的性能问题。

我的建议:

假设您有一个反映您的生产模式的暂存数据库,请使用迁移工具针对该系统生成其更改脚本。我们通常在运行之前从一个新的生产副本中恢复我们的阶段数据库。然后我们手动检查更改脚本以检查问题。之后,我们针对我们的阶段数据库运行脚本,以确保它正确执行并且所有预期的更改都发生了。现在我们确信这些脚本既可以安全地在生产环境中运行,又可以执行预期的更改。这个过程将解决我上面列出的所有三个问题。


感谢您的全面回复。关于带有生产数据库的新副本的登台数据库的要点。我一直在使用相同的程序,我也会推荐它。
“从新的生产副本中恢复我们的阶段数据库”仅供参考,这被称为“生产前测试”
乐意效劳!在我们的例子中,我们在 Visual Studio 中有一个数据库项目,而不是 EF 项目,但两者都使用 Sql Server Data Tools。我已经在我们的应用程序部署团队工作了很长一段时间,所以遇到了一些涉及的问题。 @AaronLS - 感谢您的提示
@solomon8718 如何将 EF 迁移产生的更改导入 SSDT 项目?如果涉及答案,我可以发布新问题。我喜欢 SSDT,但在我可以尝试使其与 EF Code First 同步的所有方法中,我从来没有找到一种不太笨重的方法。
@Brian:对不起,但你错了。您链接到的文章的意思是,它将查看存储在 __MigrationHistory 表中的数据,以确定在应用迁移之前 Db 的当前状态。这并不意味着它会查看架构。查看架构仅在设计时完成。换句话说:如果 _MigrationHistory 表明 Db 处于某种状态,那么 EF Migrations 将简单地假设这是正确的。它不验证数据库的模式是否与存储在 _MigrationHistory 表中的状态相匹配。
A
Adrian Grigore

我发现的另一个警告:如果您有多个网站使用相同的数据上下文,则需要确保所有网站都同时更新。否则,网站之间可能会出现持续的数据库更新/降级之争。除此之外,它对我来说很好。

编辑:在开始在生产中使用 EF 迁移一年后,我自己的观点:

EF Migrations 实际上非常酷,即使用于生产,只要您

在暂存系统上测试迁移。在运行集成测试之前,我通过在我的 CI 服务器上一直向下和向上迁移来测试所有迁移。不要自动触发迁移,而是使用管理员启动的批处理文件。这与在 SSMS 中手动运行 sql 进行迁移基本相同。


感谢您的反馈。如果不涉及答案,您如何管理 Web 应用程序中的迁移代码(在 DB 上应该具有有限的权限)以更改 DB 中的模式(应该需要更高的权限)?
M
Mariusz Jamro

我在几个项目的生产中使用它。一旦你掌握了它的窍门,我认为它很好。

在开发过程中,您可以保持自动迁移,但最后您可以直接从包管理器控制台连接到实时数据库并生成迁移。它将为您提供所有更改的迁移。

但始终始终将 -script 选项与 update-database 一起使用并自己触发 SQL。

我还建议不要使用 web deploy 中的 update db 选项。这样就无法判断有多少迁移已经因错误而被触发。我遇到过几次麻烦。所以最好获取 SQL 并手动触发它。


更新数据库来自哪里?