【问题标题】:What are the best practices for database scripts under code control代码控制下的数据库脚本的最佳实践是什么
【发布时间】:2010-09-25 07:58:59
【问题描述】:

我们目前正在审查如何在 subversion 中存储我们的数据库脚本(表、过程、函数、视图、数据修复),我想知道对于最佳方法是否有任何共识?

我们需要考虑的一些因素包括:

  • 我们应该签入“创建”脚本还是使用“更改”脚本签入增量更改
  • 我们如何跟踪给定版本的数据库状态
  • 应该很容易为任何给定的发行版本从头开始构建数据库
  • 数据库中是否应该存在一个表,列出针对它运行的脚本,或者数据库的版本等。

显然这是一个非常开放的问题,所以我很想听听人们的经验教会了他们什么。

【问题讨论】:

    标签: database svn version-control


    【解决方案1】:

    经过几次迭代,我们采取的方法大致是这样的:

    每个表和每个存储过程一个文件。还要为其他事情分开文件,例如设置数据库用户,用他们的数据填充查找表。

    表的文件以 CREATE 命令开始,并随着架构的发展而添加一系列 ALTER 命令。在测试表或列是否已经存在时,这些命令中的每一个都用括号括起来。这意味着每个脚本都可以在最新的数据库中运行,并且不会更改任何内容。这也意味着对于任何旧数据库,脚本都会将其更新为最新模式。对于空数据库,CREATE 脚本会创建表,并且会跳过 ALTER 脚本。

    我们还有一个程序(用 Python 编写),它扫描充满脚本的目录并将它们组合成一个大脚本。它解析 SQL 以推断表之间的依赖关系(基于外键引用)并适当地对它们进行排序。结果是一个怪物 SQL 脚本,它可以一次性使数据库达到规范。脚本组装程序还计算输入文件的 MD5 哈希,并使用它来更新写入列表中最后一个脚本的特殊表中的版本号。

    除非发生意外,结果是给定版本的源代码的数据库脚本创建了该代码旨在与之互操作的架构。这也意味着有一个(有点大的)SQL 脚本可以提供给客户来构建新数据库或更新现有数据库。 (这在这种情况下很重要,因为会有很多数据库实例,每个客户都有一个。)

    【讨论】:

      【解决方案2】:

      这个链接有一篇有趣的文章: https://blog.codinghorror.com/get-your-database-under-version-control/

      它提倡基线“创建”脚本,然后签入“更改”脚本并在数据库中保留版本表。

      【讨论】:

        【解决方案3】:

        升级脚本选项

        将数据库中的每个更改存储为单独的 sql 脚本。将每组更改存储在编号文件夹中。使用脚本一次应用更改一个文件夹,并在数据库中记录已应用的文件夹。

        优点: 完全自动化、可测试的升级路径

        缺点: 很难看到每个元素的完整历史 必须从头开始构建一个新数据库,遍历所有版本

        【讨论】:

          【解决方案4】:

          我倾向于检查初始创建脚本。然后,我的数据库中有一个 DbVersion 表,如果需要,我的代码在初始连接时使用它来升级数据库。例如,如果我的数据库是第 1 版,而我的代码是第 3 版,我的代码将应用 ALTER 语句将其带到第 2 版,然后再到第 3 版。为此,我使用了一个简单的 fallthrough switch 语句。

          这样做的好处是,当您部署新版本的应用程序时,它会自动升级旧数据库,您不必担心数据库与软件不同步。它还保留了一个非常明显的更改历史记录。

          这并不是对所有软件都是一个好主意,但可以应用变体。

          【讨论】:

            【解决方案5】:

            您可以通过阅读Ruby On Rails' migrations 的实现方式获得一些提示。 理解这一点的最好方法可能是自己尝试一下,然后手动检查数据库。

            对每个因素的回答:

            • 存储 CREATE 脚本。如果您想检查版本 x.y.z,那么只需运行您的创建脚本来立即设置数据库会很好。您可以添加 ALTER 脚本以从上一个版本转到下一个版本(例如,您提交版本 3,其中包含一个版本 3 CREATE 脚本和一个版本 2 → 3 更改脚本)。
            • 请参阅 Rails 迁移解决方案。基本上他们将表版本号保存在数据库中,所以你总是知道的。
            • 使用 CREATE 脚本。
            • 使用版本号可能是最通用的解决方案 - 脚本名称和路径会随着时间而改变。

            我的两分钱!

            【讨论】:

              【解决方案6】:

              我们在 Subversion 中创建了一个分支,下一个版本的所有数据库更改都被脚本化并签入。所有脚本都是可重复的,因此您可以多次运行它们而不会出错。

              我们还将更改脚本链接到问题项或错误 ID,以便我们可以在需要时保留更改集。然后,我们有一个自动构建过程,它查看我们正在发布的问题项,并从 Subversion 中提取更改脚本,并创建一个 SQL 脚本文件,其中所有更改都经过适当排序。

              然后使用这个单一文件来促进对测试、QA 和生产环境的更改。自动构建过程还创建记录版本的数据库条目(分支加上构建 ID)。我们认为这是企业开发人员的最佳方法。关于我们如何做到这一点的更多细节可以找到HERE

              【讨论】:

                【解决方案7】:

                创建脚本选项:

                使用创建脚本从头开始构建最新版本的数据库,除了默认的查找数据外,它是空的。

                使用标准版本控制技术来存储、分支、标记版本并查看对象的历史记录。

                升级实时数据库时(您不想丢失数据),在新版本中创建数据库的第二个空白副本并使用 red-gate 的 link text 之类的工具

                优点: 以类似源代码的标准方式跟踪文件的更改

                缺点: 依赖手动使用 3rd 方工具进行实际升级(无/很少自动化)

                【讨论】:

                  【解决方案8】:

                  我们公司签入它们只是因为有人决定将其放入我们所做的某些 SOX 文档中。这对我来说毫无意义,除非可以作为参考文件。我看不出有什么时候我们会把它们拉出来并尝试再次使用它们,如果我们这样做了,我们就必须知道哪个先运行,然后再运行哪个。备份数据库比保留 Alter 脚本更重要。

                  【讨论】:

                  • 我确信它们只是从 SOX 文档的角度保留的,因此您可以向审核员(如果他们询问)显示执行了哪些更改。
                  • 当然,能够向自己展示所做的更改同样重要。
                  【解决方案9】:

                  对于每个版本,我们需要提供一个 update.sql 文件,其中包含所有新的表脚本、alter 语句、新/修改的包、角色等。此文件用于将数据库从 1 版本升级到 2。

                  我们在 update.sql 文件中包含的所有这些语句都需要转到各个文件。像 alter 语句必须作为新列进入表(必须修改表脚本,而不是在文件中创建表脚本后添加 Alter 语句)以相同的方式新表、角色等。

                  因此,每当用户想要升级时,他都会使用第一个 update.sql 文件进行升级。 如果他想从头开始构建,那么他将使用已经包含上述所有语句的 build.sql,它使数据库同步。

                  斯里拉穆鲁 Sriramis4u@yahoo.com

                  【讨论】:

                    【解决方案10】:

                    就我而言,我为这项工作构建了一个 SH 脚本:https://github.com/reduardo7/db-version-updater

                    【讨论】:

                      【解决方案11】:

                      悬而未决的问题

                      就我而言,我正在尝试创建一些易于开发人员使用的简单东西,我按照以下方案进行操作

                      我测试的东西: 使用 GitlabCI 在 git 中处理基于文件的脚本

                      • 它不起作用,会产生碰撞,管理部分必须手动完成,以防万一,开发部分太复杂

                      • 通过mysql客户端使用权限和访问 对数据库的更改没有可追溯性,并且向生产的过渡是手动的

                      • 使用此处提到的程序 他们需要上传结构和许多改编,通常你最终会像这个词一样获得变更控制

                      • 存储库使用情况 无法控制 DRP 部分 我无法正确控制备份 我认为在同一台服务器上进行备份并不是一个好主意,并且会为该过程生成高延迟

                      • 这是最有效的方法

                      • 管理每个用户的权限并生成发送到数据库的所有内容的可追溯性

                      • 多平台

                      • 开发-生产-QA数据库的使用

                      • 每次修改前始终支持

                      • 管理用于更改控制的开放存储库

                      • 多服务器

                      • 通过端点停用/激活对网页或应用程序的访问

                      • 初始项目在:

                      • 如果评论经理阅读了这部分,我理解自我推销,但请删除这部分并留下其余部分,因为我认为它符合帖子中对问题作出反应的答案...... https://hub.docker.com/r/arelis/gitdb

                      我希望这能传达给你,因为我看到了几个

                      【讨论】:

                        【解决方案12】:

                        有一篇有趣的文章带有新的 URL:https://blog.codinghorror.com/get-your-database-under-version-control/

                        它有点旧,但概念仍然存在。好书!

                        【讨论】:

                          猜你喜欢
                          • 1970-01-01
                          • 2015-07-20
                          • 1970-01-01
                          • 1970-01-01
                          • 2017-12-21
                          • 1970-01-01
                          • 2021-09-18
                          • 1970-01-01
                          • 1970-01-01
                          相关资源
                          最近更新 更多