我觉得我的商店有一个漏洞,因为我们没有一个可靠的过程来控制数据库模式更改的版本。我们做了很多备份,所以我们或多或少地得到了保护,但以这种方式依赖于最后一道防线是一种糟糕的做法。

令人惊讶的是,这似乎是一个共同的主线。与我交谈过的许多商店都忽略了这个问题,因为他们的数据库不会经常更改,他们基本上只是尽量做到一丝不苟。

不过,我知道这个故事是怎么发展的。这只是时间问题,迟早会出问题,会有东西丢失。

在这方面有什么最佳实践吗?你有哪些行之有效的策略?


当前回答

我有一切必要的重新创建我的数据库从裸露的金属,减去数据本身。我相信有很多方法可以做到这一点,但我所有的脚本等都存储在subversion中,我们可以通过将所有这些从subversion中取出并运行安装程序来重建DB结构等。

其他回答

我们有一个每周的sql转储到一个颠覆回购。这是完全自动化的,但这是一项非常繁重的任务。

你会想要限制修改的数量,因为它真的会在一段时间后消耗磁盘空间!

虽然这个问题有很多很好的答案,但大多数答案都不包括市场上的创新变化,特别是商业工具。

下面是一个简短的数据库版本控制工具列表,我列出了每个工具的优缺点(完全披露:我为DBmaestro工作)

红门——已经上市很多年了。它使用集成了基于文件的版本控制的脚本来提供数据库对象的版本控制。

DBVS——使用集成了基于文件的版本控制的脚本来提供数据库对象的版本控制。

DBmaestro——在真实的数据库对象上提供版本控制过程(签出/签入)的强制执行。因此,版本控制存储库是否与应用程序使用的数据库同步是没有问题的。

我鼓励您阅读资深数据库专家Ben Taylor在LinkedIn https://www.linkedin.com/pulse/article/20140907002729-287832-solve-database-change-mangement-with-dbmaestro上发布的关于数据库强制变更管理解决方案的全面、公正的评论

RedGate软件提供了一些很棒的工具,可以帮助你对数据库进行版本化。确保让开发者为开发工作构建自己的独立本地数据库,而不是依赖于“开发服务器”,因为“开发服务器”有时可能停机,有时也可能不停机。

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

我相信有更好的方法来做到这一点,但到目前为止,它对我来说是有效的。

仅供参考,几天前Dana也提出了这个问题…源代码控制中的存储过程/DB模式