|
說實(shí)話我也是前兩周才知道有數(shù)據(jù)庫重構(gòu)這回事,當(dāng)時聽說這個概念的時候,唯一的反應(yīng)就是:數(shù)據(jù)庫居然也能重構(gòu)?剛好上周去圖書館借書,看見了《數(shù)據(jù)庫重構(gòu)》這本書,就借回來看了幾章。下面會結(jié)合自己的體會介紹一些這本書的一些觀點(diǎn)。
數(shù)據(jù)庫重構(gòu)概念
數(shù)據(jù)庫重構(gòu)是對數(shù)據(jù)庫Schema進(jìn)行的簡單改動,在保持行為和信息語義的前提下改進(jìn)設(shè)計。
數(shù)據(jù)庫重構(gòu)可以重構(gòu)數(shù)據(jù)庫Schema的結(jié)構(gòu):比如表、視圖的定義、修改; 重構(gòu)數(shù)據(jù)庫的功能:如存儲過程、觸發(fā)器等。
數(shù)據(jù)庫重構(gòu)的困難
數(shù)據(jù)庫重構(gòu)其實(shí)并不像代碼重構(gòu)那么簡單,對數(shù)據(jù)庫結(jié)構(gòu)的改動,真的是牽一發(fā)而動全身。可能你要改動業(yè)務(wù)邏輯層、UI表示層、甚至是牽連到一些其它模塊、外部調(diào)用程序,還有像數(shù)據(jù)庫里面的函數(shù)、存儲過程、觸發(fā)器等、光是把這些牽扯的例舉出來,都會讓你頭皮發(fā)麻,還要大量的測試;而且對一個已經(jīng)上線的系統(tǒng),你有這個魄力去重構(gòu)嗎?就算你有,未必其它同事、尤其拍板的人(經(jīng)理)也未必同意,這里面的風(fēng)險太大,代價太大了…..其實(shí)這都是因?yàn)閿?shù)據(jù)庫重構(gòu)比代碼重構(gòu)難,復(fù)雜。下面是我自己概括的一些:
- 代碼重構(gòu)只需要保持行為語義, 而數(shù)據(jù)庫重構(gòu)還要保持信息語義。
- 數(shù)據(jù)庫架構(gòu)所導(dǎo)致的耦合度(數(shù)據(jù)庫與外部程序是高度耦合的),數(shù)據(jù)庫重構(gòu)變得相當(dāng)復(fù)雜。按情況分分為單應(yīng)用數(shù)據(jù)庫、多應(yīng)用數(shù)據(jù)庫(相對復(fù)雜得多),下面是我按書上圖畫的單應(yīng)用數(shù)據(jù)庫和多應(yīng)用數(shù)據(jù)庫。
- 數(shù)據(jù)庫重構(gòu)缺少工具支持。像代碼重構(gòu),很多IDE(集成開發(fā)環(huán)境)都已經(jīng)提供了代碼重構(gòu)功能,比如VS里面菜單欄里面有重構(gòu)選項(xiàng),許多人都經(jīng)常使用。但是數(shù)據(jù)庫到現(xiàn)在為止沒啥工具支撐。相信數(shù)據(jù)庫工具提供商以后也一定會增添這些功能的。
- 數(shù)據(jù)庫設(shè)計、開發(fā)采用傳統(tǒng)的、串行式的思維過程,基本上忽略了敏捷的方式(說實(shí)話,我對作者這個觀點(diǎn)不太理解)。我的理解數(shù)據(jù)庫開發(fā)一直采用傳統(tǒng)的建模,設(shè)計,然后編碼實(shí)現(xiàn),沒有采用反映現(xiàn)代方法學(xué)(如XP 和RUP)的演進(jìn)式方式。
- 不是每個開發(fā)者對系統(tǒng)各部分、數(shù)據(jù)庫架構(gòu)都十分了解,不是每個人都精通數(shù)據(jù)庫和應(yīng)用程序開發(fā)。也就是說可能某人只精通數(shù)據(jù)庫、而不精通C#開發(fā),那么重構(gòu)就顯得比較困難。還有很多人只了解系統(tǒng)的部分結(jié)構(gòu),而不了解整體,這對數(shù)據(jù)庫重構(gòu)影響很大,作者建議結(jié)對編程,DBA和架構(gòu)師(技術(shù)人員)結(jié)對進(jìn)行數(shù)據(jù)庫重構(gòu)
數(shù)據(jù)庫重構(gòu)的分類
- 結(jié)構(gòu)重構(gòu): 對一個或多個表或試圖做一些變更。比如將一列從一個表移到另外一個表,將多用途的列拆分為一些單獨(dú)的列。每個列用于單一用途。
- 數(shù)據(jù)質(zhì)量重構(gòu):一種變更,改進(jìn)了數(shù)據(jù)庫中所包含信息的質(zhì)量。例如,不允許列為空,確保它總是有值,或?qū)σ涣胁捎媒y(tǒng)一格式,確保一致性。
- 參照完整性重構(gòu):一種變更,它確保參照的行在另外一個表的存在,并確保不需要的行被相應(yīng)地刪除。增加觸發(fā)器支持兩個實(shí)體間的層疊式刪除。
- 架構(gòu)重構(gòu)。 一種變更,它從整體上改變了外部程序與數(shù)據(jù)庫進(jìn)行交互的方式。用存儲過程取代部分代碼和腳本。
- 方法重構(gòu): 對方法(存儲過程、函數(shù)、觸發(fā)器)的一種變更,改進(jìn)方法質(zhì)量,比如存儲過程改名,把存儲過程里面的*用相應(yīng)的字段替換、、、、、
- 替換: 這不屬于重構(gòu),轉(zhuǎn)換時對數(shù)據(jù)Schema的一個變更,它改變了Schema的語義。
數(shù)據(jù)庫味道
正如Flower在重構(gòu)里面說的代碼的壞味道一樣,作者也嘗試總結(jié)了一些數(shù)據(jù)庫的壞味道。
- 多用途的列。 如果一個列被用于多種用途,就有可能存在額外的代碼來確保數(shù)據(jù)以“正確的方式”使用。個人認(rèn)為像表里面用來判別性別、是否刪除的字段這樣的多用途列還不是壞味道,如果超出了兩個應(yīng)用,就應(yīng)該考慮重構(gòu)了。
- 多用途的表。 如果一個表用來存放多種不同數(shù)據(jù)來源的數(shù)據(jù)。
- 重復(fù)的數(shù)據(jù)。重復(fù)的數(shù)據(jù)對操作型數(shù)據(jù)庫來說是一種嚴(yán)重的問題,因?yàn)閿?shù)據(jù)存放在幾個地方,不一致的機(jī)會就增加了。個人認(rèn)為適當(dāng)?shù)娜哂噙€是必須的。這個只能試情況而論。
- 列太多的表。一個表包含太多的列時,說明表缺乏內(nèi)聚——它試圖存放來自幾類實(shí)體的數(shù)據(jù)。我見過一個表幾十個字段的設(shè)計,只能用“無語”來形容我的感受。
- 行太多的表。大的表就有性能問題,查找就十分耗時,你這時就需要對表進(jìn)行垂直分割:將一些列移到另外一個表,將一些行移到另外一個表,進(jìn)行水平分割。
- “智能”列:智能列是這樣一種列,其中數(shù)據(jù)的不同位置代表了不同的概念。這個我不太了解(沒有這方面的使用經(jīng)驗(yàn)),作者的建議進(jìn)行更小粒度的分割字段。
- 害怕變化。如果你害怕改變你的數(shù)據(jù)庫Schema,因?yàn)槟銚?dān)心更改會破壞其它很多應(yīng)用程序,那么這就是一個明確的信號。
數(shù)據(jù)庫重構(gòu)在開發(fā)中的位置
作者提到了大多數(shù)面向數(shù)據(jù)技術(shù)本質(zhì)上都是串行的。諸如邏輯數(shù)據(jù)建模或物理數(shù)據(jù)建模。希望數(shù)據(jù)庫DBA采用類似開發(fā)者使用的現(xiàn)代演進(jìn)式技術(shù)來開發(fā),并能從中獲益。作者提供了一幅圖關(guān)于在一些關(guān)鍵開發(fā)活動中的高層視圖,這些活動發(fā)生在涉及對象和關(guān)系數(shù)據(jù)庫的現(xiàn)代項(xiàng)目中。請注意,所有的箭頭都是雙向的。你需要在這些活動之間來回迭代。同時注意沒有定義起點(diǎn)和終點(diǎn)——顯然這不是傳統(tǒng)的串行式過程。
it知識庫:數(shù)據(jù)庫重構(gòu)《Refactoring DataBase Evolutionary DataBase Design》介紹,轉(zhuǎn)載需保留來源!
鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請第一時間聯(lián)系我們修改或刪除,多謝。