數據庫版本管理最佳實踐

jopen 10年前發布 | 11K 次閱讀 數據庫

 

數據庫版本管理的難點

數據庫管理員與應用開發者想必多少都經歷過數據庫版本管理的痛苦,隨著團隊規模、客戶數量以及基礎設規模的上升,管理工作的復雜度將呈幾何次數上升。那么數據庫的版本管理究竟有何與眾不同之處,為何不能像普通的代碼與服務器一樣采取相同的管理方式呢?數據庫與其它系統組件的不同之處有以下幾點:

  • 數據庫中所存放的不僅是表數據,還有其它各種數據庫對象,如表結構、索引、存儲過程、角色、權限等等。這些數據庫對象同樣也需要進行版本管理,否則就有可能出現破壞性的錯誤。
  • 對于應用程序的部署,可以使用自動化持續集成工具,甚至可以通過容器現實 不可變基礎設施 。因為這些應用程序一旦部署之后,在下一次部署之前通常不會產生任何變化。但數據庫中包含著大量實時的業務數據,數據表中的內容每時每刻都在變化,無法以類似于二進制文件替換的方式簡單地部署變更。
  • 數據庫也可能具有外部依賴,例如在SQL Server中可以調用外部的SQL CLR程序集,對于這些依賴同樣要進行版本管理。但目前在數據庫領域還很少有類似于 npmNuGet 這樣的包管理工具能夠進行方便地依賴管理。
  • 數據庫是一種集中化的資源,如果多個開發者同時提交的修改中有沖突,那么在實際運行變更腳本之前幾乎無法檢測到這種沖突的存在。

來自于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等人撰寫的著作《 數據庫重構 》,有興趣的讀者可以仔細閱讀此書,以便更深入地了解這一主題的相關知識。

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!