写点什么

数据库版本管理最佳实践

  • 2015-08-19
  • 本文字数:2313 字

    阅读完需:约 8 分钟

数据库版本管理的难点

数据库管理员与应用开发者想必多少都经历过数据库版本管理的痛苦,随着团队规模、客户数量以及基础设规模的上升,管理工作的复杂度将呈几何次数上升。那么数据库的版本管理究竟有何与众不同之处,为何不能像普通的代码与服务器一样采取相同的管理方式呢?数据库与其它系统组件的不同之处有以下几点:

  • 数据库中所存放的不仅是表数据,还有其它各种数据库对象,如表结构、索引、存储过程、角色、权限等等。这些数据库对象同样也需要进行版本管理,否则就有可能出现破坏性的错误。
  • 对于应用程序的部署,可以使用自动化持续集成工具,甚至可以通过容器现实不可变基础设施。因为这些应用程序一旦部署之后,在下一次部署之前通常不会产生任何变化。但数据库中包含着大量实时的业务数据,数据表中的内容每时每刻都在变化,无法以类似于二进制文件替换的方式简单地部署变更。
  • 数据库也可能具有外部依赖,例如在 SQL Server 中可以调用外部的 SQL CLR 程序集,对于这些依赖同样要进行版本管理。但目前在数据库领域还很少有类似于 npm NuGet 这样的包管理工具能够进行方便地依赖管理。
  • 数据库是一种集中化的资源,如果多个开发者同时提交的修改中有冲突,那么在实际运行变更脚本之前几乎无法检测到这种冲突的存在。

来自于 EastBanc Technologies 的 Vladimir Khorikov 近期发表了一篇博客文章,为读者介绍了一些他在数据库版本管理方面所采用的最佳实践。

最佳实践

最佳实践之一:将数据库和引用数据与代码一视同仁,也即是说它们也需要由版本控制系统进行管理。

Vladimir 在这里特意强调了引用数据的重要性,这些数据是运行应用程序不可或缺的元数据,因此同样需要保存至版本控制系统中。

最佳实践之二:数据库 Schema 与引用数据的每一次变动都应进行显式的记录,也就是说,对于数据库的任何一次修改,都应当保存在一个独立的文件中。如果某个变更脚本会同时影响到 Schema 与引用数据,那么应当将这些变动保存在同一个脚本文件中。

Vladimir 认为,坚持遵守为每一次修改生成一个独立的脚本文件的做法非常有必要。如今有许多项目的做法是将数据库的 Schema 保存在版本控制系统中,也就是保存了当前数据库版本的一个快照。这种方式无法将不同的修改分别保存到不同的脚本文件中,此外,在引用数据表中的变动往往会被忽略。

目前已经有许多工具可以对数据库进行版本控制管理,例如 Visual Studio 中的数据库项目,以及 Redgate 的 SQL Source Control 。虽然这些工具在小型数据库项目的管理中十分便利,但在 Vladimir 看来,在大型项目中以自动生成脚本的方式管理数据库反而变成了一种负担。他将在今后的博客文章中继续介绍这种工具的使用与问题所在。

最佳实践之三:当变更脚本部署之后,确保它的不可变性。

在 Vladimir 看来,在独立的文件中保存变更的意义就在于对这些变更进行追踪,一旦更改了这些脚本的内容,也就失去了版本管理的意义。因此正确的做法是保持这些脚本不变,如果需要撤消其中的某些变更,就另行创建一个单独的撤消脚本。

最佳实践之四:所有的数据库 Schema 与引用数据只能通过执行变更脚本的方式进行更新,坚决抵制人为修改数据库的做法。

与上一条实践一样,一旦对数据库直接进行手动更新,版本管理就变成了一纸空谈。因此必须通过签入版本控制系统中的脚本对数据库进行更新。

最佳实践之五:项目中的每个开发者都应当分配一个自有的数据库实例。

这一实践尤其适合于在大型团队中使用,因为在这种环境中,开发者的数据库变更很可能会与他人的变更产生冲突。而如果每位开发者都能够在一个独立的实例中进行开发,那么这种冲突可以在合并时通过版本控制系统解决。不过这种情况应当只适用于自动生成变更脚本的工具,否则不同的开发者会使用不同的脚本文件保存变更操作,版本控制系统对于不同文件中的冲突一无所知。

Vladimir 还建议为每个代码分支创建一个独立的数据库实例,当然这种做法取决于不同分支中的代码有多大的差别。这个实践在实际情况中可能会面临两种问题,一是如何修改配置信息,让开发者连接到不同的数据库,同时这种配置信息的变更不应签入版本库中。二是如果数据库信息非常庞大,在更新与分发时就非常耗时与占用磁盘空间。

