我想让我的数据库受到版本控制。有人有任何建议或推荐文章来帮助我入门吗?

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

有帮助吗?

解决方案

马丁·福勒(Martin Fowler)写了我最喜欢的关于这个主题的文章, http://martinfowler.com/articles/evodb.html. 。我选择不将架构转储置于版本控制之下,因为 明矾 和其他人建议是因为我想要一种简单的方法来升级我的生产数据库。

对于具有单个生产数据库实例的 Web 应用程序,我使用两种技术:

数据库升级脚本

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

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

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

这可确保轻松查看存在的数据库模式版本,并且数据库升级脚本仅运行一次。再说一次,这些是 不是 数据库转储。相反,每个脚本代表 变化 需要从一个版本移动到下一个版本。它们是您应用于生产数据库以“升级”它的脚本。

开发者沙箱同步

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

警告:我的自动化测试针对架构正确但为空的数据库运行,因此此建议不能完全满足您的需求。

其他提示

Red Gate 的 SQL Compare 产品不仅允许您进行对象级比较并从中生成更改脚本,而且还允许您将数据库对象导出到按对象类型组织的文件夹层次结构中,只需创建一个 [objectname].sql这些目录中每个对象的脚本。对象类型层次结构如下:

\功能
\安全
\安全\角色
\安全\模式
\安全\用户
\存储过程
\表格

如果您在进行更改后将脚本转储到同一根目录,则可以使用它来更新 SVN 存储库,并单独保留每个对象的运行历史记录。

这是围绕发展的“难题”之一。据我所知,没有完美的解决方案。

如果您只需要存储数据库结构而不是数据,则可以将数据库导出为 SQL 查询。(在企业管理器中:右键单击数据库 -> 生成 SQL 脚本。我建议在选项选项卡上设置“每个对象创建一个文件”)然后您可以将这些文本文件提交到 svn 并利用 svn 的 diff 和日志记录功能。

我将其与批处理脚本结合在一起,该脚本采用几个参数并设置数据库。我还添加了一些额外的查询,用于输入默认数据,例如用户类型和管理员用户。(如果您想了解更多信息,请发布一些内容,我可以将脚本放在可访问的地方)

