硬核干货——《中小企业 AI 实战指南》免费下载! 了解详情
写点什么

数据库版本管理最佳实践

  • 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:365699
用户头像

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

关注

评论

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

python sorted()函数及sort()方法,零基础Python开发

程序媛可鸥

Python 程序员 面试

中文在线研讨会 | 如何突破Jenkins瓶颈,实现集中管理、灵活高效的CI/CD

龙智—DevSecOps解决方案

ci 持续集成 持续交付

在线SQL(Insert/Update)语句转JSON工具

入门小站

工具

踏雪痕项目管理学习笔记

踏雪痕

项目管理 PMP Certification 3月程序媛福利 3月月更

代码安全 | 什么是OWASP?OWASP十大漏洞解析

龙智—DevSecOps解决方案

漏洞 安全漏洞 漏洞防护 OWASP十大漏洞 静态代码安全

网站被DDOS攻击了怎么办?

源字节1号

开源 前端开发 后端开发

315权益日解读:“幸运”大牌和巨头,“挡枪”作坊和“小弟”?

易观分析

315晚会 央视315晚会 消费者权益

周末给女友讲了遍加密算法,没想到...

浅羽技术

算法 安全 加密算法

在线JSON转CSV格式文件工具

入门小站

工具

2022年最新iOS面试题(附答案)

iOSer

ios iOS面试 ios开发 iOS 知识体系 iOS涨薪

攻击面管理(ASM)技术详解和实现

风向标

网络安全 asm 安全419 零零信安

Trace大盘点

奋飞安全

龙智荣誉 | 一封来自客户的感谢信

龙智—DevSecOps解决方案

感谢信

企业CICD规模化落地浅析

阿里云云效

云计算 阿里云 云原生 CI/CD 持续交付

什么牌子的云堡垒机好用?效果好?

行云管家

云计算 堡垒机 云堡垒机

一眼定位问题,函数计算发布日志关键词秒检索功能

阿里巴巴云原生

档案管理系统平台:助力实现档案管理现代化

小炮

【模块五】设计微博系统中”微博评论“的高性能高可用计算架构

yhjhero

架构 #架构训练营

Linux之ab命令

入门小站

Linux

用户文章 | 没有什么比现成的解决方案更香的了 - P4Python 玩家速看

龙智—DevSecOps解决方案

perforce P4 Perforce Helix Core P4Python

数据分析师如何正确地提意见?

博文视点Broadview

Nebula Graph 在企查查的应用

NebulaGraph

数据库 开源 图数据库 知识图谱

【网络安全】记一次网站站点渗透

网络安全学海

网络安全 信息安全 渗透测试 WEB安全 安全漏洞

python Excel数据表格转为HTML网页数据表格,阿里快手拼多多等7家大厂Python面试真题

程序媛可鸥

Python 程序员 面试

python pandas loc布尔索引(指定条件下的索引),你花了多久弄明白架构设计

程序媛可鸥

Python 程序员 面试

从0到1:基于微信小程序的瑜伽馆预约平台的开发笔记

CC同学

龙蜥一站式质量协作平台T-One上线,助你轻松完成测试

OpenAnolis小助手

开源 测试 软件包 协作平台

郑州等保测评公司有哪些?在哪里?

行云管家

网络安全 等保 等保测评 等保2.0 郑州

性能测试中Disruptor框架ExceptionHandler使用分享

FunTester

Disruptor 性能测试 接口测试 异常处理 FunTester

全球案例 | Hubspot 通过 Confluence 打造透明的协作文化,使之成为让无数人骄傲的企业

龙智—DevSecOps解决方案

Jira Atlassian Atlassian Confluence 协同办公软件 协同软件

虚位以待 | 龙智有你更出彩

龙智—DevSecOps解决方案

求职 招聘

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