資料庫的持續整合和版本控制

2021-09-16 18:23:15 字數 3928 閱讀 4624

在提出版本化資料庫工作是乙個必要規則這一觀點之後,scott allen又詳述了乙個做好版本化資料庫的方法,他給出了乙個易於理解、實踐性很強的方法,通過建立基線、使用變更指令碼的方法來管理資料庫的修訂、控制程式化資料庫物件(如檢視、儲存過程、函式和觸發器),並充分利用分支和合併。

\u0026#xd;\n

allen在發布了關係型資料庫開發的三個原則的經驗總結文章之後,就開始寫後續的系列文章了。這三個原則如下:

\u0026#xd;\n一、不要在共享資料庫伺服器上進行開發工作

就像軟體開發中其它所謂便捷的方法一樣,共享資料庫的使用也是乙個泥潭,它正等著凍結乙個專案呢。開發人員相互覆蓋彼此所做的修改,我在伺服器上所做的改變讓你的開發機器上的**中斷執行,這些都讓遠端開發速度很慢而且非常困難。避免使用共享資料庫,也就免避了因使用它造成的極度時間浪費和因之而生的bug。
僅保留乙份權威的schema生成源
每乙個人都必須知道該從**獲得正式的schema,並且可以用它輕鬆地重新建立乙個新的資料庫。當我走到電腦前,可以從原始碼庫中獲得最新的版本,構建後就可以通過最簡單的工具建立資料庫(在更多的場景中,構建的過程甚至可以在資料庫不存在時自己建立乙個,所以這個構建過程應該是一步到位方式的)。
三、對你的資料庫進行版本管理
這樣做的原因之一就是要將變化由開發傳遞到測試,最終在一種可控制的、一致的環境下生產。其二就是可以重建任何時間點上的資料庫,如果你正在將軟體交付給客戶的話,這一點就尤為重要。如果有人在你提交的應用版本build 20070612中發現了bug,你就必須能重建當時那個版本的狀況——包括資料和其它所需。
\u0026#xd;\n

allen說明了版本化資料庫的目的就是為了能保證所做的改變能保持一致性、可控性、可測試性和可重現性。許多推廣者都同意這一點,並認為實現這個目標對任何乙個敏捷團隊的效率都很重要。

\u0026#xd;\n

在列出了版本化資料庫的重要性後,allen又相繼發布了4個貼子來描述他推薦的實現方法。

\u0026#xd;\n

其中,第一篇貼子描述了allen宣稱的版本化資料庫的起點——建立乙個資料庫schema基線。從本質上來講,這個基線是乙個指令碼,或者是一連串指令碼,它包含所有可以從零開始生成應用資料庫的sql命令。它包括建立所有資料庫所有物件(表、約束、函式、檢視、索引等)的sql命令、表查詢及操作命令和插入應用所需初始資料的命令。allen建議,一旦它完成建立並且驗證無誤,應立刻「將它提交到原始碼控制庫」,此時「你可以認為已將資料庫基線化了」。

\u0026#xd;\n

\u0026#xd;\n

我喜歡將所有生成表、約束、預設值和主鍵的sql語句儲存到同乙個檔案中,而那些建立檢視、儲存過程、函式的指令碼則分開來單獨儲存。

\u0026#xd;\n

如果你喜歡多檔案儲存的方式,那就需要乙個批處理檔案,shell指令碼,應用程式,或其它自動化工具來自動定位並執行安裝資料庫需要的所有指令碼檔案。人工干涉這個過程是一種倒退。

\u0026#xd;\n

\u0026#xd;\n

allen建議並強調,基線中需要乙個表用來記錄任何有關資料庫結構的改變,在他後面的三個貼子中,他詳細描述了該如何處理這些變化。

\u0026#xd;\n

首先,allen討論了變更指令碼——一種管理除檢視、儲存過程、函式以外的資料庫物件的機制。這種方法要求任何乙個改變(或一組相關的改變)必須有乙個新生成的指令碼檔案可通過「增量」更新的方式來代表,這與ruby migration很相似。換句話說,當團隊發現資料庫需要做改變時,他們建立乙個新的指令碼來將資料庫修改到想要的樣子,通過測試後提交到原始碼控制庫中。一旦發布後,這個指令碼就永遠不要再修改。

\u0026#xd;\n

allen這麼做使檢視、儲存過程和函式的更新方式與其它資料庫物件完全相反,每個物件都有乙個「建立命令」檔案,然後通過更新這乙個檔案來更新這些物件,對於為什麼他喜歡這樣做,他解釋到:

\u0026#xd;\n

原因很簡單,就是為了更快速地確定問題所在。如果有人提交了乙個資料庫結構變化,它移除了檢視所引用的乙個列,那麼你可以盡早地發現有錯誤,因為在構建版本提交到測試以前,這個問題就會被發現;同樣,如果有人提交了乙個檢視,但卻忘了發布它所需要的結構改變,幾分鐘後就會有人跑到他們的桌子前問他們為什麼要破壞軟體的執行。

