數據庫模型設計連載(7~9)

發表于:2007-04-28來源:作者:點擊數: 標簽:數據庫模型設計連載
連載之7 原創:胖子劉(轉載請注明作者和出處,謝謝) 數據庫 物理模型設計的其他模式 除了上面提到的四種主要設計模式,還有一些其他模式,在某些項目中可能會用到,在這里先簡單做個說明,暫不做深入討論,等到以后的項目用到這些模式的時候,再結合實際

連載之7
原創:胖子劉(轉載請注明作者和出處,謝謝)

數據庫物理模型設計的其他模式
除了上面提到的四種主要設計模式,還有一些其他模式,在某些項目中可能會用到,在這里先簡單做個說明,暫不做深入討論,等到以后的項目用到這些模式的時候,再結合實際需求詳細解說。
(一)繼承模式
繼承模式,可以看作是“主從模式”的一種特殊情況(或者說是“變形”),它所代表的兩個對象也是“一對多”的關系。它與“主從模式”的區別是,“繼承模式”中從表的主鍵是復合主鍵,并且復合主鍵中必定包含主表的主鍵列。
根據從表繼承主表的列的數量,繼承模式又分以下兩種情況:
1.       從表繼承主表的全部列
圖7
在這種情況下,從表除了代表自身的專用字段以外,還冗余了主表的全部字段。這種設計方式的缺點顯而易見:
  • 數據冗余度大
  •  一致性差
  • 磁盤存儲量大
它的優點也顯而易見:
  • 正因為它的冗余度大、所以它不易丟失數據。假設主表數據丟失、或者被誤操作刪改,也能依據從表數據重新生成主表數據;這種設計方式,可以在發生數據損壞的時候從應用的角度進行一定程度的數據恢復,等于是在SQL Server數據庫級別的數據恢復功能之上又加了一道保險。
  • 正因為它一致性差、主表數據被重復存儲,所以可依據外鍵關系進行數據驗證。將主從表記錄作關聯比較,如果數據不一致,就可以得知數據要么被人為改動,或者要么程序代碼中存在bug。
  • 盡管磁盤存儲量大,但是數據在查詢統計的時候,只需針對從表進行搜索即可,無需關聯操作,可以加快檢索的速度。這就是數據庫模型設計中經常提到的“以空間換時間”。
2.       從表只繼承主表的主鍵列
圖8
這種設計方式,從表只繼承了主表的主鍵列,這種方式的優缺點與前面剛好相反。
優點:
  • 數據冗余度小
  • 一致性高
  • 磁盤存儲量小
缺點:
  • 正因為它的冗余度小、所以它易丟失數據。假設主表數據丟失、或者被誤操作刪改,就只能通過SQL Server數據庫級別的數據恢復操作來找回丟失的數據了。
  • 正因為它一致性高,所以無法進行應用程序級的數據驗證。
  • 由于采用了一致性設計,磁盤存儲量較小,但是數據在查詢統計的時候,必須要對兩個表進行內連接(INNER JOIN)操作,才能搜索到相關數據。而內連接操作時需要耗費一定的時間的。這就是數據庫模型設計中經常提到的“以時間換空間”。
當然,在實際的數據庫模型設計過程中,還會有介于上述兩者之間的第3種情況出現,那就是從表繼承了主表的主鍵列以及部分其他列。這就要求我們設計人員要依據實際的業務需求進行綜合分析、權衡、折中,給出最符合業務需求的設計結果。
 
連載之8
原創:胖子劉(轉載請注明作者和出處,謝謝)
(二)自聯結模式
自聯結模式,也可以看作是“主從模式”的一種特殊情況(或者說是“變形”),它在一張表內實現了“一對多關系”,并且可以根據業務需要實現“有限層”或者“無限層”的主從嵌套。
這種模式用得最多的情況就是實現“樹形結構”數據的存儲,比如各大網站上常見的細分類別、應用系統的組織結構、Web系統的菜單樹等都能用到這種模式。
自聯結模式有很多變體,且每種變體的優缺點同樣鮮明。由于本連載的重點在于對跨行業通用數據庫模型設計進行分析,所以對每種具體模式的細節方面的設計技巧不能作詳細論述,請大家原諒。這里僅舉兩個例子說明:
 
