Allen在發(fā)布了關(guān)系型數(shù)據(jù)庫開發(fā)的三個原則的經(jīng)驗總結(jié)文章之后,就開始寫后續(xù)的系列文章了。這三個原則如下:
一、不要在共享數(shù)據(jù)庫服務(wù)器上進(jìn)行開發(fā)工作
就像軟件開發(fā)中其它所謂便捷的方法一樣,共享數(shù)據(jù)庫的使用也是一個泥潭,它正等著凍結(jié)一個項目呢。開發(fā)人員相互覆蓋彼此所做的修改,我在服務(wù)器上所做的改變讓你的開發(fā)機(jī)器上的代碼中斷運行,這些都讓遠(yuǎn)程開發(fā)速度很慢而且非常困難。避免使用共享數(shù)據(jù)庫,也就免避了因使用它造成的極度時間浪費和因之而生的Bug。
二、僅保留一份權(quán)威的Schema生成源
每一個人都必須知道該從哪里獲得正式的Schema,并且可以用它輕松地重新創(chuàng)建一個新的數(shù)據(jù)庫。當(dāng)我走到電腦前,可以從源碼庫中獲得最新的版本,構(gòu)建后就可以通過最簡單的工具創(chuàng)建數(shù)據(jù)庫(在更多的場景中,構(gòu)建的過程甚至可以在數(shù)據(jù)庫不存在時自己創(chuàng)建一個,所以這個構(gòu)建過程應(yīng)該是一步到位方式的)。
三、對你的數(shù)據(jù)庫進(jìn)行版本管理
這樣做的原因之一就是要將變化由開發(fā)傳遞到測試,最終在一種可控制的、一致的環(huán)境下生產(chǎn)。其二就是可以重建任何時間點上的數(shù)據(jù)庫,如果你正在將軟件交付給客戶的話,這一點就尤為重要。如果有人在你提交的應(yīng)用版本build 20070612中發(fā)現(xiàn)了bug,你就必須能重建當(dāng)時那個版本的狀況——包括數(shù)據(jù)和其它所需。
Allen說明了版本化數(shù)據(jù)庫的目的就是為了能保證所做的改變能保持一致性、可控性、可測試性和可重現(xiàn)性。許多推廣者都同意這一點,并認(rèn)為實現(xiàn)這個目標(biāo)對任何一個敏捷團(tuán)隊的效率都很重要。
在列出了版本化數(shù)據(jù)庫的重要性后,Allen又相繼發(fā)布了4個貼子來描述他推薦的實現(xiàn)方法。
其中,第一篇貼子描述了Allen宣稱的版本化數(shù)據(jù)庫的起點——創(chuàng)建一個數(shù)據(jù)庫Schema基線。從本質(zhì)上來講,這個基線是一個腳本,或者是一連串腳本,它包含所有可以從零開始生成應(yīng)用數(shù)據(jù)庫的SQL命令。它包括創(chuàng)建所有數(shù)據(jù)庫所有對象(表、約束、函數(shù)、視圖、索引等)的SQL命令、表查詢及操作命令和插入應(yīng)用所需初始數(shù)據(jù)的命令。Allen建議,一旦它完成創(chuàng)建并且驗證無誤,應(yīng)立刻“將它提交到源碼控制庫”,此時“你可以認(rèn)為已將數(shù)據(jù)庫基線化了 ”。
對于如何創(chuàng)建這個基線,Allen建議使用那些能從現(xiàn)有數(shù)據(jù)庫中導(dǎo)出腳本的工具(與手工編寫他們的過程相反)。作為參考,他還描述了他是如何結(jié)構(gòu)化那些生成的腳本文件的:
我喜歡將所有生成表、約束、缺省值和主鍵的SQL語句保存到同一個文件中,而那些創(chuàng)建視圖、存儲過程、函數(shù)的腳本則分開來單獨存儲。
如果你喜歡多文件保存的方式,那就需要一個批處理文件,shell腳本,應(yīng)用程序,或其它自動化工具來自動定位并運行安裝數(shù)據(jù)庫需要的所有腳本文件。人工干涉這個過程是一種倒退。
Allen建議并強(qiáng)調(diào),基線中需要一個表用來記錄任何有關(guān)數(shù)據(jù)庫結(jié)構(gòu)的改變,在他后面的三個貼子中,他詳細(xì)描述了該如何處理這些變化。
首先,Allen討論了變更腳本——一種管理除視圖、存儲過程、函數(shù)以外的數(shù)據(jù)庫對象的機(jī)制。這種方法要求任何一個改變(或一組相關(guān)的改變)必須有一個新生成的腳本文件可通過“增量”更新的方式來代表,這與Ruby Migration很相似。換句話說,當(dāng)團(tuán)隊發(fā)現(xiàn)數(shù)據(jù)庫需要做改變時,他們創(chuàng)建一個新的腳本來將數(shù)據(jù)庫修改到想要的樣子,通過測試后提交到源碼控制庫中。一旦發(fā)布后,這個腳本就永遠(yuǎn)不要再修改。
Allen這么做使視圖、存儲過程和函數(shù)的更新方式與其它數(shù)據(jù)庫對象完全相反,每個對象都有一個“創(chuàng)建命令”文件,然后通過更新這一個文件來更新這些對象,對于為什么他喜歡這樣做,他解釋到:
原因很簡單,就是為了更快速地確定問題所在。如果有人提交了一個數(shù)據(jù)庫結(jié)構(gòu)變化,它移除了視圖所引用的一個列,那么你可以盡早地發(fā)現(xiàn)有錯誤,因為在構(gòu)建版本提交到測試以前,這個問題就會被發(fā)現(xiàn);同樣,如果有人提交了一個視圖,但卻忘了發(fā)布它所需要的結(jié)構(gòu)改變,幾分鐘后就會有人跑到他們的桌子前問他們?yōu)槭裁匆茐能浖倪\行。
另一個原因就是為了避免我遇到過的某些不太常見的錯誤。對于那些隱匿在視圖背后的Schema的變化,某些數(shù)據(jù)庫產(chǎn)品仍會強(qiáng)迫完成執(zhí)行計劃,而由此引發(fā)的問題很難跟蹤。“扔掉所有的東西,重新開始”會避免發(fā)生這類事情。
Allen著重強(qiáng)調(diào)了利用自動化工具更好地實施上述策略的重要性:
當(dāng)開發(fā)人員、測試人員或者安裝人員從源碼控制庫中更新并運行本地數(shù)據(jù)升級工具時,它就像會魔術(shù)般地完成工作。它有三個步驟:
1、通過對比現(xiàn)有數(shù)據(jù)庫結(jié)構(gòu)變更腳本文件和SchemaChangeLog表中的記錄,來應(yīng)用最新的數(shù)據(jù)庫結(jié)構(gòu);
2、刪掉數(shù)據(jù)庫中所有的存儲過程、視圖和函數(shù);
3、運行所有的變更腳本將視圖、存儲過程和函數(shù)添回到數(shù)據(jù)庫中去。
對于遵循這些策略的好處,尤其是使用自動化工具,Allen給出了一些示例:
由于數(shù)據(jù)結(jié)構(gòu)變更腳本保存在源碼控制庫中,你可以在任何時候重新創(chuàng)建任意時間點上的數(shù)據(jù)庫。如果客戶報告了一個關(guān)于build 3.1.5.6723的bug,那么,你所需要做的就是獲取相應(yīng)版本標(biāo)號或標(biāo)記過的源碼,然后運行這一基線和這一標(biāo)記下所有的數(shù)據(jù)庫變更腳本。當(dāng)其運行結(jié)束后,你就已經(jīng)有了一份與客戶發(fā)現(xiàn)bug時一模一樣的數(shù)據(jù)庫,也就獲得了一個重現(xiàn)這個bug的好機(jī)會。而且,當(dāng)改變由開發(fā)階段進(jìn)入測試階段時,就從根本上提供了一個一致的、有序的、可重現(xiàn)的產(chǎn)品。
Allen在這一系列文章的最后,還提及他是如何處理分支與合并的,而這是所有應(yīng)用在版本服務(wù)器上建立它的第一個版本后都要面對的現(xiàn)實問題。 Allen建議為發(fā)布而分支,這也是他偏好的分支策略,同時解釋了他為什么會為每個新的發(fā)布版本重創(chuàng)數(shù)據(jù)庫基線。他通過一個示例來描述了這個問題,并添加了這樣一個場景:在較早版本中發(fā)現(xiàn)了缺陷,就必須對已分支的版本進(jìn)行相應(yīng)的數(shù)據(jù)構(gòu)結(jié)構(gòu)變更。在這個分支版本中,創(chuàng)建新的腳本來處理變更是沒有問題的,問題是,如何將這個變更也應(yīng)用到當(dāng)前的主線版本中:
想要在主線中修復(fù)它,有兩種選擇。實際上可能會有無數(shù)種可能性,這取決于你想如何應(yīng)用你的更新。但這里只提供兩種選擇:
1、將數(shù)據(jù)庫變更腳本合并到當(dāng)前主線版本01.00.0046的腳本中,并在基線版本2.0中進(jìn)行相應(yīng)的修復(fù)來處理這一變更;
2、寫一個新的數(shù)據(jù)庫結(jié)構(gòu)變更腳本02.00.0003,其與分支版本46中的變更保持一致。
對于選項一,你必須小心處理,因為任何已經(jīng)更新到v2.0版的數(shù)據(jù)庫都并不會從分支上獲得46號變更腳本(除非你編寫的工具與我的不一樣)。你只能讓別人手工運行這一腳本,或者你自己查看對與現(xiàn)存的2.0版本數(shù)據(jù)庫沖突(對于這種結(jié)果,無論如何僅限于在開發(fā)和測試機(jī)器上)。所以,除非你剛開始著手 2.0的開發(fā)不久,否則這個選擇并不算太好。
相比之下,選項二則要友好多了。1.0版本的數(shù)據(jù)庫將會從01.00.0046中獲得修復(fù)。2.0版本的數(shù)據(jù)庫則在02.00.0003中得到修復(fù)。但你也要很小心地去編寫02.00.0003的修改腳本,以免它履蓋運行01.00.0046腳本后所做的修改。
換句話說,數(shù)據(jù)庫是按照2.0版的基線腳本安裝的,必須要應(yīng)用02.00.0003腳本,但實際的產(chǎn)品數(shù)據(jù)庫可能是從1.0版開始的,它將應(yīng)用 01.00.0046腳本來修復(fù),所以你不能讓02.00.0003去再次修改這個實際已經(jīng)升級到2.0版的數(shù)據(jù)庫否則,會造成錯誤
聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com