[Architecture Pattern] Database Migration (上)
动机
在软件项目的生命周期里,每次做软件版本的修改,难免会去修改到数据库的Schema。
针对这种数据库版本的变更,一般的做法会在版本控制系统(SVN)里,存放生成数据库的SQL脚本文件案。在每个软件版本的释出时间点,开发人员会依照当时的数据库,建立数据库生成SQL脚本文件案并存入SVN。这样安装人员只要取得SVN某个软件版本的执行文件,以及对应版本的数据库生成SQL脚本文件案,就可以为客户完成安装部属的工作。
这样的架构模式,遇到旧版本系统要升级为新版本系统的时候。安装人员会需要:将旧版本的数据保留、建立新版本数据库、将旧版本的数据汇入新版本系统数据库。完成这些升级数据库的系统操作,需要一定程度的专业知识,并且还需要对不同版本数据之间的差异有一定程度的熟悉。这代表了,在软件产品的生命周期内,需要投入更多资源在维护人力上。并且这样的升级,不是业务人员或是客户自己可以处理的问题。通常这些….代表了开发人员的灾难。
在[架构之美:顶尖架构师于软件设计中蕴含的智能结晶]这本书中的第四章,提出了一个Database Migration模式。Database Migration最主要是将「每一次数据库版本修改」,包装成为一个更新计划对象。更新计划对象里,则定义了目标版本、Schema变更、数据转换…等等职责。当然Database Migration也定义执行这些更新计划对象的运作逻辑,用来完成整个数据库更新的职责。
当旧版本系统要升级为新版本系统的时候,安装人员只需要取得所有更新计划对象的对象串行,并且执行更新程序。更新程序会依照数据库目前版本,选择要执行更新计划对象,将数据库依照版本顺序依次更新到目标版本。
这样的设计将数据库更新自动化,可以大幅降低维护所需要的人力成本。并且设计上是针对「每一次数据库版本修改」来开发更新计划对象,这也避免开发人员因为时间关系,而遗忘做了哪些修改的问题。
本篇文章介绍一个Database Migration的实作,这个实作定义对象之间的职责跟互动,用来完成Database Migration应该提供的功能及职责。为自己做个纪录,也希望能帮助到有需要的开发人员。
结构
Database Migration主要是将数据库更新的职责,拆为四大部分:数据库版本管理、更新计划、更新计划管理、数据库更新逻辑。模式的结构如下:
主要的参与者有:
DatabaseVersionManager
-封装数据库版本管理的职责。
-提供目前数据库版本给DatabaseUpdater使用。
-提供DatabaseUpdater设定数据库版本的功能。
- DatabaseVersionManager需要特殊处理第1.0版的更新,因为第1.0版数据库,没有任何内容。侦测到没有任何内容时,需要告知DatabaseUpdater。
DatabaseUpdatePlan
-每一个DatabaseUpdatePlan封装一个更新计划。
-提供数据库更新的目标版本,给DatabaseUpdater使用。
-提供数据库更新的结果版本,给DatabaseUpdater使用。
-封装数据库更新,所要执行的Schema变更程序代码。
-封装数据库更新,所要执行的数据转换程序代码。
-DatabaseUpdatePlan需要特殊处理第1.0版的更新,因为第1.0版数据库,没有任何内容。侦测到没有任何内容时,第1.0版的更新要将数据库完整建立。
DatabaseUpdatePlanRepository
-封装更新计划管理的职责。
-取得所有提供更新的DatabaseUpdatePlan实作。
-使用外部设定数据来Reflection生成DatabaseUpdatePlan实作。
DatabaseUpdater
-封装数据库更新逻辑。
-使用DatabaseVersionManager取得目前数据库版本。
-使用DatabaseUpdatePlanRepository取得所有DatabaseUpdatePlan。
-比对DatabaseUpdatePlan更新的目标版本,是否为目前数据库版本,如果是就执行DatabaseUpdatePlan。
-取得DatabaseUpdatePlan更新的结果版本,用来更新DatabaseVersionManager的目前数据库版本。
-上述动作重复执行,到没有可以更新的DatabaseUpdatePlan为止。
透过下面的图片说明,可以了解相关对象之间的互动流程。
待续...
期許自己~
能以更簡潔的文字與程式碼,傳達出程式設計背後的精神。
真正做到「以形寫神」的境界。