我觉得我的商店有一个漏洞,因为我们没有一个可靠的过程来控制数据库模式更改的版本。我们做了很多备份,所以我们或多或少地得到了保护,但以这种方式依赖于最后一道防线是一种糟糕的做法。
令人惊讶的是,这似乎是一个共同的主线。与我交谈过的许多商店都忽略了这个问题,因为他们的数据库不会经常更改,他们基本上只是尽量做到一丝不苟。
不过,我知道这个故事是怎么发展的。这只是时间问题,迟早会出问题,会有东西丢失。
在这方面有什么最佳实践吗?你有哪些行之有效的策略?
我觉得我的商店有一个漏洞,因为我们没有一个可靠的过程来控制数据库模式更改的版本。我们做了很多备份,所以我们或多或少地得到了保护,但以这种方式依赖于最后一道防线是一种糟糕的做法。
令人惊讶的是,这似乎是一个共同的主线。与我交谈过的许多商店都忽略了这个问题,因为他们的数据库不会经常更改,他们基本上只是尽量做到一丝不苟。
不过,我知道这个故事是怎么发展的。这只是时间问题,迟早会出问题,会有东西丢失。
在这方面有什么最佳实践吗?你有哪些行之有效的策略?
当前回答
必须阅读将数据库置于版本控制之下。查看K. Scott Allen的系列帖子。
When it comes to version control, the database is often a second or even third-class citizen. From what I've seen, teams that would never think of writing code without version control in a million years-- and rightly so-- can somehow be completely oblivious to the need for version control around the critical databases their applications rely on. I don't know how you can call yourself a software engineer and maintain a straight face when your database isn't under exactly the same rigorous level of source control as the rest of your code. Don't let this happen to you. Get your database under version control.
其他回答
我使用SchemaBank来版本控制我所有的数据库模式更改:
从第一天开始,我将我的db模式转储导入其中 我开始用网络浏览器改变我的模式设计(因为它们是基于SaaS /云的) 当我想更新我的db服务器时,我从它生成更改(SQL)脚本并应用到db。在Schemabank中,它们要求我在生成更新脚本之前将工作提交为版本。我喜欢这种练习,这样当我需要的时候,我就可以随时追溯。
我们的团队规则是,在没有存储设计工作之前,永远不要直接接触db服务器。但它发生了,有人可能会被诱惑打破规则,为了方便。我们将再次将模式转储导入到模式银行中,并让它执行diff,如果发现不一致,则对某人进行攻击。虽然我们可以从它生成alter脚本,使我们的db和模式设计同步,但我们讨厌这样做。
顺便说一下,它们还允许我们在版本控制树中创建分支,这样我就可以维护一个用于登台,一个用于生产。还有一个用于编码沙盒。
一个非常整洁的基于web的模式设计工具,带有版本控制和变更管理。
虽然这个问题有很多很好的答案,但大多数答案都不包括市场上的创新变化,特别是商业工具。
下面是一个简短的数据库版本控制工具列表,我列出了每个工具的优缺点(完全披露:我为DBmaestro工作)
红门——已经上市很多年了。它使用集成了基于文件的版本控制的脚本来提供数据库对象的版本控制。
DBVS——使用集成了基于文件的版本控制的脚本来提供数据库对象的版本控制。
DBmaestro——在真实的数据库对象上提供版本控制过程(签出/签入)的强制执行。因此,版本控制存储库是否与应用程序使用的数据库同步是没有问题的。
我鼓励您阅读资深数据库专家Ben Taylor在LinkedIn https://www.linkedin.com/pulse/article/20140907002729-287832-solve-database-change-mangement-with-dbmaestro上发布的关于数据库强制变更管理解决方案的全面、公正的评论
You should never just log in and start entering "ALTER TABLE" commands to change a production database. The project I'm on has database on every customer site, and so every change to the database is made in two places, a dump file that is used to create a new database on a new customer site, and an update file that is run on every update which checks your current database version number against the highest number in the file, and updates your database in place. So for instance, the last couple of updates:
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
我相信有更好的方法来做到这一点,但到目前为止,它对我来说是有效的。
我总是检查我的数据库结构转储到源代码控制。全数据库转储,但我通常只是压缩和存储。
是的,我们通过保留SQL作为构建的一部分来做到这一点——我们保留DROP。sql,创造。sql,用户。sql,值。SQL和版本控制,所以我们可以恢复到任何带标签的版本。
我们还有ant任务,可以在需要时重新创建db。
此外,SQL还被标记为与之配套的源代码。