前言
ER建模環節完成后,需求就被描述成了ER圖。之后,便可根據這個ER圖設計相應的關系表了。
但從ER圖到具體關系表的建立還需要經過兩個步驟:1. 邏輯模型設計 2. 物理模型設計。其中前者將ER圖映射為邏輯意義上的關系表,后者則映射為物理意義上的關系表。邏輯意義上的關系表可以理解為單純意義上的關系表,它不涉及到表中字段數據類型,索引信息,觸發器等等細節信息。
本文將詳細介紹前者。確切來說,也就是ER模型到邏輯關系表的映射是如何完成的。
基本概念
在開始進行ER模型到邏輯關系表的具體映射之前,首先來學習一下邏輯模型中所涉及到的一些概念。
1. 關系(relation)
關系就是在數據庫中存在的,包含行和列的一張表。也常被稱為關系表,或者表。注意只有在確保不會引起混亂的時候使用最后一種稱呼,因為關系表和一般意義上的表有很大區別(下文會分析)。
2. 列(column)
列就是字面意義上表的列。但是它也有時被稱作屬性,或者域。
3. 行(row)
行就是字面意義上表的行。但是它也有時被稱作元祖,或者記錄。
4. 關系表 VS 一般的表
關系表有以下幾個基本約束:
a. 一個列只能有一個名稱;
b. 不能出現完全一樣的行;
c. 表中每個值都必須為單值;
d. 同一列中的所有值都必須屬於同一個域;
e. 行/列順序無關
5. 主碼(primary key)
每個關系必須要有一個主碼(可含多列),用來唯一標識表中各行記錄。
6. 實體完整性約束(entity integrity constraint)
指所有主碼必須非空。
6. 外碼(foreign key)
外碼是某關系中的一列,而這一列恰恰又是另一個關系的主碼。
7. 參照完整性約束(reference integrity constraints)
外碼取值要么為空,要么為其參照關系中的主碼取值。
ER模型到關系表的映射
1. 將常規實體映射為關系
對常規實體來說,每個常規屬性對應到關系表中的一列,而某單值且唯一的列則映射為主碼,標記下划線。
如下實體:
將映射為關系:
2. 將具有復合屬性的實體映射為關系
這類映射中,復合屬性的各子屬性會映射到的新的關系中,但是復合屬性名本身不會。
如下實體:
將映射為關系:
雖然關系中沒有出現符合屬性名了,但數據庫上層的前端應用可能會利用到復合屬性名。也就是ER圖在各個階段都有可能用到,不是說映射為關系后就沒啥事了。
3. 將具有唯一復合屬性的實體映射為關系
這類映射中,將會形成一個復合主碼,其成員為復合屬性的各子屬性。
如下實體:
將映射為關系:
4. 將具有可選屬性的實體映射為關系
這類映射中,需要將可選屬性對應的列標記一個(O)。
如下實體:
將映射為關系:
5. 一對多(1:M)聯系的映射
這類映射的規則為:在由1:M聯系中屬於M側的實體所映射得到的關系中設置一個外碼,這個外碼對應於由1側的實體映射得到的關系中的主碼。
如下ER模型:
將映射為關系:
注意,外碼命名不一定要和它對應的主碼一致,應根據實際情況決定。
6. 多對多(M:N)聯系映射
這類映射的規則為:除了具有多對多聯系的兩個實體之外,聯系本身也需要映射為關系。聯系對應的關系中將有兩個外碼,分別對應兩個實體的主碼,同時這兩個外碼構成新關系的主碼。
比如下面這個ER模型:
將映射為關系:
7. 一對一(1:1)聯系的映射
這類映射和1:M的很相似。原則上外鍵設在任何一個實體的關系中都OK,但如果一對一聯系中的基數約束是強制單個和可選單個這種類型,則最好將外鍵設置在可選多的一側。因為這樣可以保證關系中不會出現太多空值。
比如下面這個ER模型:
將映射為關系:
8. 將具有若干候選碼的實體映射為關系
這類映射中,主碼依然標記划線,而非主碼唯一屬性則標記(U)。
如下實體:
將映射為關系:
9. 將具有多值屬性的實體映射為關系
這類映射中,需要為多值屬性創建一個新的關系。新的關系中包含一個外碼,對應到主實體的主碼。同時屬性值和外碼構成新的關系的復合主碼。
如下實體:
將映射為關系:
10. 將具有派生屬性的實體映射為關系
派生屬性不需要做什么特別處理,那是前端的事情,哈哈。
11. 一對多(1:M)一元聯系的映射
這類映射的規則為:實體映射得到的關系中包含一個外碼,對應到關系自身的主碼。
如下ER模型:
將映射為關系:
需要注意的是,該映射中外鍵名和主鍵名是不同的,以區分它和主碼。事實上關系中也不允許出現名稱相同的兩列。
12. 多對多(M:N)一元聯系的映射
這類映射的規則為:除了實體本身需要映射為關系之外,多對多聯系需要映射為另一個關系。新的關系中將有兩個外碼,它們均對應到實體主碼。且這兩個外碼又組合為新關系的復合主碼。
如下ER模型:
將映射為關系:
這里同樣要注意外鍵名要避免和主鍵名重復。
13. 一對一(1:1)一元聯系的映射
和上面第11條講的一對多的一元聯系映射規則完全相同,此處不再舉例說明。
14. 將弱實體映射為關系
弱實體映射和常規一對多聯系映射一樣需要在弱實體(M側實體)中建立一個對應到屬主實體(1側實體)的外碼。然而區別是弱實體中的主碼是弱實體自身的部分碼+外碼構成的復合主碼,而后者的主碼僅是M側實體自己的主碼。
如下ER模型:
將映射為關系:
當然,如果聯系是一對一,則弱實體的主碼就是那個對應到其屬主實體的外碼而沒有部分碼了。
如下ER模型:
將映射為關系:
15. 將關聯實體映射為關系
關聯實體本身就是聯系,因此它的映射規則和聯系是一樣的。聯系的映射在前文已經完成講解,此處不再累述了。
16. 三元聯系的映射
這類映射和多對多聯系的映射比較相似。如下ER模型:
可映射為:
這里提示下,三元聯系的情況,聯系肯定是多對多對多的。因為如果這三元中有一個為一,那么三元聯系就應轉成兩個二元的一對多聯系。
概念模型 VS 邏輯模型
想必有不少人還不大清楚概念模型,邏輯模型,物理模型的區別。這里先來探討下概念模型和邏輯模型,有關物理模型的討論則將放到第四篇。
我們首先可以認為概念模型建模和ER建模,需求可視化表達的是一個意思。在這個環節中,數據開發人員繪制ER圖,並和項目各方人員協同需求,達成一致。由於這部分的工作涉及到的人員開發能力比較薄弱,甚至不懂開發,因此ER圖必須清晰明了,不能涉及到過多的技術細節。在ER圖繪制完畢之后,才開始將它映射為關系表。這個映射的過程,就叫做邏輯模型建模或者關系建模。
有人會說,ER圖不是可以直接映射到關系嗎,而且已經有了相應的映射工具了,為什么還要繪制ER圖多此一舉呢?針對這個問題前文已經回答了。ER圖是拿出去和別人談需求的,要求各方人員都能看得懂。而關系表設計到了過多實現細節,比如:要給多對多聯系/多值屬性等多建一張表,要設置外碼,各種復合主碼等。這些東西不應該在談需求的時候出現,它們應當對非開發人員透明。而且ER圖中每個屬性只會出現一次,減少了蘊含的信息量,是更好的交流和文檔化工具。
還有,ER模型所蘊含的信息,也沒有全部被邏輯模型包含。比如聯系的自定義基數約束,比如實體的復合屬性,派生屬性,用戶的自定義約束等等。因此ER模型在整個開發流程(如物理模型建模,甚至前端開發)中是都會用到的,不能認為ER模型轉換到邏輯模型后就可以扔一邊了。
小結
本文的邏輯關系表都是利用建模工具直接由ER圖生成的。這確實很方便,但那些系統自動增加的字段和表的命名則需要根據實際情況進行調整。
邏輯模型設計好后,就可以開始着手數據庫的物理實現了。數據庫的物理實現也被稱為物理模型建模,這個階段不但需要參照邏輯模型,還應當參照ER圖。