可以使用 EF 迁移更新生产数据库吗?
Is it OK to update a production database with EF migrations?
据this blog post称,大多数使用 EF 迁移的公司应该不会使用 EF 迁移更新生产数据库的数据库架构。相反,博客 post 的作者建议使用架构更新脚本作为部署过程的一部分。
我已经使用架构更新脚本几年了,虽然它们有效,但我计划在未来使用 EF 迁移,原因如下:
- 更快的部署,更少的停机时间
- 更简单的部署过程
- 现有数据的迁移比使用 T-SQL
更容易
- 等待应用的更改的更易于理解的语法(DbMigration class 具有干净的 C# 语法与笨拙的 T-SQL 传统环境中的迁移脚本)。
- 如果新软件版本的部署失败,有一个简单快速的降级到旧数据库模式的途径
我能想到的一个禁止使用 EF 迁移生产数据库的原因是,如果数据库架构仅由 DBA 而不是开发人员更改。但是,我既是 DBA 又是开发人员,所以这对我来说并不重要。
那么,使用 EF 更新生产数据库有哪些风险?
编辑:我想补充一点,正如 solomon8718 已经建议的那样,我总是将生产数据库的新副本拉到我的登台服务器并测试要在登台服务器上应用的 EF 迁移,然后再将它们应用到生产服务器。 IMO 这对于生产系统的任何模式更新都是必不可少的,无论我是否使用 EF 迁移。
好吧,我会尽力回答的。我会说不,没有理由不在生产中使用代码优先迁移。毕竟,如果您不能一路走下去,那么这个易于使用的系统有什么意义呢?
我看到的最大问题是您已经注意到的任何系统都可能遇到的所有问题。只要整个团队(如果适用,包括 DBA)都参与其中,我认为允许 EF 通过迁移来管理架构就不那么复杂,因此比传统的基于脚本的管理更不容易出错。在生产系统上执行迁移之前,我仍然会进行备份,但无论如何你都会这样做。
也没有说 DBA 不能从 Visual Studio 执行迁移。在执行实际操作之前,仍然可以使用数据库级别的权限锁定访问权限,并且 he/she 可以检查迁移(如果需要,可以使用 -Script
以有用的 SQL 导出格式) .然后他们仍然处于控制之中,但您可以使用代码优先迁移。该死,他们甚至可能最终会喜欢它!
更新:自从 SPROC 和 TVF 出现以来,我们也在迁移中处理它们,尽管它们实际上是使用直接 SQL 语句在 Up()
,以及它们在 Down()
中的反向(对于简单的 SPROC,您也可以使用 CreateStoredProcedure
和 DropStoredProcedure
,但我认为您仍然必须在 SQL).我想你可以说这是一个警告;目前还没有一种方法可以完全用 C# 编写一个完整的综合数据库。但是,您 可以 使用包含 SQL 脚本的迁移来管理整个架构。我们从这个过程中发现的一个好处是,您可以将 C# 配置文件用于架构对象名称(例如,用于生产和开发的不同服务器名称),通过简单的 String.Format
,结合 XML 转换配置文件本身。
我在几个项目的生产中使用它。一旦你掌握了它,我觉得它很好。
在开发过程中,您可以保持自动迁移,但最后您可以直接从包管理器控制台连接到实时数据库并生成迁移。它将为您提供所有更改的一次迁移。
但始终始终将 -script
选项与 update-database
一起使用,然后自己触发 SQL。
我还建议不要使用网络部署中的更新数据库选项。这样就无法判断有多少迁移已经因错误而被触发。我已经 运行 遇到过几次这样的麻烦。所以最好获取 SQL 并手动触发它。
是的,有很好的理由不使用自动化系统(例如代码优先迁移)来进行生产数据库更改。但一如既往,规则也有例外。
提到的一个原因是访问权限,这与您组织的变更管理规则和安全策略直接相关。
另一个原因是您对迁移工具本身的信任程度。我们确定该工具没有错误吗?如果工具在中途失败怎么办?您确定您有最新的备份和一个在需要时回滚的过程吗?
更改脚本可能会执行意外或低效的脚本。我遇到过 sql 生成将数据复制到临时 table,删除原始 table,然后重新创建原始 table 以添加新列等情况如果您不小心(或有意)更改了列的显示顺序,或者重命名 table。如果涉及数百万条记录,这可能会导致严重的性能问题。
我的推荐:
假设您有一个反映生产模式的登台数据库,请使用迁移工具针对该系统生成其更改脚本。我们通常在 运行ning 之前从新的生产副本恢复阶段数据库。然后我们手动检查更改脚本以检查问题。在那之后,我们 运行 针对我们的阶段数据库的脚本,以确保它正确执行并且所有预期的更改都发生了。现在我们确定这些脚本在生产中对 运行 都是安全的,并且可以执行预期的更改。此过程将解决我上面列出的所有三个问题。
我发现的另一个注意事项:如果您有多个网站使用相同的数据上下文,则需要确保所有网站都同时更新。否则网站之间可能会发生持续的数据库更新/降级斗争。除此之外,它对我来说效果很好。
编辑:开始在生产中使用 EF 迁移一年后我自己的观点:
EF Migrations 实际上非常酷,即使是用于生产,前提是您
- 在暂存系统上测试迁移。在 运行 集成测试之前,我通过在我的 CI 服务器上一路上下迁移来测试所有迁移。
- 不自动触发迁移,而是使用管理员启动的批处理文件。这与在 SSMS 中手动迁移的 运行 和 sql 基本相同。
据this blog post称,大多数使用 EF 迁移的公司应该不会使用 EF 迁移更新生产数据库的数据库架构。相反,博客 post 的作者建议使用架构更新脚本作为部署过程的一部分。
我已经使用架构更新脚本几年了,虽然它们有效,但我计划在未来使用 EF 迁移,原因如下:
- 更快的部署,更少的停机时间
- 更简单的部署过程
- 现有数据的迁移比使用 T-SQL 更容易
- 等待应用的更改的更易于理解的语法(DbMigration class 具有干净的 C# 语法与笨拙的 T-SQL 传统环境中的迁移脚本)。
- 如果新软件版本的部署失败,有一个简单快速的降级到旧数据库模式的途径
我能想到的一个禁止使用 EF 迁移生产数据库的原因是,如果数据库架构仅由 DBA 而不是开发人员更改。但是,我既是 DBA 又是开发人员,所以这对我来说并不重要。
那么,使用 EF 更新生产数据库有哪些风险?
编辑:我想补充一点,正如 solomon8718 已经建议的那样,我总是将生产数据库的新副本拉到我的登台服务器并测试要在登台服务器上应用的 EF 迁移,然后再将它们应用到生产服务器。 IMO 这对于生产系统的任何模式更新都是必不可少的,无论我是否使用 EF 迁移。
好吧,我会尽力回答的。我会说不,没有理由不在生产中使用代码优先迁移。毕竟,如果您不能一路走下去,那么这个易于使用的系统有什么意义呢?
我看到的最大问题是您已经注意到的任何系统都可能遇到的所有问题。只要整个团队(如果适用,包括 DBA)都参与其中,我认为允许 EF 通过迁移来管理架构就不那么复杂,因此比传统的基于脚本的管理更不容易出错。在生产系统上执行迁移之前,我仍然会进行备份,但无论如何你都会这样做。
也没有说 DBA 不能从 Visual Studio 执行迁移。在执行实际操作之前,仍然可以使用数据库级别的权限锁定访问权限,并且 he/she 可以检查迁移(如果需要,可以使用 -Script
以有用的 SQL 导出格式) .然后他们仍然处于控制之中,但您可以使用代码优先迁移。该死,他们甚至可能最终会喜欢它!
更新:自从 SPROC 和 TVF 出现以来,我们也在迁移中处理它们,尽管它们实际上是使用直接 SQL 语句在 Up()
,以及它们在 Down()
中的反向(对于简单的 SPROC,您也可以使用 CreateStoredProcedure
和 DropStoredProcedure
,但我认为您仍然必须在 SQL).我想你可以说这是一个警告;目前还没有一种方法可以完全用 C# 编写一个完整的综合数据库。但是,您 可以 使用包含 SQL 脚本的迁移来管理整个架构。我们从这个过程中发现的一个好处是,您可以将 C# 配置文件用于架构对象名称(例如,用于生产和开发的不同服务器名称),通过简单的 String.Format
,结合 XML 转换配置文件本身。
我在几个项目的生产中使用它。一旦你掌握了它,我觉得它很好。
在开发过程中,您可以保持自动迁移,但最后您可以直接从包管理器控制台连接到实时数据库并生成迁移。它将为您提供所有更改的一次迁移。
但始终始终将 -script
选项与 update-database
一起使用,然后自己触发 SQL。
我还建议不要使用网络部署中的更新数据库选项。这样就无法判断有多少迁移已经因错误而被触发。我已经 运行 遇到过几次这样的麻烦。所以最好获取 SQL 并手动触发它。
是的,有很好的理由不使用自动化系统(例如代码优先迁移)来进行生产数据库更改。但一如既往,规则也有例外。
提到的一个原因是访问权限,这与您组织的变更管理规则和安全策略直接相关。
另一个原因是您对迁移工具本身的信任程度。我们确定该工具没有错误吗?如果工具在中途失败怎么办?您确定您有最新的备份和一个在需要时回滚的过程吗?
更改脚本可能会执行意外或低效的脚本。我遇到过 sql 生成将数据复制到临时 table,删除原始 table,然后重新创建原始 table 以添加新列等情况如果您不小心(或有意)更改了列的显示顺序,或者重命名 table。如果涉及数百万条记录,这可能会导致严重的性能问题。
我的推荐:
假设您有一个反映生产模式的登台数据库,请使用迁移工具针对该系统生成其更改脚本。我们通常在 运行ning 之前从新的生产副本恢复阶段数据库。然后我们手动检查更改脚本以检查问题。在那之后,我们 运行 针对我们的阶段数据库的脚本,以确保它正确执行并且所有预期的更改都发生了。现在我们确定这些脚本在生产中对 运行 都是安全的,并且可以执行预期的更改。此过程将解决我上面列出的所有三个问题。
我发现的另一个注意事项:如果您有多个网站使用相同的数据上下文,则需要确保所有网站都同时更新。否则网站之间可能会发生持续的数据库更新/降级斗争。除此之外,它对我来说效果很好。
编辑:开始在生产中使用 EF 迁移一年后我自己的观点:
EF Migrations 实际上非常酷,即使是用于生产,前提是您
- 在暂存系统上测试迁移。在 运行 集成测试之前,我通过在我的 CI 服务器上一路上下迁移来测试所有迁移。
- 不自动触发迁移,而是使用管理员启动的批处理文件。这与在 SSMS 中手动迁移的 运行 和 sql 基本相同。