代码控制下的数据库脚本的最佳实践是什么?

时间:2008-12-04 13:42:21

标签: database svn version-control

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

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

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

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

12 个答案:

答案 0 :(得分:18)

经过几次迭代后,我们采用的方法大致如下:

每个表和每个存储过程一个文件。还可以为其他内容分隔文件,例如设置数据库用户,使用数据填充查找表。

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

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

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

答案 1 :(得分:2)

通过阅读使用Ruby On Rails' migrations完成此操作的方法,您可以获得一些提示。 了解这一点的最好方法可能是自己尝试一下,然后手动检查数据库。

您的每个因素的答案:

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

我的两分钱!

答案 2 :(得分:2)

升级脚本选项

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

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

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

答案 3 :(得分:2)

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

这样做的好处是,当您部署新版本的应用程序时,它将自动升级旧数据库,您永远不必担心数据库与软件不同步。它还保持着非常明显的变化历史。

这对所有软件来说都不是一个好主意,但可以应用各种变化。

答案 4 :(得分:2)

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

它提倡基线'create'脚本,然后检入'alter'脚本并在数据库中保留一个版本表。

答案 5 :(得分:1)

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

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

然后使用此单个文件来促进对Test,QA和Production环境的更改。自动构建过程还会创建记录版本(分支加构建ID)的数据库条目。我们认为这是企业开发人员的最佳方法。有关我们如何执行此操作的详细信息,请参见HERE

答案 6 :(得分:0)

创建脚本选项:

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

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

升级实时数据库(您不想丢失数据)时,在新版本中创建数据库的空白第二份副本,并使用红门link text

等工具

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

缺点: 依赖手动使用第三方工具进行实际升级(无/自动化程度较低)

答案 7 :(得分:0)

我们公司检查它们只是因为有人决定把它放在我们做的SOX文件中。除了可能作为参考文件之外,对我来说根本没有意义。我看不出有时候我们把它们拉出去并尝试再次使用它们,如果我们这样做了,我们必须知道哪一个首先运行,哪一个运行之后。备份数据库比保留Alter脚本更重要。

答案 8 :(得分:0)

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

我们在update.sql文件中包含的内容之一,所有这些语句需要转到各自的相应文件。像alter statement一样,必须将表作为一个新列(表脚本必须修改,而不是在文件中创建表脚本后添加Alter语句),方法与新表,角色等相同。

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

sriRamulu Sriramis4u@yahoo.com

答案 9 :(得分:0)

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

答案 10 :(得分:0)

开放式问题如何

在我的情况下,我正在尝试创建易于开发人员使用的简单内容,并且按照以下方案进行操作

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

  • 它不起作用,会发生冲突,如果发生灾难并且开发部分过于复杂,则必须手动执行管理部分

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

  • 此处提到的程序的使用 他们需要上载结构和许多改编本,通常您会像单词一样

  • 存储库使用情况 无法控制DRP部分 我无法正确控制备份 我认为将备份存储在同一台服务器上并不是一个好主意,这样会为该过程带来很大的麻烦

  • 这是最有效的方法

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

  • 多平台

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

  • 每次修改之前始终支持

  • 管理开放式存储库以进行更改控制

  • 多服务器

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

  • 初始项目位于:

  • 万一评论管理者阅读了这一部分,我理解了自我提升,但请删除此部分,然后将其余部分留空,因为我认为它符合帖子中所回答问题的答案... https://hub.docker.com/r/arelis/gitdb

我希望这能给您带来帮助,因为我看到了几个

答案 11 :(得分:-1)

有一篇关于新网址的有趣文章:https://blog.codinghorror.com/get-your-database-under-version-control/

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