如果您还需要保留所有数据,我建议保留数据库的备份并使用 Redgate (http://www.red-gate.com/)产品进行比较。它们并不便宜,但每一分钱都物有所值。

首先,您必须选择适合您的版本控制系统:

  • 集中版本控制系统 - 一种标准系统,用户在处理文件之前/之后签出/签入,并且文件保存在单个中央服务器中

  • 分布式版本控制系统 - 将存储库克隆的系统,每个克隆实际上都是存储库的完整备份,因此,如果任何服务器崩溃,则可以使用任何克隆的存储库来恢复它,以便在满足您的需求之后选择正确的系统,您需要设置存储库,这是每个版本控制系统的核心,所有这些都将在以下文章中解释: http://solutioncenter.apexsql.com/sql-server-source-control-part-i-understanding-source-control-basics/

设置存储库后,如果是中央版本控制系统,则设置工作文件夹后,您可以阅读 本文. 。它展示了如何使用以下方法在开发环境中设置源代码控制:

  • SQL Server Management Studio 通过 MSSCCI 提供程序,

  • Visual Studio 和 SQL Server 数据工具

  • 第三方工具 ApexSQL 源代码管理

在红门,我们提供了一个工具, SQL 源代码控制, ,它使用 SQL Compare 技术将您的数据库与 TFS 或 SVN 存储库链接起来。该工具集成到 SSMS 中,让您可以像平常一样工作,只是它现在允许您提交对象。

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

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

如果您谈论的是测试数据,我们建议您使用工具或通过您定义的部署后脚本生成测试数据,或者只需将生产备份恢复到开发环境。

您可能想看看 Liquibase (http://www.liquibase.org/)。即使您不使用该工具本身,它也可以很好地处理数据库更改管理或重构的概念。

为所有推荐 RedGate 工具的人+1,并提供额外的推荐和警告。

SqlCompare 还有一个记录良好的 API:例如,您可以编写一个控制台应用程序,在签入时将源代码控制的脚本文件夹与 CI 集成测试数据库同步,这样当有人从脚本文件夹签入对架构的更改时,它会与匹配的应用程序一起自动部署代码更改。这有助于缩小与忘记将本地数据库中的更改传播到共享开发数据库的开发人员之间的差距(我认为大约是我们的一半:))。

需要注意的是,无论是脚本解决方案还是其他解决方案,RedGate 工具都足够流畅,因此很容易忘记抽象背后的 SQL 现实。如果重命名表中的所有列,SqlCompare 无法将旧列映射到新列,并且会删除表中的所有数据。它会生成警告,但我看到人们点击了它。我认为,这里有一个普遍的观点值得提出,即到目前为止,您只能自动化数据库版本控制和升级 - 抽象非常容易泄漏。

我们用 数据库幽灵 管理我们的 SQL 数据库。然后,您将脚本放在版本控制中构建新数据库,它将构建新数据库,或将任何现有数据库升级到版本控制中的架构。这样您就不必担心创建更改脚本(尽管您仍然可以这样做,例如您想要更改列的数据类型并需要转换数据)。

在 VS 2010 中,使用数据库项目。

  1. 编写数据库脚本
  2. 更改脚本或直接在DB服务器上
  3. 使用数据>架构比较

打造完美的数据库版本控制解决方案,并使同步数据库变得轻而易举。

这是一种使用更改脚本将数据库脚本保存到版本控制中的好方法,以便您可以升级您拥有的任何数据库。此外,您可能希望保存不同版本的架构,以便可以创建完整的数据库,而不必应用所有更改脚本。处理脚本应该是自动化的,这样您就不必进行手动工作。

我认为为每个开发人员拥有一个单独的数据库而不是使用共享数据库很重要。这样,开发人员可以独立于其他开发人员创建测试用例和开发阶段。

自动化工具应该具有处理数据库元数据的方法,它告诉哪些数据库处于什么开发状态以及哪些表包含版本可控数据等等。

您还可以查看迁移解决方案。这些允许您在 C# 代码中指定数据库架构,并使用 MSBuild 上下滚动数据库版本。

我目前正在使用 数据库, ,并且一直运行良好。

您没有提到有关目标环境或约束的任何细节,因此这可能并不完全适用......但是,如果您正在寻找一种有效跟踪不断发展的数据库模式的方法,并且不反对使用 Ruby 的想法,那么 ActiveRecord 的迁移正合您的胃口。

迁移使用 Ruby DSL 以编程方式定义数据库转换;每个转换都可以应用或(通常)回滚,从而允许您在任何给定时间点跳转到数据库模式的不同版本。定义这些转换的文件可以像任何其他源代码一样被签入版本控制。

因为迁移是其中的一部分 活动记录, ,它们通常用于全栈 Rails 应用程序;但是,您可以轻松地独立于 Rails 使用 ActiveRecord。看 这里 了解在 Rails 之外使用 AR 迁移的更详细处理。

每个数据库都应该处于源代码控制之下。缺少的是自动将所有数据库对象和“配置数据”写入文件的工具,然后可以将其添加到任何源代码控制系统中。如果您使用的是 SQL Server,那么我的解决方案在这里: http://dbsourcetools.codeplex.com/ 。玩得开心。- 内森。

这很简单。

  1. 当基础项目准备就绪后,您必须创建完整的数据库脚本。该脚本已提交至 SVN。这是第一个版本。

  2. 之后,所有开发人员创建更改脚本(ALTER...、新表、存储过程等)。

  3. 当您需要当前版本时,您应该执行所有新的更改脚本。

  4. 当应用程序发布到生产环境时,您将返回到 1(但当然它将是后续版本)。

Nant 将帮助您执行这些更改脚本。:)

请记住。当有纪律时,一切都会顺利进行。每次提交数据库更改时,代码中相应的函数也会提交。