1.       簡單自聯結
簡單自聯結,就是在一個表里設置當前類ID、父類ID,同時規定最頂層類的父類ID為一個固定值(比如0),在生成樹的時候使用遞歸算法,記錄的前后順序通過“排序號”字段來確定。
圖9
這個表用來存儲菜單樹很方便。首先會有一個主菜單,主菜單下有子菜單,子菜單下面又有孫菜單……菜單的數量不確定、層級不確定,用戶可以在任意菜單下增加新的子菜單,或者刪除某個子菜單及其下的所有孫菜單……這種設計方式很多人都會用到,短小精悍、維護方便、且完全滿足用戶需求,而且樹的層次不限,擴展起來非常容易。這些都是它的優點。
它的缺點就是樹結構的生成由于使用了遞歸算法,必然要對該表進行多次讀?。ㄗx取的次數 = 表內的記錄數 – 最深層級的記錄數),多次讀取就來了比較低的運行效率,當表里的記錄很多的時候,這個缺點可以稱得上是致命的。
于是就有了下面的這種設計模式。
2.       擴展自聯結
擴展自聯結,與簡單自聯結的最大區別就是通過附加冗余字段來避免遞歸運算,所要實現的主要目標就是一次讀取就能生成整個樹,一次提高樹的生成效率。
但是,魚與熊掌不可兼得,凡事都有兩面性。
生成樹的效率提高了,增刪改表內記錄的算法就會相應復雜,并且樹的層數也變為有限的了。
所以在此類設計的時候,大家還是要認真分析業務需求,看看實際業務的重點在什么地方,然后再作具體設計。比如一些門戶網站在首頁顯示產品類別是業務重點,那么我們在設計的時候就要盡可能的提高生成樹的效率,采取擴展自聯結模式;相反,一些基于Web的業務系統,要求對菜單樹的增刪改維護操作盡量簡單,由于菜單的數目不多,所以菜單樹的生成效率不是瓶頸,那么我們設計的時候就可以采取簡單自聯結模式。
關于附加冗余字段實現擴展自聯結的方法很多,網上也有很多這方面的帖子,大家可以到Google上搜一下。
在這里僅舉一個例子如下:
圖10
這個設計與前面的設計最大的區別就是排序字段,前面的簡單自聯結用了一個整數型的字段來實現排序,這里用了一個Varchar20型的字段“層級代碼”來實現大排序。這個字段的取值兩位一組,代表一層,假定最深為5層,初始值為0000000000。
按照這樣的設計,表內的數據記錄可能就是這樣的:
ID           TypeName           ParentID            TypeLevel
1             根類別               0                 000000
2             類別1                1                 010000
3             類別1.1              2                 010100
4             類別1.2              2                 010200
5             類別2                1                 020000
6             類別2.1              5                 020100
7             類別3                1                 030000
8             類別3.1              7                 030100
9             類別3.2              7                 030200
10            類別1.1.1            3                 010101
……
現在按TypeLevel字段進行排序,執行如下SQL語句:SELECT * FROM TMP_Type ORDER BY TypeLevel
列出記錄集如下:
ID           TypeName           ParentID            TypeLevel
1             總類別               0                 000000
2             類別1                1                 010000
3             類別1.1              2                 010100
10            類別1.1.1            3                 010101
4             類別1.2              2                 010200
5             類別2                1                 020000
6             類別2.1              5                 020100
7             類別3                1                 030000
8             類別3.1              7                 030100
9             類別3.2              7                 030200
……
在控制顯示類別的層次時,只要對“層級代碼”字段中的數值進行判斷,每2位一組,如大于0則向右移2個空格。
連載之9
原創:胖子劉(轉載請注明作者和出處,謝謝)
(三)單表模式
單表模式,就是把相關子類的屬性統統集中在一個表里,通過“類別”字段來區分表內記錄所屬的子類以及該類的有效屬性。在實際案例當中,單表模式的應用還是很廣泛的。舉個例子,有車的朋友現在拿出你們的《中華人民共和國機動車行駛證》,翻到“副頁”,看看副頁登記的檔案指標。下圖為推測設計圖、不代表真實設計。
圖11
我是2006年2月份買的車,我的機動車行駛證副頁記載了如下檔案指標:“號牌號碼、車輛類型、總質量、整備質量、核定載質量、準牽引總質量、核定載客、駕駛室共乘、貨箱內部尺寸、后軸鋼板彈簧片數、外廓尺寸、檢驗記錄?!睘g覽本文的朋友可以跟自己的行駛證對照一下,尤其是老司機,看看若干年前發的行駛證和現在的有沒有區別。
在這里大家可以很清楚的看到,上述指標中“號牌號碼、車輛類型、總質量、整備質量、外廓尺寸、檢驗記錄”是各種類型的車輛的公共屬性,“核定載質量、準牽引總質量、駕駛室共乘、貨箱內部尺寸、后軸鋼板彈簧片數”是貨運車輛的專有屬性,“核定載客”是客運車輛的專有屬性。
根據經驗我推測,就此種表現形式而言,公安機關交通管理部門的計算機系統應該就是采用“單表模式”進行的設計。通過這一個表就可以容納包括貨車、客車、轎車、摩托車、農用車等所有類型的車輛檔案。這里面有一個“車輛類型”屬性,這個屬性就是用來區分當前記錄所屬類別,程序代碼根據這個屬性的值來確定當前檔案記錄的哪些屬性是有效、且需要記錄和打印的,哪些屬性對當前記錄來說是無效的。比如我行駛證上的車輛類型是“轎車”,除公共屬性以外,只有“核定載客”指標打印了一個“5人”字樣,其余指標打印的都是“--”字樣,因為這些指標都是貨車才有的,對轎車而言是無意義的。
這種設計有一個明顯的好處——如果事先對車輛檔案都有哪些指標調研的很充分,且后期基本上不需要擴展,那么系統運行時無論遇上什么類型的車輛檔案都不需要變更程序,具有很強的通用性。很明顯,行駛證是套打的,這種設計便于大批量的制作證件底單。因為不管什么類型的車輛檔案都是這個格式,只要開動機器印刷便是。
凡事有利就有弊,這種設計的弊端也很明顯。首先是給人的印象不是很人性化。我明明買的是轎車,你發給我的證件搞那么多貨車的指標在上面干嘛?浪費版面!其次,如果一旦后期需要對某種類型的車輛檔案擴充屬性(無論你前期的需求調研多么充分,都不能保證以后不會變化),假設國家新頒布一部法規或者國標,要求必須在行駛證上記載客車的“發動機排量”、其他類型的車輛不作要求,那么按照這種設計,所有車輛(包括“無辜的”貨車在內)都要換證(呵呵,不知道這種換證收不收工本費)!
聲明:以上例子僅僅是我的推測,用以說明“單表模式”。我沒有交通管理部門的工作經歷,如果與實際情況不符,歡迎同行批評指正。
 

原文轉自:http://www.anti-gravitydesign.com

国产97人人超碰caoprom_尤物国产在线一区手机播放_精品国产一区二区三_色天使久久综合给合久久97