另乙個原因就是為了避免我遇到過的某些不太常見的錯誤。對於那些隱匿在檢視背後的schema的變化,某些資料庫產品仍會強迫完成執行計畫,而由此引發的問題很難跟蹤。「扔掉所有的東西,重新開始」會避免發生這類事情。

\u0026#xd;\n

allen著重強調了利用自動化工具更好地實施上述策略的重要性:

\u0026#xd;\n

當開發人員、測試人員或者安裝人員從原始碼控制庫中更新並執行本地資料公升級工具時,它就像會魔術般地完成工作。它有三個步驟:

1、通過對比現有資料庫結構變更指令碼檔案和schemachangelog表中的記錄,來應用最新的資料庫結構;

2、刪掉資料庫中所有的儲存過程、檢視和函式;

3、執行所有的變更指令碼將檢視、儲存過程和函式添回到資料庫中去。

\u0026#xd;\n

對於遵循這些策略的好處,尤其是使用自動化工具,allen給出了一些示例:

\u0026#xd;\n

由於資料結構變更指令碼儲存在原始碼控制庫中,你可以在任何時候重新建立任意時間點上的資料庫。如果客戶報告了乙個關於build 3.1.5.6723的bug,那麼,你所需要做的就是獲取相應版本標號或標記過的原始碼,然後執行這一基線和這一標記下所有的資料庫變更指令碼。當其執行結束後,你就已經有了乙份與客戶發現bug時一模一樣的資料庫,也就獲得了乙個重現這個bug的好機會。而且,當改變由開發階段進入測試階段時,就從根本上提供了乙個一致的、有序的、可重現的產品。
\u0026#xd;\n

allen在這一系列文章的最後,還提及他是如何處理分支與合併的,而這是所有應用在版本伺服器上建立它的第乙個版本後都要面對的現實問題。allen建議為發布而分支,這也是他偏好的分支策略,同時解釋了他為什麼會為每個新的發布版本重創資料庫基線。他通過乙個示例來描述了這個問題,並新增了這樣乙個場景:在較早版本中發現了缺陷,就必須對已分支的版本進行相應的資料構結構變更。在這個分支版本中,建立新的指令碼來處理變更是沒有問題的,問題是,如何將這個變更也應用到當前的主線版本中:

\u0026#xd;\n

想要在主線中修復它,有兩種選擇。實際上可能會有無數種可能性,這取決於你想如何應用你的更新。但這裡只提供兩種選擇:

1.將資料庫變更指令碼合併到當前主線版本01.00.0046的指令碼中,並在基線版本2.0中進行相應的修復來處理這一變更;

2.寫乙個新的資料庫結構變更指令碼02.00.0003,其與分支版本46中的變更保持一致。

對於選項一,你必須小心處理,因為任何已經更新到v2.0版的資料庫都並不會從分支上獲得46號變更指令碼(除非你編寫的工具與我的不一樣)。你只能讓別人手工執行這一指令碼,或者你自己檢視對與現存的2.0版本資料庫衝突(對於這種結果,無論如何僅限於在開發和測試機器上)。所以,除非你剛開始著手2.0的開發不久,否則這個選擇並不算太好。

相比之下選項二則要友好多了。1.0版本的資料庫將會從01.00.0046中獲得修復。2.0版本的資料庫則在02.00.0003中得到修復。但你也要很小心地去編寫02.00.0003的修改指令碼,以免它履蓋執行01.00.0046指令碼後所做的修改。

換句話說,資料庫是按照2.0版的基線指令碼安裝的,必須要應用02.00.0003指令碼,但實際的產品資料庫可能是從1.0版開始的,它將應用01.00.0046指令碼來修復,所以你不能讓02.00.0003去再次修改這個實際已經公升級到2.0版的資料庫否則,會造成錯誤。

\u0026#xd;\n檢視英文原文

continuous integration and version control for databases

資料庫的持續整合和版本控制

在提出版本化資料庫工作是乙個必要規則這一觀點之後,scott allen又詳述了乙個做好版本化資料庫的方法,他給出了乙個易於理解 實踐性很強的方法,通過建立基線 使用變更指令碼的方法來管理資料庫的修訂 控制程式化資料庫物件 如檢視 儲存過程 函式和觸發器 並充分利用分支和合併。allen在發布了關係...

資料庫版本控制

資料庫的版本控制與 版本控制的區別在於資料庫中的生產資料是現場創造的,當我們的表結構發生改變時,不能直接用drop table然後再create table,因為這樣會導致生產資料丟失。而 則完全由開發人員創造,可以用完全覆蓋的方式公升級。由於這點不同,致使資料庫在版本控制的過程中必然要採 用與 不...

持續整合環境, Tomcat 的安裝和配置

持續整合環境,tomcat 的安裝和配置 目錄把tomcat壓縮包上傳到tomcat 伺服器上 提取碼 28kr 關閉防火牆 systemctl disable firewalld now 安裝jkd yum y install j a 1.8.0 openjdk tar zxf apache to...