Zac*_*son 306 database svn sql-server version-control
我想让我的数据库受版本控制.有没有人有任何建议或推荐的文章让我开始?
我总是希望在那里至少有一些数据(如alumb提到的:用户类型和管理员).我还经常需要大量生成的测试数据来进行性能测量.
ESV*_*ESV 174
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
);
Run Code Online (Sandbox Code Playgroud)
每次运行与新版本对应的升级脚本时,都会获取一个新条目.
这样可以确保很容易看到存在哪个版本的数据库模式,并且数据库升级脚本只运行一次.同样,这些不是数据库转储.相反,每个脚本代表从一个版本移动到下一个版本所需的更改.它们是您应用于生产数据库以"升级"它的脚本.
警告:我的自动化测试是针对模式正确但空的数据库运行的,因此这个建议不能完全满足您的需求.
Dan*_*ane 45
Red Gate的SQL Compare产品不仅允许您进行对象级比较,并从中生成更改脚本,而且还允许您将数据库对象导出到按对象类型组织的文件夹层次结构中,并创建一个[objectname] .sql这些目录中每个对象的脚本.对象类型层次结构如下:
\ Functions
\ Security
\ Security\Roles
\ Security\Schemas
\ Security\Users
\ Stored Procedures
\ Tables
如果在进行更改后将脚本转储到同一根目录,则可以使用它来更新SVN仓库,并单独保留每个对象的运行历史记录.
alu*_*umb 39
这是围绕发展的"难题"之一.据我所知,没有完美的解决方案.
如果只需要存储数据库结构而不是数据,则可以将数据库导出为SQL查询.(在企业管理器中:右键单击数据库 - >生成SQL脚本.我建议在选项选项卡上设置"为每个对象创建一个文件")然后,您可以将这些文本文件提交到svn并使用svn的diff和logging函数.
我把它与批处理脚本绑在一起,该脚本需要几个参数并设置数据库.我还添加了一些其他查询,用于输入默认数据,如用户类型和管理员用户.(如果你想了解更多信息,发布一些内容,我可以将脚本放在某处)
如果您还需要保留所有数据,我建议保留数据库的备份并使用Redgate(http://www.red-gate.com/)产品进行比较.它们并不便宜,但它们值得每一分钱.
小智 38
首先,您必须选择适合您的版本控制系统:
集中版本控制系统 - 用户在处理文件之前/之后签出/签入的标准系统,文件保存在单个中央服务器中
分布式版本控制系统 - 正在克隆存储库的系统,每个克隆实际上是存储库的完整备份,因此如果任何服务器崩溃,则可以使用任何克隆的存储库来恢复它在为您的需求选择正确的系统之后,您需要设置存储库,这是每个版本控制系统的核心所有这些都在以下文章中解释:http://solutioncenter.apexsql.com/sql-server-source-control-part-i-understanding -source -控制-基础/
设置存储库后,如果中央版本控制系统是工作文件夹,您可以阅读本文.它显示了如何使用以下方法在开发环境中设置源代码管理:
SQL Server Management Studio通过MSSCCI提供程序,
Visual Studio和SQL Server数据工具
Dav*_*son 24
在Red Gate,我们提供了一个工具SQL Source Control,它使用SQL Compare技术将您的数据库与TFS或SVN存储库相链接.此工具集成到SSMS中,让您可以像平常一样工作,除了它现在允许您提交对象.
对于基于迁移的方法(更适合自动部署),我们提供SQL Change Automation(以前称为ReadyRoll),它创建和管理一组增量脚本作为Visual Studio项目.
在SQL源代码管理中,可以指定静态数据表.它们作为INSERT语句存储在源代码管理中.
如果您正在讨论测试数据,我们建议您使用工具或通过您定义的部署后脚本生成测试数据,或者只是将生产备份还原到开发环境.
ale*_*edy 18
每个推荐RedGate工具的人都需要+1,并附加建议和警告.
SqlCompare还有一个体面的文档API:例如,您可以编写一个控制台应用程序,它将您的源控制脚本文件夹与签入时的CI集成测试数据库同步,以便当有人从脚本文件夹中检查对架构的更改时它会随着匹配的应用程序代码更改自动部署.这有助于缩小与那些忘记将本地数据库中的更改传播到共享开发数据库的开发人员的差距(我认为大约有一半,我认为:)).
需要注意的是,使用脚本解决方案或其他方法,RedGate工具非常流畅,很容易忘记抽象背后的SQL现实.如果重命名表中的所有列,则SqlCompare无法将旧列映射到新列,并将删除表中的所有数据.它会产生警告,但我看到有人点击过去.我认为,这里有一个普遍的观点,即到目前为止你只能实现数据库版本控制和升级的自动化 - 抽象是非常漏洞的.
rom*_*n m 15
使用VS 2010,使用数据库项目.
制作完美的数据库版本控制解决方案,使数据库同步变得轻而易举.
Sil*_*ode 13
使用更改脚本将数据库脚本保存到版本控制是一种很好的方法,这样您就可以升级任何一个数据库.此外,您可能希望为不同版本保存模式,以便您可以创建完整数据库而无需应用所有更改脚本.处理脚本应该是自动化的,这样您就不必进行手动操作.
我认为为每个开发人员建立一个单独的数据库并且不使用共享数据库很重要.这样,开发人员可以独立于其他开发人员创建测试用例和开发阶段.
自动化工具应该具有处理数据库元数据的方法,该方法告诉哪些数据库处于什么开发状态以及哪些表包含版本可控数据等等.
Mat*_*att 11
您没有提及有关目标环境或约束的任何细节,因此这可能不完全适用...但是如果您正在寻找一种方法来有效地跟踪不断发展的数据库架构并且不会对使用的想法产生不利影响Ruby,ActiveRecord的迁移就在你的小巷里.
迁移以编程方式使用Ruby DSL定义数据库转换; 每个转换都可以应用或(通常)回滚,允许您在任何给定的时间点跳转到不同版本的数据库模式.定义这些转换的文件可以像任何其他源代码一样检入版本控制.
由于迁移是ActiveRecord的一部分,因此它们通常可用于全栈Rails应用程序; 但是,您可以轻松地使用独立于Rails的ActiveRecord.有关在 Rails之外使用AR迁移的更详细的处理,请参见此处.
小智 10
每个数据库都应该受源代码控制.缺少的是一个自动编写所有数据库对象 - 和"配置数据" - 到文件的工具,然后可以将其添加到任何源控制系统.如果您使用的是SQL Server,那么我的解决方案就在这里:http://dbsourcetools.codeplex.com/.玩得开心. - 内森
这很简单.
基础项目准备就绪后,您必须创建完整的数据库脚本.此脚本已提交给SVN.这是第一个版本.
之后,所有开发人员都会创建更改脚本(ALTER ...,新表,sprocs等).
当您需要当前版本时,您应该执行所有新的更改脚本.
当应用程序发布到生产,然后你回到1(但那时它将是连续版本的课程).
Nant将帮助您执行这些更改脚本.:)
记住.当有纪律时,一切都很好.每次提交数据库更改时,代码中的相应函数也会被提交.
如果您有一个小型数据库并且想要对整个数据库进行版本化,那么这个批处理脚本可能会有所帮 它将MSSQL数据库MDF文件分离,压缩和检查到Subversion.
如果您主要想要对架构进行版本设置并且只有少量参考数据,则可以使用SubSonic Migrations来处理它.这样做的好处是您可以轻松地向上或向下迁移到任何特定版本.
因为我们的应用程序必须跨多个RDBMS工作,所以我们使用数据库中立的Torque格式(XML)将我们的模式定义存储在版本控制中.我们还以XML格式对数据库的参考数据进行版本控制,如下所示(其中"Relationship"是参考表之一):
<Relationship RelationshipID="1" InternalName="Manager"/>
<Relationship RelationshipID="2" InternalName="Delegate"/>
etc.
Run Code Online (Sandbox Code Playgroud)
然后,我们使用自行开发的工具生成从数据库的X版本到版本X + 1所需的架构升级和参考数据升级脚本.
要使转储到更快一点的源代码控制系统,您可以使用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)
)
Run Code Online (Sandbox Code Playgroud)
正常运行模式:您可以从此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
Run Code Online (Sandbox Code Playgroud)
注意:如果在任何数据库中使用非标准排序规则,则需要/* COLLATE */使用数据库排序规则替换.即COLLATE Latin1_General_CI_AI
我们不存储数据库模式,我们将更改存储到数据库中.我们所做的是存储架构更改,以便为任何版本的数据库构建更改脚本并将其应用于客户的数据库.我编写了一个数据库实用程序应用程序,它与我们的主应用程序一起分发,可以读取该脚本并知道需要应用哪些更新.它还有足够的智能来根据需要刷新视图和存储过程.
迁移到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进行那么多的更改.它允许我们跟踪我们关心的所有对象的更改,并且它允许我们在发生严重问题时重建我们的完整模式.
典型的解决方案是根据需要转储数据库并备份这些文件.
根据您的开发平台,可能有开源插件可用.滚动自己的代码来完成它通常是相当微不足道的.
注意:您可能希望备份数据库转储,而不是将其置于版本控制中.这些文件在版本控制中会变得非常快,并导致整个源代码控制系统变慢(我现在回想起CVS恐怖故事).
我们刚刚开始使用Team Foundation Server.如果您的数据库是中等大小,那么visual studio可以与内置的比较,数据比较,数据库重构工具,数据库测试框架甚至数据生成工具进行一些很好的项目集成.
但是,该模型不适合非常大或第三方数据库(加密对象).所以,我们所做的只是存储我们的自定义对象.Visual Studio/Team Foundation服务器非常适用于此.
我同意ESV的答案,并且由于这个原因,我在一段时间内开始了一个小项目,以帮助在一个非常简单的文件中维护数据库更新,然后可以保持一个长边的源代码.它允许轻松更新开发人员以及UAT和Production.该工具适用于Sql Server和MySql.
一些项目特点:
该代码托管在谷歌代码上.请查看Google代码以获取更多信息
http://code.google.com/p/databaseversioncontrol/
我也在数据库中使用一个版本,通过数据库扩展属性系列程序存储.我的应用程序有每个版本步骤的脚本(即从1.1移动到1.2).部署后,它会查看当前版本,然后逐个运行脚本,直到它到达最后一个应用程序版本.没有脚本具有直接的"最终"版本,即使部署在干净的数据库上,也可以通过一系列升级步骤进行部署.
现在我要补充的是,我两天前在MS校园里看到了关于新的和即将推出的VS DB版本的演示.演讲专注于这个主题,我被吹走了.您一定要查看它,新设施专注于在T-SQL脚本(CREATE)中保持模式定义,运行时增量引擎将部署模式与定义的模式进行比较,并执行增量ALTER和与源代码集成的集成,最多并包括用于自动构建丢弃的MSBUILD持续集成.该drop将包含一个新文件类型,即.dbschema文件,可以将其带到部署站点,命令行工具可以执行实际的"增量"并运行部署.我有关于此主题的博客条目以及VSDE下载的链接,您应该查看它们:http://rusanu.com/2009/05/15/version-control-and-your-database/
这是一个非常古老的问题,但是即使现在许多人仍在尝试解决这个问题。他们要做的就是研究Visual Studio数据库项目。没有这个,任何数据库开发都显得无能为力。从代码组织到部署再到版本控制,它简化了一切。