我想让我的数据库处于版本控制之下。

我总是希望在那里至少有一些数据(如alumb提到的:用户类型和管理员)。我还经常需要大量生成的测试数据来进行性能度量。

如何对数据库应用版本控制?


当前回答

在迁移到x64平台后,我们需要对SQL数据库进行版本调整,而旧版本在迁移过程中出现了问题。我们写了一个c#应用程序,使用sqlmo将所有SQL对象映射到一个文件夹:

                Root
                    ServerName
                       DatabaseName
                          Schema Objects
                             Database Triggers*
                                .ddltrigger.sql
                             Functions
                                ..function.sql
                             Security
                                Roles
                                   Application Roles
                                      .approle.sql
                                   Database Roles
                                      .role.sql
                                Schemas*
                                   .schema.sql
                                Users
                                   .user.sql
                             Storage
                                Full Text Catalogs*
                                   .fulltext.sql
                             Stored Procedures
                                ..proc.sql
                             Synonyms*
                                .synonym.sql
                             Tables
                                ..table.sql
                                Constraints
                                   ...chkconst.sql
                                   ...defconst.sql
                                Indexes
                                   ...index.sql
                                Keys
                                   ...fkey.sql
                                   ...pkey.sql
                                   ...ukey.sql
                                Triggers
                                   ...trigger.sql
                             Types
                                User-defined Data Types
                                   ..uddt.sql
                                XML Schema Collections*
                                   ..xmlschema.sql
                             Views
                                ..view.sql
                                Indexes
                                   ...index.sql
                                Triggers
                                   ...trigger.sql

然后,应用程序将新编写的版本与存储在SVN中的版本进行比较,如果存在差异,则更新SVN。 我们确定每晚运行一次流程就足够了,因为我们没有对SQL做那么多更改。它允许我们跟踪所有我们关心的对象的变化,并且允许我们在发生严重问题时重新构建完整的模式。

其他回答

典型的解决方案是根据需要转储数据库并备份这些文件。

根据您的开发平台,可能会有可用的开源插件。编写自己的代码来完成这个任务通常是相当简单的。

注意:您可能希望备份数据库转储,而不是将其放入版本控制中。在版本控制中,文件可能会迅速变大,并导致整个源代码控制系统变慢(我正在回忆CVS的恐怖故事)。

版本控制数据库的另一种选择是使用版本控制数据库,现在有几个这样的数据库。

https://www.dolthub.com/blog/2021-09-17-database-version-control/

这些产品没有在其他类型的数据库上应用版本控制——它们是自己的数据库引擎,支持版本控制操作。因此,您需要迁移到它们,或者在它们的基础上开始构建。

我编写了其中一个,DoltDB,它结合了MySQL和Git的接口。看看这里:

https://github.com/dolthub/dolt

关于这个主题,Martin Fowler写了一篇我最喜欢的文章http://martinfowler.com/articles/evodb.html。我选择不像alumb和其他人建议的那样将模式转储放在版本控制下,因为我想要一种简单的方法来升级我的生产数据库。

对于一个web应用程序,我将有一个生产数据库实例,我使用两种技术:

数据库升级脚本

一个序列数据库升级脚本,其中包含将模式从版本N移动到版本N+1所需的DDL。(这些会进入你的版本控制系统。)一个_version_history_表,类似于

create table VersionHistory (
    Version int primary key,
    UpgradeStart datetime not null,
    UpgradeEnd datetime
    );

每次运行与新版本对应的升级脚本时获取一个新条目。

这可以确保很容易查看数据库模式的版本,并且数据库升级脚本只运行一次。同样,这些不是数据库转储。相反,每个脚本表示从一个版本迁移到下一个版本所需的更改。它们是应用于生产数据库以“升级”它的脚本。

开发人员沙箱同步

备份、清理和收缩生产数据库的脚本。在每次升级到生产DB后运行此命令。 在开发人员的工作站上恢复(并在必要时调整)备份的脚本。每个开发人员在每次升级到生产DB后都会运行此脚本。

警告:我的自动化测试运行在模式正确但空的数据库上,因此这个建议不能完全满足您的需求。

在Red Gate,我们提供了一个工具,SQL Source Control,它使用SQL Compare技术将数据库与TFS或SVN存储库链接起来。该工具集成到SSMS中,让您像往常一样工作,只是现在允许提交对象。

对于基于迁移的方法(更适合于自动化部署),我们提供了SQL Change Automation(以前称为ReadyRoll),它作为Visual Studio项目创建和管理一组增量脚本。

在SQL源代码控制中,可以指定静态数据表。它们作为INSERT语句存储在源代码控制中。

如果您正在讨论测试数据,我们建议您要么使用工具生成测试数据,要么通过您定义的部署后脚本生成测试数据,要么简单地将生产备份恢复到开发环境。

我同意ESV的答案,正是出于这个原因,我开始了一个小项目,以帮助维护一个非常简单的文件中的数据库更新,然后可以在一个很长的源代码之外进行维护。它允许对开发人员以及UAT和生产进行轻松的更新。该工具适用于SQL Server和MySQL。

项目的一些特点:

允许模式更改 允许值树填充 允许单独的测试数据插入,例如。UAT 允许回滚选项(不是自动的) 维护对SQL server和MySQL的支持 有能力导入现有的数据库到版本控制与一个简单的命令(SQL server仅…仍在开发MySQL)

请查看代码以获得更多信息。