我觉得我的店有个漏洞,因为我们没有适当的过程来版本化数据库架构更改。我们进行了大量备份,因此我们或多或少都得到了保障,但是以这种方式依赖您的最后一道防线是不明智的做法。
令人惊讶的是,这似乎是一个常见的话题。我说过的许多商店都忽略了这个问题,因为它们的数据库不经常更改,并且基本上只是在尝试细致。
但是,我知道那个故事是怎么回事。事情排错了一切,丢失了东西只是时间问题。
是否有最佳做法?有哪些对您有用的策略?
我觉得我的店有个漏洞,因为我们没有适当的过程来版本化数据库架构更改。我们进行了大量备份,因此我们或多或少都得到了保障,但是以这种方式依赖您的最后一道防线是不明智的做法。
令人惊讶的是,这似乎是一个常见的话题。我说过的许多商店都忽略了这个问题,因为它们的数据库不经常更改,并且基本上只是在尝试细致。
但是,我知道那个故事是怎么回事。事情排错了一切,丢失了东西只是时间问题。
是否有最佳做法?有哪些对您有用的策略?
Answers:
必须阅读使数据库受版本控制。查看K. Scott Allen的系列文章。
在版本控制方面,数据库通常是二等甚至三等公民。从我所看到的情况来看,在一百万年之内不会考虑没有版本控制的情况下编写代码的团队-的确如此-可以完全忽略应用程序所依赖的关键数据库的版本控制需求。我不知道当数据库未与其余代码完全处于相同的严格源代码控制级别时,如何称呼自己为软件工程师并保持直言不讳。不要让这种情况发生在您身上。使数据库受版本控制。
数据库本身?没有
创建它们的脚本,包括静态数据插入,存储过程等;当然。它们是文本文件,它们包含在项目中,并且像其他所有文件一样签入和签出。
当然,在理想情况下,您的数据库管理工具可以做到这一点。但您只需要对此加以纪律。
我绝对喜欢Rails ActiveRecord迁移。它将DML抽象为ruby脚本,然后可以在源存储库中轻松对其进行版本控制。
但是,通过一些工作,您可以做同样的事情。任何DDL更改(ALTER TABLE等)都可以存储在文本文件中。为文件名保留编号系统(或日期戳),并依次应用它们。
Rails在数据库中也有一个“版本”表,用于跟踪上一次应用的迁移。您可以轻松地执行相同操作。
您永远不应仅登录并开始输入“ ALTER TABLE”命令来更改生产数据库。我所在的项目在每个客户站点上都有数据库,因此对数据库的每次更改都在两个地方进行,一个用于在新客户站点上创建新数据库的转储文件,以及一个正在运行的更新文件每次更新时,都会根据文件中的最高编号检查当前数据库版本号,并就地更新数据库。因此,例如,最后几个更新:
if [ $VERSION \< '8.0.108' ] ; then
psql -U cosuser $dbName << EOF8.0.108
BEGIN TRANSACTION;
--
-- Remove foreign key that shouldn't have been there.
-- PCR:35665
--
ALTER TABLE migratorjobitems
DROP CONSTRAINT migratorjobitems_destcmaid_fkey;
--
-- Increment the version
UPDATE sys_info
SET value = '8.0.108'
WHERE key = 'DB VERSION';
END TRANSACTION;
EOF8.0.108
fi
if [ $VERSION \< '8.0.109' ] ; then
psql -U cosuser $dbName << EOF8.0.109
BEGIN TRANSACTION;
--
-- I missed a couple of cases when I changed the legacy playlist
-- from reporting showplaylistidnum to playlistidnum
--
ALTER TABLE featureidrequestkdcs
DROP CONSTRAINT featureidrequestkdcs_cosfeatureid_fkey;
ALTER TABLE featureidrequestkdcs
ADD CONSTRAINT featureidrequestkdcs_cosfeatureid_fkey
FOREIGN KEY (cosfeatureid)
REFERENCES playlist(playlistidnum)
ON DELETE CASCADE;
--
ALTER TABLE ticket_system_ids
DROP CONSTRAINT ticket_system_ids_showplaylistidnum_fkey;
ALTER TABLE ticket_system_ids
RENAME showplaylistidnum
TO playlistidnum;
ALTER TABLE ticket_system_ids
ADD CONSTRAINT ticket_system_ids_playlistidnum_fkey
FOREIGN KEY (playlistidnum)
REFERENCES playlist(playlistidnum)
ON DELETE CASCADE;
--
-- Increment the version
UPDATE sys_info
SET value = '8.0.109'
WHERE key = 'DB VERSION';
END TRANSACTION;
EOF8.0.109
fi
我敢肯定有更好的方法可以做到这一点,但是到目前为止,它对我来说是有效的。
begin transaction; ... end transaction;
为传递--single-transaction
给psql
。
我看到的最佳实践是创建一个构建脚本,以在临时服务器上剪贴和重建数据库。每次迭代都有一个用于数据库更改的文件夹,所有更改都使用“ Drop ... Create”的脚本编写。通过这种方式,您可以随时通过将构建指向要版本控制的文件夹来回滚到早期版本。
我相信这是通过NaNt / CruiseControl完成的。
Visual Studio中的新数据库项目提供了源代码管理和更改脚本。
他们有一个比较数据库的好工具,可以生成一个脚本,将一个模式转换为另一个模式,或更新一个模式中的数据以匹配另一个模式。
db模式被“切碎”以创建许多非常小的.sql文件,每个描述数据库的DDL命令一个。
+汤姆
附加信息2008-11-30
在过去的一年中,我一直将其用作开发人员,并且非常喜欢它。可以轻松地将我的开发工作与生产进行比较,并生成用于发布的脚本。我不知道它是否缺少DBA“企业型”项目所需的功能。
因为该架构已“切碎”到sql文件中,所以源代码控件可以正常工作。
一个陷阱是,使用数据库项目时,您需要有不同的心态。该工具在VS中有一个“数据库项目”,它只是sql,还有一个自动生成的本地数据库,该数据库具有架构和一些其他管理数据-但没有您的应用程序数据,还有用于该数据库的本地dev db应用数据开发工作。您很少知道自动生成的数据库,但是您必须在那里知道它,因此您可以不理会它:)。可以清楚地识别出这个特殊的数据库,因为它的名称中包含一个Guid,
VS DB项目在将其他团队成员所做的数据库更改集成到本地项目/相关数据库方面做得很好。但您需要采取额外的步骤来将项目架构与本地dev db架构进行比较,并应用mod。这是有道理的,但起初似乎很尴尬。
数据库项目是一个非常强大的工具。它们不仅生成脚本,而且可以立即应用它们。确保不要破坏它的生产数据库。;)
我真的很喜欢VS DB项目,并且我希望以后的所有数据库项目都可以使用此工具。
+汤姆
要求开发团队使用SQL数据库源代码管理管理系统并不是解决问题的灵丹妙药。由于开发人员需要将对对象所做的更改保存在单独的SQL脚本中,打开源代码管理系统客户端,使用客户端检入SQL脚本文件,然后,数据库源控件本身会带来额外的开销。将更改应用到实时数据库。
我可以建议使用称为ApexSQL Source Control的SSMS加载项。它使开发人员可以直接通过SSMS的向导通过源控制系统轻松映射数据库对象。该插件包括对TFS,Git,Subversion和其他SC系统的支持。它还包括对源代码控制静态数据的支持。
下载并安装ApexSQL Source Control之后,只需右键单击要版本控制的数据库,然后导航到SSMS中的ApexSQL Source Control子菜单。单击将数据库链接到源代码管理选项,选择源代码管理系统和开发模型。之后,您需要提供所选信息源控制系统的登录信息和存储库字符串。
您可以阅读本文以获取更多信息:http : //solutioncenter.apexsql.com/sql-source-control-reduce-database-development-time/
我在项目上使用过的最成功的方案是将备份和差异SQL文件结合在一起。基本上,在每个发行版之后,我们都会备份数据库,并执行SQL转储,以便我们也可以从头开始创建空白模式。然后,每当需要更改数据库时,都可以在版本控制下向SQL目录中添加更改脚本。我们将始终在文件名前添加序列号或日期,因此第一个更改将类似于01_add_created_on_column.sql,下一个脚本将为02_added_customers_index。我们的CI机器将检查这些内容,并在已从备份还原的db的新副本上顺序运行它们。
我们还提供了一些脚本,开发人员可以使用这些脚本通过一个命令将其本地数据库重新初始化为当前版本。
我使用SchemaBank来版本控制所有数据库架构更改:
我们的团队规则是永远不要直接触摸数据库服务器,而无需先存储设计工作。但是它的确发生了,为了方便起见,有人可能会想违反规则。我们将模式转储再次导入到schemabank中,让它进行比较,如果发现差异,则对某人进行打击。尽管我们可以从中生成alter脚本,以使数据库和架构设计同步,但我们对此感到讨厌。
顺便说一句,它们还允许我们在版本控制树中创建分支,以便我可以维护一个用于登台,一个用于生产。还有一个用于编码沙箱。
一个非常简洁的基于Web的架构设计工具,具有版本控制和变更管理功能。
我使用从MySQL Workbech导出的SQL CREATE脚本,然后使用它们的“导出SQL ALTER”功能,最后得到一系列创建脚本(当然编号)以及可以在它们之间应用更改的alter脚本。
3.-导出SQL ALTER脚本通常,您现在必须手动编写ALTER TABLE语句,以反映对模型所做的更改。但是您可以变得聪明,让Workbench为您完成艰苦的工作。只需从主菜单中选择File-> Export-> Forward Engineer SQL ALTER Script…。
这将提示您指定当前模型应与之比较的SQL CREATE文件。
从步骤1中选择SQL CREATE脚本。然后,该工具将为您生成ALTER TABLE脚本,您可以对数据库执行此脚本以使其更新。
您可以使用MySQL查询浏览器或mysql客户端执行此操作。您的模型和数据库现已同步!
当然,所有这些脚本都在版本控制下。
关于数据库模型本身已经进行了很多讨论,但是我们还将所需的数据保存在.SQL文件中。
例如,为了有用,您的应用程序可能需要在安装中进行以下操作:
INSERT INTO Currency (CurrencyCode, CurrencyName)
VALUES ('AUD', 'Australian Dollars');
INSERT INTO Currency (CurrencyCode, CurrencyName)
VALUES ('USD', 'US Dollars');
我们将currency.sql
在subversion下有一个名为的文件。作为构建过程中的手动步骤,我们将先前的currency.sql与最新的currency.sql进行比较,并编写一个升级脚本。
我们对数据库周围的所有内容进行版本控制和源代码控制:
我们使用变更管理器和一些自定义脚本通过自动化作业来完成所有这些工作。我们让变更管理器监视这些变更并通知完成的时间。
我相信每个数据库都应该受到源代码控制,并且开发人员应该有一种简便的方法来从头开始创建本地数据库。受Visual Studio for Database Professionals的启发,我创建了一个开放源代码工具,该工具可对MS SQL数据库进行脚本编写,并提供了一种将其部署到本地DB引擎的简便方法。尝试http://dbsourcetools.codeplex.com/。玩得开心,-内森。
如果您的数据库是SQL Server,我们可能只是您要寻找的解决方案。SQL Source Control 1.0现在已经发布。
http://www.red-gate.com/products/SQL_Source_Control/index.htm
这集成到SSMS中,并提供了数据库对象和VCS之间的粘合。“脚本输出”是透明进行的(它在后台使用了SQL Compare引擎),这应该使其使用起来如此简单,以至于不会妨碍开发人员采用该过程。
另一种Visual Studio解决方案是ReadyRoll,它作为SSDT数据库项目的子类型实现。这采用了迁移驱动的方法,该方法更适合DevOps团队的自动化要求。
我使用了ThoughtWorks的dbdeploy工具,网址为http://dbdeploy.com/。它鼓励使用迁移脚本。在每个发行版中,我们将变更脚本整合到一个文件中,以简化理解并允许DBA“祝福”变更。
这对我来说也一直是一个很大的烦恼-似乎对开发数据库进行快速更改,将其保存(忘记保存更改脚本)太简单了,然后就陷入了困境。您可以撤消刚刚做的事情,然后重做以创建更改脚本,或者当然也可以从头开始编写它,尽管这花费了大量时间来编写脚本。
我过去使用过的有助于此功能的工具是SQL Delta。它将向您显示两个数据库(我相信是SQL Server / Oracle)之间的差异,并生成迁移A-> B所需的所有更改脚本。这样做的另一个好处是,可以显示生产(或测试)数据库与开发数据库之间的数据库内容之间的所有差异。由于越来越多的应用程序将对它们的执行至关重要的配置和状态存储在数据库表中,因此拥有删除,添加和更改适当行的更改脚本可能会非常痛苦。SQL Delta显示数据库中的行,就像它们在Diff工具中一样-更改,添加,删除。
出色的工具。这是链接:http : //www.sqldelta.com/
RedGate很棒,我们在进行数据库更改时会生成新的快照(一个很小的二进制文件),并将该文件作为资源保留在项目中。每当我们需要更新数据库时,我们都会使用RedGate的工具包来更新数据库,并能够从空数据库中创建新数据库。
RedGate还可以制作数据快照,尽管我还没有亲自使用过它们,但它们同样强大。
仅供参考,这也是Dana在几天前提出的... 源代码控制中的存储过程/ DB模式