[Architecture] Database Migration (上)

摘要:[Architecture] 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為止。

 

 

透過下面的圖片說明,可以了解相關物件之間的互動流程。

 

 

 

 

待續...

 

期許自己
能以更簡潔的文字與程式碼,傳達出程式設計背後的精神。
真正做到「以形寫神」的境界。