如果您有一个小型数据库并且想要对整个数据库进行版本控制, 这个批处理脚本 可能有帮助。它将 MSSQL 数据库 MDF 文件分离、压缩并签入 Subversion。

如果您主要想对架构进行版本控制并且只有少量参考数据,则可以使用 亚音速迁移 来处理这个问题。这样做的好处是您可以轻松地向上或向下迁移到任何特定版本。

为了使转储到源代码控制系统的速度更快一些,您可以使用 sysobjects 中的版本信息来查看自上次以来哪些对象已更改。

设置: 在要增量检查的每个数据库中创建一个表,以保存上次检查时的版本信息(第一次运行时为空)。如果您想重新扫描整个数据结构,请清除此表。

IF ISNULL(OBJECT_ID('last_run_sysversions'), 0) <> 0 DROP TABLE last_run_sysversions
CREATE TABLE last_run_sysversions (
    name varchar(128), 
    id int, base_schema_ver int,
    schema_ver int,
    type char(2)
)

正常运行模式: 您可以从此 sql 中获取结果,并为您感兴趣的结果生成 sql 脚本,并将它们放入您选择的源代码管理中。

IF ISNULL(OBJECT_ID('tempdb.dbo.#tmp'), 0) <> 0 DROP TABLE #tmp
CREATE TABLE #tmp (
    name varchar(128), 
    id int, base_schema_ver int,
    schema_ver int,
    type char(2)
)

SET NOCOUNT ON

-- Insert the values from the end of the last run into #tmp
INSERT #tmp (name, id, base_schema_ver, schema_ver, type) 
SELECT name, id, base_schema_ver, schema_ver, type FROM last_run_sysversions

DELETE last_run_sysversions
INSERT last_run_sysversions (name, id, base_schema_ver, schema_ver, type)
SELECT name, id, base_schema_ver, schema_ver, type FROM sysobjects

-- This next bit lists all differences to scripts.
SET NOCOUNT OFF

--Renamed.
SELECT 'renamed' AS ChangeType, t.name, o.name AS extra_info, 1 AS Priority
FROM sysobjects o INNER JOIN #tmp t ON o.id = t.id
WHERE o.name <> t.name /*COLLATE*/
AND o.type IN ('TR', 'P' ,'U' ,'V')
UNION 

--Changed (using alter)
SELECT 'changed' AS ChangeType, o.name /*COLLATE*/, 
       'altered' AS extra_info, 2 AS Priority
FROM sysobjects o INNER JOIN #tmp t ON o.id = t.id 
WHERE (
   o.base_schema_ver <> t.base_schema_ver
OR o.schema_ver      <> t.schema_ver
)
AND  o.type IN ('TR', 'P' ,'U' ,'V')
AND  o.name NOT IN ( SELECT oi.name 
         FROM sysobjects oi INNER JOIN #tmp ti ON oi.id = ti.id
         WHERE oi.name <> ti.name /*COLLATE*/
         AND oi.type IN ('TR', 'P' ,'U' ,'V')) 
UNION

--Changed (actually dropped and recreated [but not renamed])
SELECT 'changed' AS ChangeType, t.name, 'dropped' AS extra_info, 2 AS Priority
FROM #tmp t
WHERE    t.name IN ( SELECT ti.name /*COLLATE*/ FROM #tmp ti
         WHERE NOT EXISTS (SELECT * FROM sysobjects oi
                           WHERE oi.id = ti.id))
AND  t.name IN ( SELECT oi.name /*COLLATE*/ FROM sysobjects oi
         WHERE NOT EXISTS (SELECT * FROM #tmp ti
                           WHERE oi.id = ti.id)
         AND   oi.type  IN ('TR', 'P' ,'U' ,'V'))
UNION

--Deleted
SELECT 'deleted' AS ChangeType, t.name, '' AS extra_info, 0 AS Priority
FROM #tmp t
WHERE NOT EXISTS (SELECT * FROM sysobjects o
                  WHERE o.id = t.id)
