關系數據庫設計
一、基本概念
1關系模型
表:和數學上的關系這個概念密切相關,關系數據庫是表的集合。表中的一行代 表了一系列值之間的聯系。
屬性:表的列首被稱為屬性。
域:屬性所允許的值。
數學上的描述
關系:可以代替“表”這個概念的數學名詞。關系是元組的集合。
元組:可以代替“行”這個概念的數學名詞。
元組變量:代表元組的變量,以所有元組集為域的變量。
原子的域:域的元素被看做是不可再分的單元。
超碼:一個或多個屬性的集合。這些屬性的組合可以在一個關系中唯一標識一個元組。
候選碼:最小的超碼,它的任意真子集都不能構成超碼。
主碼:被數據庫設計者選中的,用來在同一個關系中區分不同元組的候選碼。
外碼:一個關系模式
參照關系:稱r1為外碼依賴的參照關系。
被參照關系:稱r2為外碼的被參照關系。
數據庫模式:數據庫的邏輯設計。
數據庫實例:給定時刻數據庫中數據的一個快照。
與程序設計語言類比
關系模式:相當於程序設計語言中類型定義的概念。其與關系的區別在於,關系相當於程序設計語言中變量的概念。
關系實例:對應於程序設計語言中變量的值得概念
2 實體-聯系模型(E-R模型)
實體-聯系模型(E-R數據模型):基於對現實世界的這樣一種認識,世界由一組稱為實體的基本對象及這些對象間的聯系組成。E-R模型的三個基本概念:實體集,聯系集,屬性。
實體
實體集:具有相同類型及共享相同性質的實體集合。
實體集有可能相交。
數據庫包括一組實體集,每個實體集中包括一些相同類型的實體。
實體集可能有多個屬性。
實體集中的實體可以用一個(屬性,數據值)對的集合來表示。
實體集的外延:組成實體集的各實體。
屬性:實體集中每個成員具有的描述性性質。。
屬性的域(屬性的值集):屬性都有一個值,屬性的可取值的集合為屬性的域。
簡單屬性:不能劃分為更小的部分的屬性。
復合屬性:可再劃分為更小的部分的屬性。
單值屬性:對特定實體都只有單獨的一個值的屬性。
多值屬性:可能對應一組值的屬性。
派生屬性
基屬性(存儲的屬性):被派生的屬性。
聯系:多個實體間的相互關聯。
聯系集:同類型聯系的集合。
參與:實體集之間的關聯稱為參與。
聯系實例:表示所模擬的現實世界的命名實體間的一個關聯。
實體的角色:實體在聯系中的作用。
聯系集的度:參與聯系集的實體集的數目。
映射基數(基數比例):通過一個聯系集能同時與另一個實體相聯系的實體數目。
對實體集A與B之間的二元聯系集,其映射基數為:
一對一:A中的一個實體至多同B中的一個實體相聯系,B中的一個實體也至多同A中的一個實體相聯系。
一對多:A中的一個實體可以同B中的任意數目的實體相聯系,而B中的一個實體至多同A中的一個實體相聯系。
多對一:A中的一個實體至多同B中的一個實體相聯系,而B中的一個實體可以和A中的任意數目的實體相聯系。
多對多:A中的一個實體可以同B中的任意數目的實體相聯系,B中的一個實體也可以同A中的任意數目的實體相聯系。
實體集E全部參與聯系集R:實體集E中的每個實體都參與到聯系集R的至少一個聯系中。
實體集E部分參與聯系集R:實體集E中只有部分實體參與到聯系集R中。
碼:用以區別實體和聯系,並惟一地標識聯系。
超碼:一個或多個屬性的集合,這些屬性的組合可以使我們在一個實體集中惟一地標識一個實體。
候選碼:最小的超碼,其任意真子集都不能成為超碼。
主碼:用來在同一實體集中區分不同實體的候選碼。
應該選擇那些從不或極少變化的屬性作為主碼。
聯系的主碼結構依賴於聯系集映射基數。一對一的聯系中,可使用兩個主碼中的任何一個作為聯系的主碼。多對多的聯系中,聯系的主碼由兩個主碼共同構成。一對多的聯系中,聯系的主碼由其中之一決定。
弱實體集:屬性不足以形成主碼的實體集被稱為弱實體集。
強實體集:有主碼的實體集。
標識實體集(屬主實體集):弱實體集所依賴的強實體集。
標識性聯系:將弱實體集與其標識實體集相聯系的聯系集。標識性聯系是從若實體集到標識實體集的多對一聯系,且弱實體集全部參與聯系。
分辨符:能夠區分若弱實體的屬性集合。
特殊化:在實體內部分組的過程。
一般化:高層實體集與一個或多個低層實體集間的包含關系。
超類:即高層實體集。
子類:即低層實體集。
屬性繼承:由特殊化和一般化所產生的高層實體和低層實體的一個重要特性,高層實體集會被低層實體集繼承。
二、規範化原則
第一範式
如果一個關系模式R的所有屬性域都是原子的,稱關系模式R屬於第一範式。更一般地表達方式為,所有屬性都是簡單屬性,這樣的實體集符合第一範式。
第二範式
如果實體集符合第一範式,並且非主碼完全依賴於主碼,這樣的實體集符合第二範式。
第三範式
如果實體集符合第二範式,並且其非主碼均不依賴於其他任何非主碼,這樣的實體集符合第三範式。
三、設計過程(非關系型數據庫可用)
第一階段,需求分析。和領域專家、數據庫用戶廣泛交流,獲得較詳細的規格說明,最終提交的產品為用戶需求規格說明。
第二階段,概念設計。選擇數據模型,將需求轉換為數據庫的概念模式。
若為關系型數據庫設計,那麽必定選擇關系模型,最終提交的產品為實體-聯系圖和功能需求規格說明。本階段的具體工作就是:定義數據庫中表示實體,實體屬性,實體之間的聯系和實體上的限制;描述在數據上進行的各類操作(增刪改查)或事物。
獲得E-R模型後使用上面介紹的範式進行檢驗和優化。
第三階段,邏輯設計。將概念模式映射為將被使用的數據庫系統的實現數據模型。
若為關系數據庫設計,要實現數據模型就是關系數據模型,通常將E-R模型定義的概念模式映射為關系模式,所以最終提交的產品為關系模式。
獲得關系模式後,使用上面介紹的範式對模式檢驗和優化。
第四階段,物理設計。定義數據庫的物理特征,完成設計。
四、設計過程詳解
1概念設計要點
1)應該選擇實體還是屬性?
實體和屬性的概念並不是非常精確的,其區別取決於被建模的現實中的事物的特征或結構。
一般的原則是,根據被建模的現實事物的特征,要使用屬性前先要判斷此屬性是否可以再次分割,即此屬性是否有包含了其他一些“屬性”,這些屬性能夠更精確地描述它,這個時候應該使用實體而不是屬性。
2)一個實體集的主碼可以作為另一個實體集的屬性嗎?
一般來講,在建模的過程中,將一個實體集屬性作為另一個實體集的屬性是不合適的,最明顯的缺點就是造成數據的重復存儲,況且將一個實體集的主碼作為另一個實體集的屬性更不恰當,因為,如果在建模的過程中,發現兩個實體似乎有著共同的屬性,那麽這兩個實體之間必然存在聯系,這時應抽象出兩個實體集的聯系,將他們的關系用聯系明確的表達出來,而不是將關系隱藏起來。
3)可以將相關實體集的主碼屬性作為聯系集的屬性嗎?
由於聯系集中隱含了相關實體集的主碼屬性,所以不要將相關實體集的主碼屬性作為聯系集的屬性。這樣做常常是由於概念不清導致的。
4)是否可以將兩個實體集的聯系集也設計為實體集?
具體情況具體分析。
若相關實體集與聯系集都是一對一的關系,那麽用聯系集比較好。此外,描述實體間的行為時用聯系比較好。
若不上述假設不成立,那麽應考慮將兩個實體集的聯系集設計為實體集。
5)避免使用四元或高於四元的聯系集
一些看起來非二元聯系集通常可以轉換為多個二元聯系集,但將有些高元聯系生硬地轉換成多個二元也是不恰當的。
6)盡可能將兩個實體集間的多對多的聯系轉換為一對一或一對多的聯系
7)聯系屬性的布局
將描述性屬性放到聯系集還是實體集取決於業務特點。
一對一的聯系集,聯系的屬性可以放到任一參與聯系的實體中。
一對多的聯系集,聯系的屬性僅能放到參與聯系的“多”的那邊的實體集中。
多對多的聯系集,聯系的屬性一般放在聯系集中
8)應該選擇那些從不或極少變化的屬性作為主碼
9)弱實體集與多值屬性
如果弱實體集只參與標識性聯系,並且屬性不多,可以將弱實體集表示為屬主實體集的一個復合屬性。
10)特殊化還是一般化
采用的特化是為了表達實體集所包含的子集之間的差異,突出強調子集的特征,以滿足業務的需要。
采用一般化的原因是凸顯實體集間的相似性隱藏他們之間的差異,以滿足業務的需要。
11)使用聚集
E-R模型無法表達聯系間的聯系。聚集表達了更復雜的關系。當需要表達聯系間的聯系或聯系與實體間的聯系時使用聚集。
2邏輯設計要點
邏輯設計就是要將ER模型轉換為關系模式
1)由強實體集導出的關系模式
強實體集的主碼就是生成的關系模式的主碼。強實體集的描述屬性就是關系模式的屬性。
2)由弱實體集導出的關系模式
有弱實體集A和強實體集B,A依賴於B。
由弱實體集A導出的關系模式的主碼由B的主碼和A的分辨符組合而成。
在關系A上指明外碼約束,
3)由聯系集導出的關系模式
有聯系集R,參與R的所有實體集的主碼的並集為C,由並集構成的屬性集合P={p1,p2,p3,......}
R的描述性屬性為D ={d1,d2,d3,......}
聯系集導出的關系模式的屬性對應於P與D的並集中的各個屬性。
關系的主碼的確定規則為:
一對一的二元聯系集,關系模式的主碼是是參與聯系的實體集中任意一個的主碼。
多對一的二元聯系集,關系模式的主碼是聯系集中“多”的一方的實體集的主碼。
多對多的二元聯系集,關系模式的主碼是參與聯系的實體集的主碼的並集。
4)模式冗余
一般地,參與聯系的實體中,包含了弱實體集及其依賴的強實體集,那麽由此聯系集導出的關系模式極可能是冗余的。
5)關系模式的合並
一對一的聯系,聯系集的關系模式可以和參與聯系的任一實體集的關系模式合並。
部分參與到聯系中的情形,可以通過使用空值進行模式合並。
合並之後的模式的外碼約束要做相應的調整。
6)復合屬性與多值屬性
復合屬性的處理方式:為每個子屬性創建單獨的屬性。
多值屬性的處理方式:為多值屬性M創建關系模式R。
R具有的屬性包括:對應M的屬性A,以及M所在的實體集的主碼。
R的主碼由模式中所有屬性構成。
7)一般化
為高層實體集創建一個模式,為此高層實體集的每個低層實體集創建一個模式,模式中的屬性包括對應於低層實體集的每個屬性和對應於高層實體集的主碼的每個屬性。高層實體集的主碼屬性也是低層實體集的主碼屬性。
也可以不為高層實體集創建模式,只為每個低層實體集創建模式,這樣低層實體集的屬性為對應的低層實體集的屬性以及對應的高層實體集的屬性。
8)由聚集導出的關系模式
表示聚集不需要單獨導出關系模式,聚集關系模式是定義該聚集的聯系集的關系模式。
9)聚集與實體集間的聯系導出的關系模式
這種聯系導出的關系模式,屬性包括對應實體集的主碼中的每個屬性、聯系集主碼中的每個屬性、聯系集(聚集與實體集間的聯系集)的描述性屬性。
五、設計實例
下面僅對部分關鍵建模問題加以分析。
應用背景描述:
提供在線文獻閱讀和下載的網站,有普通的用戶和網站的管理員,如果平臺對外開放API服務,那麽還有開發者,即授權調用API的用戶。
文獻按種類可分為:期刊,會議,報紙,博士碩士論文,圖書等。
若將文獻按行業分類為:建築建材,水利水電,石油化工,信息產業等。
若將每個行業細分,比如:電訊、電話、印刷、出版、新聞、廣播等。
為方便用戶閱讀,所以還要提供導航,導航類似於將每個行業細分的結果。
系統將用戶的行為呈現給用戶,例如下載量,閱讀量,瀏覽歷史。
可以訂閱喜歡的刊物,實時跟蹤最新文章動態。
用戶可以自定義主題,按照自定義主題檢索相關文獻。系統也會提供默認的主題。
用戶可以收藏喜歡的文章,還可以下載文獻。
根據上述描述獲得實體:
普通用戶(讀者),用戶所屬的機構,網站管理員,API開發者,文獻,行業,導航,主題,統計信息。
E-R建模分析與導出關系模式:
可以將用戶的賬號作為主碼,但在實際使用過程中,卻常使用自增的Id作為主碼,稱為UserId,雖然自增的Id不是構成實體所必須的,原因是自增Id是整型而賬號一般為字符串,且一般關系數據庫默認建立索引,整型上的索引有一定的優勢。
統計信息只與普通用戶有聯系,可以將統計信息和普通用戶合並為一個實體,即統計信息成為復合屬性,但這是不好的設計。雖然這樣可以減少實體數量,但是普通用戶的基本信息,例如賬號,密碼,郵箱等是不經常變化的。而統計信息是隨著用戶的行為經常變化的。所以這裏用實體而不用屬性。這裏沒有將弱實體集轉換為強實體集的復合屬性。
統計信息構成弱實體集,它依賴強實體集,即由所有普通用戶構成的實體集。弱實體集分辨符取自增Id,稱為StaticId。導出關系模式的主碼是分辨符即StaticId與用戶UserId
收藏是用戶的一種行為,一個用戶可以收藏多篇文章,一篇文章也可被多個用戶收藏,他們是多對多的關系。通過收藏這種行為用戶和文獻建立起了關系。
收藏時間是關系的描述性屬性,由於是多對多的關系,所以收藏時間應該放在聯系集中。導出的關系模式的主碼為用戶實體集與文章實體集的主碼的並集。
導航和用戶之間的關系也是多對多的。客戶端頁面的導航要有一個顯示順序,而且是可以調整的。那麽導航順序這個屬性也應該放在聯系集中。
平臺的用戶包括普通的用戶和API使用者,他們都是用戶,有共性又有差別。根據API接口的訪問權限可以對使用API的用戶細分,例如:超級用戶可以調用涉及修改操作的API接口,而一般用戶只能調用涉及查詢操作的API接口,但這種細分不構成一般化與特殊化的概念。這裏並未采用為高層實體創建模式的方式實現一般化的過程。而是為每個低層實體創建一個模式。
參考書目:
數據庫系統概念 (原書第5版)
作者:(美)Abraham Silberschatz/(美)Henry F.Korth/(美)S.Sudarshan
出版社: 機械工業出版社
譯者: 楊冬青/馬秀莉/唐世渭
關系數據庫設計