最佳实践之六:将数据库的版本号也保存在数据库中。

Vladimir 就经常在一张独立的表 Settings 中保存一个数值型的版本信息。如果这个系统是一种可分发的应用(即每个用户都对应着一个不同的版本),那么可通过它了解当前客户所使用的应用的版本。

最佳实践的益处

Vladimir 随后简单地描述了这些最佳实践所带来的益处。最明显的一点就是,一旦出现数据库 Schema 不一致的情况,可以通过执行变更脚本确保升级到最新的版本。这一点对于可分发应用来说尤为明显。

最佳实践的第二个益处是实现了数据库变更的高内聚性,对于 Schema 与引用数据的全部改动都集中在版本控制系统中,而不是散落在应用程序的各处。同样,由于数据库脚本中包含了在开发某个特性时对数据库产生的所有变更,因而更易于理解这些变更的含义。

最后,Vladimir 表示,实现这些实践无需从一个全新的项目中开始。你可以现在就为数据库 Schema 创建一个初始化的脚本,将其作为版本 1,然后通过应用以上实践让你的脚本逐渐充实起来,最终成功地实现数据库版本管理的目标。

Vladimir 也在文中向读者强烈推荐了由 Ambler 等人撰写的著作《数据库重构》,有兴趣的读者可以仔细阅读此书,以便更深入地了解这一主题的相关知识。


感谢徐川对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ @丁晓昀),微信(微信号: InfoQChina )关注我们,并与我们的编辑和其他读者朋友交流(欢迎加入 InfoQ 读者交流群)。

2015-08-19 08:365816
用户头像

发布了 428 篇内容, 共 200.4 次阅读, 收获喜欢 39 次。

关注

评论

发布
暂无评论
发现更多内容

短网址服务设计整理

程序员架构进阶

架构 设计实践 28天写作 实操案例 3月日更

php的一些漏洞梳理

依旧廖凯

28天写作 3月日更

存量用户运营企业微信的“用户端小程序”优化方案

vivo互联网技术

小程序 微信 性能优化 大前端 企业微信

JVM笔记--如果你写JVM,最需要考虑的重要结构是什么?

秦怀杂货店

Java JVM

Wireshark 数据包分析学习笔记 Day13

穿过生命散发芬芳

Wireshark 数据包分析 3月日更

Nginx配置静态文件服务从入门到精通

happlyfox

28天写作 3月日更

滚雪球学 Python 之内置 random 模块

梦想橡皮擦

28天写作 3月日更

像这样操作 Python 列表,能让你的代码更优雅 | pythonic 小技巧

AlwaysBeta

Python

假期无聊冰河开发了一款国民级游戏!

冰河

Java 游戏

看了 GitHub 上的这些面试题项目后,我飘了!

JackTian

GitHub 开源 面试

LeetCode题解:91. 解码方法,动态规划(优化),JavaScript,详细注释

Lee Chen

算法 大前端 LeetCode

算法攻关-climbing-stairs(O(n))_70

小诚信驿站

刘晓成 小诚信驿站 28天写作 算法攻关

算命、运气和其他「Day 24」

道伟

28天写作

产品训练营 第四周作业

万顷湖天碧

网易 Duilib:功能全面的开源桌面 UI 开发框架

有道技术团队

开源

项目延期了,怎么办?

石云升

项目管理 28天写作 职场经验 管理经验 3月日更

大作业

LouisN

协助市场监督管理局,打造质量基础设施“一站式”服务平台

源中瑞-龙先生

哪有简单的满足——自我决定论

Justin

心理学 28天写作 游戏设计

容器or虚拟机?

xcbeyond

Docker 容器 3月日更 专业术语

美丽的数学学习笔记(1)

方勇(gopher)

产品经理训练营 - 大作业

joelhy

产品经理训练营

诊所数字化:医疗机构常见的系统整理

boshi

医院 医疗 七日更

Hamcrest

insight

单元测试 3月日更

yum安装Nginx全流程指南

happlyfox

28天写作 3月日更

Apache Oozie 深入原理讲解

五分钟学大数据

大数据 28天写作 3月日更 oozie

掌握了开源框架还不够,你更需要掌握源代码

华为云开发者联盟

开源 Element 源代码 Vue 3

Rancher 2.5.6发布,支持Kubernetes 1.20

Rancher

5 分钟部署一个 OIDC 服务并对接 nightingale

冯骐

CAS Nightingale 认证授权 OIDC Apereo

前端开发:Mac环境的Chrome浏览器设置跨域请求的SameSite解决方法

三掌柜

vue.js 大前端 3月日更

为什么MySQL不推荐使用子查询和join

Java小咖秀

MySQL MySQL优化

数据库版本管理最佳实践_数据库_邵思华_InfoQ精选文章