AND t.name NOT IN (  SELECT oi.name /*COLLATE*/ FROM sysobjects oi
         WHERE NOT EXISTS (SELECT * FROM #tmp ti
                           WHERE oi.id = ti.id)
         AND   oi.type  IN ('TR', 'P' ,'U' ,'V'))
UNION

--Added
SELECT 'added' AS ChangeType, o.name /*COLLATE*/, '' AS extra_info, 4 AS Priority
FROM sysobjects o
WHERE NOT EXISTS (SELECT * FROM #tmp t
                  WHERE o.id = t.id)
AND      o.type  IN ('TR', 'P' ,'U' ,'V')
AND  o.name NOT IN ( SELECT ti.name /*COLLATE*/ FROM #tmp ti
         WHERE NOT EXISTS (SELECT * FROM sysobjects oi
                           WHERE oi.id = ti.id))
ORDER BY Priority ASC

笔记: 如果您在任何数据库中使用非标准排序规则,则需要替换 /* COLLATE */ 与您的数据库排序规则。IE。 COLLATE Latin1_General_CI_AI

因为我们的应用程序必须跨多个 RDBMS 工作,所以我们使用数据库中立的方法将架构定义存储在版本控制中 扭矩 格式(XML)。我们还对 XML 格式的数据库参考数据进行版本控制,如下所示(其中“关系”是参考表之一):

  <Relationship RelationshipID="1" InternalName="Manager"/>
  <Relationship RelationshipID="2" InternalName="Delegate"/>
  etc.

然后,我们使用自制工具生成从数据库版本 X 到版本 X + 1 所需的模式升级和参考数据升级脚本。

我们不存储数据库模式,而是存储对数据库的更改。我们所做的是存储架构更改,以便我们为任何版本的数据库构建更改脚本并将其应用到客户的数据库。我编写了一个数据库实用程序应用程序,它与我们的主应用程序一起分发,它可以读取该脚本并知道需要应用哪些更新。它还具有足够的智能来根据需要刷新视图和存储过程。

在迁移到 x64 平台后,我们需要对 SQL 数据库进行版本控制,但旧版本因迁移而中断。我们编写了一个 C# 应用程序,它使用 SQLDMO 将所有 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 进行太多更改。它允许我们跟踪我们关心的所有对象的更改,并且它允许我们在出现严重问题时重建完整的模式。

我不久前写了这个应用程序, http://sqlschemasourcectrl.codeplex.com/ 它将按照您想要的频率扫描您的 MSFT SQL 数据库,并自动将您的对象(表、视图、过程、函数、sql 设置)转储到 SVN 中。奇迹般有效。我将它与 Unfuddle 一起使用(它允许我在签到时收到警报)

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

根据您的开发平台,可能有可用的开源插件。滚动您自己的代码来完成此操作通常相当简单。

笔记:您可能想要备份数据库转储而不是将其置于版本控制中。这些文件在版本控制中可能会变得非常快,并导致整个源代码控制系统变得缓慢(我现在回想起 CVS 的恐怖故事)。

我们刚刚开始使用 Team Foundation Server。如果您的数据库是中等规模,那么 Visual Studio 有一些很好的项目集成,其中包含内置比较、数据比较、数据库重构工具、数据库测试框架,甚至数据生成工具。

但是,该模型不太适合非常大的数据库或第三方数据库(加密对象)。所以,我们所做的就是只存储我们定制的对象。Visual Studio / Team Foundation Server 对此非常有效。

TFS 数据库首席架构师。博客

MS TFS 站点

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

一些项目特点:

  • 允许架构更改
  • 允许值树填充
  • 允许单独的测试数据插入,例如。UAT
  • 允许回滚选项(非自动)
  • 保持对 SQL Server 和 Mysql 的支持
  • 能够通过一个简单的命令将现有数据库导入版本控制(仅限 sql server ...仍在mysql上工作)

该代码托管在谷歌代码上。请查看 Google 代码以获取更多信息

http://code.google.com/p/databaseversioncontrol/

不久前,我发现了一个 VB bas 模块,它使用 DMO 和 VSS 对象来将整个数据库脚本化并写入 VSS。我把它变成了VB脚本并发布了 这里. 。您可以轻松地取出 VSS 调用并使用 DMO 生成所有脚本,然后从调用 VBScript 的同一个批处理文件中调用 SVN 来签入它们?

戴夫·J

我还使用通过数据库扩展属性过程系列存储的数据库中的版本。我的应用程序具有每个版本步骤的脚本(即从 1.1 移至 1.2)。部署后,它会查看当前版本,然后逐个运行脚本,直到到达最后一个应用程序版本。没有脚本具有直接的“最终”版本,即使部署在干净的数据库上也会通过一系列升级步骤进行部署。

现在我想补充的是,两天前我在 MS 校园看到了一个关于新的和即将推出的 VS DB 版本的演示。演讲专门针对这个主题,我惊呆了。您绝对应该检查一下,新工具专注于在 T-SQL 脚本 (CREATE) 中保留模式定义,这是一个运行时增量引擎,用于将部署模式与定义的模式进行比较,并执行增量更改以及与源代码集成的集成,最多并包括用于自动构建下降的 MSBUILD 持续集成。该drop将包含一个新的文件类型,即.dbschema文件,可以将其带到部署站点,并且命令行工具可以执行实际的“增量”并运行部署。我有一篇关于此主题的博客文章,其中包含 VSDE 下载的链接,您应该查看它们: http://rusanu.com/2009/05/15/version-control-and-your-database/

这是一个非常古老的问题,但许多人现在仍在尝试解决这个问题。他们所要做的就是研究 Visual Studio 数据库项目。如果没有这一点,任何数据库开发都会显得非常无力。从代码组织到部署再到版本控制,它简化了一切。

根据我的经验,解决方案有两个:

  1. 您需要处理多个开发人员在开发过程中对开发数据库所做的更改。

  2. 您需要处理客户站点中的数据库升级。

为了处理#1,您需要一个强大的数据库差异/合并工具。最好的工具应该能够尽可能地执行自动合并,同时允许您手动解决未处理的冲突。

完美的工具应该通过使用 3 路合并算法来处理合并操作,该算法考虑到 THEIRS 数据库和 MINE 数据库中相对于 BASE 数据库所做的更改。

我编写了一个商业工具,为 SQLite 数据库提供手动合并支持,目前我正在为 SQLite 添加对 3 路合并算法的支持。检查一下: http://www.sqlitecompare.com

为了处理#2,您将需要一个适当的升级框架。

基本思想是开发一个自动升级框架,该框架知道如何从现有的 SQL 模式升级到较新的 SQL 模式,并且可以为每个现有的数据库安装构建升级路径。

查看我关于该主题的文章 http://www.codeproject.com/KB/database/sqlite_upgrade.aspx 大致了解我在说什么。

祝你好运

利隆·莱维

查看 DBGhost http://www.innovartis.co.uk/. 。我已经以自动化方式使用了两年,效果非常好。它允许我们的数据库构建就像 Java 或 C 构建一样,除了数据库之外。你知道我的意思。

我建议使用比较工具为您的数据库临时建立一个版本控制系统。一个好的选择是 xSQL 架构比较xSQL 数据比较.

现在,如果您的目标是仅将数据库的架构置于版本控制之下,您可以简单地使用 xSQL Schema Compare 来生成架构的 xSQL 快照并将这些文件添加到版本控制中。然后,要恢复或更新到特定版本,只需将数据库的当前版本与目标版本的快照进行比较即可。

唉,如果您也希望将数据置于版本控制之下,您可以使用 xSQL Data Compare 为您的数据库生成更改脚本,并将 .sql 文件添加到版本控制中。然后,您可以执行这些脚本来恢复/更新到您想要的任何版本。请记住,对于“恢复”功能,您需要生成更改脚本,执行后将使版本 3 与版本 2 相同,而对于“更新”功能,您需要生成执行相反操作的更改脚本。

最后,凭借一些基本的批处理编程技能,您可以使用 xSQL Schema Compare 和 xSQL Data Compare 的命令行版本来自动化整个过程

免责声明:我隶属于 xSQL。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top