Table of Contents
第七章 數據庫設計和E-R模型
E-R數據模型提供了一個找出在數據庫中表示的實體以及實體之間如何關聯的方法。最終,數據庫設計將會表示爲一個關係數據庫設計和一個與之關聯的約束集合。
7.1 設計過程概覽
7.1.1 設計階段
- 數據庫設計的最初階段需要完整的刻畫出未來數據庫用戶的數據需求 ===> 用戶需求規格說明書
- 用戶需求規格說明書(specification of function requirement)中,用戶描述將在數據上進行的各類操作,包括:增刪改查
- 概念設計(conceptual-design)階段:設計者選擇數據模型,並採用所選數據模型的概念將這些需求轉換爲數據庫的概念模式。概念設計階段所產生的模式提供了一個對企業的詳細綜述。======> E-R 圖
- 通常使用E-R模型來表示概念設計。
- 概念模式定義了數據庫中表示的實體,屬性,實體之間的聯繫,以及實體和聯繫上的約束
- 完善的概念模式還指明企業的功能需求。在這個階段要確保所有數據需求都被滿足,還要檢查和去除設計的冗餘。
- 從抽象數據模型到數據庫實現的轉換過程在最後兩個設計階段中進行
- 邏輯設計階段(logical-design phase): 設計者將高層概念模式映射到將使用的數據庫系統的實現數據模型上。實現數據模型通常是關係數據模型,該階段通常包括將實體-聯繫模型定義的概念模式映射到關係模式
- 物理設計階段(physical-design phase):該階段指明數據庫的物理特徵,這些特徵包括:文件組織格式和索引結構的選擇。
7.1.2 設計選擇
數據庫設計的主要部分是:決定如何在設計中表示各種類型的“事物”。
實體Entity:指示所有可明確識別的個體,如:教師、學生、系、課程和開課記錄
聯繫Relationship:表示實體之間的關聯
設計數據庫模式時要避免的兩個主要缺陷:
- 冗餘:包含重複信息
- 冗餘導致維護困難,信息容易變得不一致
- 如:開課記錄關係中不僅包括課程id,還包括課程的名稱;課程關係中也包括了課程id和名稱。
- 不完整:不好的設計可能會使得某些信息無法建模
- 例如:只用開課記錄來維護課程信息,而不單獨創建課程關係,會導致無法展示未開課的課程。
另外,數據庫設計過程中還需要在很多好的設計中選擇一個。
7.2 實體-聯繫模型
實體-聯繫(Entity-Relationship) 數據模型的提出旨在方便數據庫設計,它是通過允許定義代表數據庫全局邏輯結構的企業模式實現的。
E-R模型採用了三個基本概念:
- 實體集
- 聯繫集
- 屬性
7.2.1 實體集
實體(Entity):是現實世界中可區別於所有其他對象的一個“事物”或“對象”。例如:大學中的每個人都是一個實體。
實體集(Entity Set):相同類型即具有相同性質(或屬性)的一個實體集合。例如:大學中所有的老師可以定義爲實體集instructor
外延(extension):實體集的外延指屬於實體集的實體的實際集合。例如:大學中實際老師的集合構成了實體集instructor的外延
屬性(attribute):實體通過一組屬性來表示。屬性是實體集中每個成員所擁有的的描述性性質。例如:instructor實體集可能具有屬性ID,name等
值(Value):每個實體的每個屬性都有一個值
數據庫包含一組實體集,每個實體集包括任意數量的相同類型的實體。
7.2.2 聯繫集
聯繫(relationship):指多個實體之間的相互關聯。例如:可以定義關聯教師Katz和學生Shankar的聯繫advisor,這一聯繫指明Katz是Shankar的導師。
聯繫集(relationship set): 相同類型的聯繫的集合。
參與(participate):實體集之間的關聯稱爲參與,例如:實體集E1,E2, ..., En參與了聯繫集R。
E-R模式中的一個聯繫實例(relationship instance)表示在所建模的現實世界企業中命名實體間的一個關聯。
實體在聯繫中扮演的功能稱爲實體的角色(role)。
同樣的實體集以不同的角色參與一個聯繫集多於一次,這類 聯繫集被稱作自環的(recursive)聯繫集。這類聯繫集需要現實指明實體的角色,即:他們是如何參與到聯繫中的。
- 例如:聯機集:課程的先修課程-顯示的指明每個實體扮演的角色,是課程,還是先修課程
聯繫集也可以具有描述性屬性(descriptive attribute)。
- 例如:實體集instructor合student之間的聯繫集advisor,可以具備date屬性,描述教師稱爲學生的導師的起始時間。
二元(binary)聯繫集:即聯繫集有兩個參與的實體集組成
度(degree):參與聯繫集的實體集的數目稱爲聯繫集的度。二元聯繫集的度是2,三元聯繫集的度是3。
7.2.3 屬性
域(domain)/值集(value set):每個屬性都有一個可取值的集合,稱爲該屬性的域,或者值集。
正規的說,實體集的屬性是將實體集映射到域的函數。一個實體集可以具有多個屬性。
E-R模型中的屬性可以按照如下的屬性類型來進行劃分:
- 簡單(simple)和複合(composite)屬性:
- 簡單屬性不能進行進一步劃分爲更小的屬性
- 複合屬性可以劃分爲更小的屬性,如:地址可以劃分爲國家,省,市等。
- 複合屬性是可以具有層次的,因爲其子屬性也可以進一步劃分。
- 單值(single-valued)和多值(multivalued)屬性
- 單值屬性要求實體集中的每個特定實體都只有一個單獨的值。如:一個學生只能由一個student_ID
- 一個實體的某個屬性可能具有多個值,這種屬性是多值屬性。如:一個教師可能有多個電話號碼phone-number,那麼phone_number就是一個多值屬性。
- 我們用{phone_number}表示多值屬性
- 我們可以對多值屬性設置數目的上、下界,如:要求單個老師的電話號碼限制在2個以內。
- 派生屬性(derived):這類屬性的值可以從別的相關屬性或實體派生出來。
- 例如,instructor中的年齡屬性age,可以從date_of_birth中推算出來。則date_of_birth是基屬性,age是派生屬性。
空值null:可以表示屬性的值未知或者不存在。
7.3 約束
7.3.1 映射基數
映射基數(mapping cardinality)或基數比率:表示一個實體通過一個聯繫集能關聯的實體的個數。
對於實體集A和B之間的二元聯繫集R來說,映射基數必然是以下情況之一:
- 一對一(one-to-one): A中一個實體至多與B中一個實體相關聯,反之亦然。
- 一對多(one-to-many):A中的一個實體可以與B中任意數目的實體關聯,而B中的實體至多與A中的一個實體關聯
- 多對一(many-to-one):A中的一個實體至多與B中的一個實體相關聯,而B中的實體可以與A中的任意數目的實體相關聯。
- 多對多(many-to-many): A中的實體可以與B中任意數目的實體關聯,B中的實體也可以與A中任意數目的實體相關聯
7.3.2 參與約束
如果實體集E中的每個實體都參與到聯繫集R的至少一個聯繫中,實體集E在聯繫集R中的參與稱爲全部的(total)。例如:圖7-5 a中的B
如果實體集E中只有部分實體參與到聯繫集R的至少一個聯繫中,實體集E在聯繫集R中的參與稱爲部分的(partial)。例如:圖7-5a中的A
7.3.3 碼
碼可以用來唯一的標識實體,同樣可用於唯一的標識聯繫。
一個實體的屬性的值必須可以唯一表示該實體,即:一個實體集沒有兩個實體在所有屬性上的取值都相同。2.3節介紹的關係的超碼、候選碼和主碼的概念同樣適用於實體集。
超碼(superkey):是一個或多個屬性的集合,這些屬性的組合可以唯一標識一個元組。超碼的任意超集也是超碼。
候選碼(candidate key):如果該超碼的任意真子集都不能成爲超碼,那麼該集合就是候選碼。
主碼(primary key):代表被數據庫設計者選中的,主要用來在一個關係中區分不同元組的候選碼。
- 主碼應該選擇那些值從不或者很少發生變化的屬性。
聯繫集的碼:
設R是一個涉及實體集E1,E2,..., En的聯繫集。設primary-key(Ei)代表構成時提及Ei的主碼的屬性。假設所有主碼的屬性名是不同的。聯繫集R 的主碼的構成依賴於同聯繫集R相關聯的屬性集合。
- 如果聯繫集R沒有屬性與之關聯,那麼屬性集合
primary-key(E1)∪primary-key(E2)∪...∪primary-key(En)
構成了集合R中的一個聯繫
- 如果聯繫集R中有屬性a1,a2,...,am與之關聯,那麼屬性集合
primary-key(E1)∪primary-key(E2)∪...∪primary-key(En)∪{a1,a2,...,am}
構成了集合R中的一個聯繫
以上兩種情況,屬性集合primary-key(E1)∪primary-key(E2)∪...∪primary-key(En)組成了聯繫集的一個超碼
如果實體集間主碼的屬性名稱有重複,那麼需要重命名以作區分。
聯繫集的主碼依賴於聯繫集的映射基數。
- 若由A和B組成的聯繫集是多對多的:則primary-key(A)∪primary-key(B)組成聯繫集的主碼
- 若由A和B組成的聯繫集是一對多的:則primary-key(B)組成聯繫集的主碼
- 若由A和B組成的聯繫集是一對一的:則primary-key(A)或primary-key(B)都可以作爲聯繫集的主碼
7.4 從實體集中刪除冗餘屬性
聯繫集可能會導致不同實體集中的屬性冗餘,此時需要將冗餘屬性從原始實體集中刪除。
例如:
- instructor(ID, name, dept_name, salary)
- department(dept_name, building, budget)
如果構建聯繫集inst_dept(ID, dept_name),那麼dept_name在instructor中就是冗餘的,我們需要將其刪除。
這是因爲一個instructor可以屬於多個系,所以我們需要構建聯繫集;如果一個教師只能屬於一個系,我們不需要構建聯繫集,繼續保持原有的結構即可。
7.5 實體-聯繫圖
7.5.1 基本結構
- 分成兩部分的矩形:代表實體集;本書中有陰影的部分包含實體集的名字;第二部分包含實體集中所有屬性的名字。
- 菱形:代表聯繫集
- 未分割的矩形:代表聯繫集的屬性。構成主碼的屬性以下劃線標註
- 線段:將實體集連接到聯繫集
- 虛線:將聯繫集屬性連接到聯繫集
- 雙線:顯示實體在聯繫集中的參與度
- 雙菱形:代表連接到弱實體集的標誌性聯繫集
7.5.2 映射基數
用不同箭頭可以表示一對一,一對多,多對一,和多對多
更復雜的表示方法表示映射基數
l..h表示:l是最小映射基數,h是最大映射基數。最小值1表示這個實體集在該聯繫集中全部參與。
例如:下圖表示了一個學生必須要有且僅有一個導師。student的映射基數爲1,instructor的映射基數爲0...*表示advisor表示教師可以擁有0或多個學生。
7.5.3 複雜的屬性
下圖說明了如何表達複雜屬性。
其中name,adress,street均爲複合屬性;
phone_number爲多值屬性;
age爲派生屬性
7.5.4 角色
我們通過在菱形和矩形之間的連線上進行標註來表示角色。
7.5.5 非二元的聯繫集
7.5.6 弱實體集
弱實體集(weak entity set):沒有足夠的屬性以形成主碼的實體集稱爲弱實體集
強實體集(strong entity set):有主碼的實體稱爲強實體集。
例如:
course(course_id, title, credits)
section(sec_id, semester, year, course_id)
在這種情況下,section中(sec_id, semester, year, course_id)作爲主碼,若沒有course_id, 則剩餘屬性不足以作爲主碼,但是course_id又關聯於course實體集。所以section是弱實體集,而course是強實體集。
弱實體集必須與另一個稱作標識(identifying)或屬主屬性(owner entity set)的實體集關聯纔能有意義。每個弱實體必須與一個標識實體關聯,即:弱實體集存在依賴(existence dependent)於標識實體集。
我們稱標識實體集擁有(own)它所標識的弱實體集。將弱實體集與標識實體集相聯的聯繫稱爲標識性聯繫(identifying relationship)。
標識性聯繫是從弱實體集到標識實體集多對一的,並且弱實體集在聯繫中的參與是全部的。標識性聯繫集不應該有任何描述性屬性,因爲這種屬性中的任意一個都可以與弱實體集相關聯。
分辨符(discriminator)+ 標識實體集的主碼==>弱實體集的主碼
例如:section的主碼由分辨符(sec_id, semester, year)和course_id組成。
注意:雖然我們可以讓sec_id是不重複的,但是section在概念上仍然依賴於section,通過使之成爲弱實體可以明確這種依賴關係。
當弱實體集屬性不多時,我們可以將一個弱實體集表示爲屬主實體集的一個多值複合屬性;當弱實體集屬性較多是,建模時將其表示爲弱實體集更恰當。
7.5.7 大學的E-R圖
7.6 轉換爲關係模式
可以將E-R數據庫模式轉換爲一個關係模式的集合。關係集合名 即爲 相應的實體集或聯繫集的名稱。
7.6.1 具有簡單屬性的強實體集的表示
設E是隻具有簡單描述屬性a1,a2,..., an的強實體集,則可以用具有n個不同屬性的模式E來表示這個實體。該模式的關係中的每個元組同實體集E的一個實體對應。
強實體集的主碼==> 生成的模式的主碼
例如:圖7-15中
classroom(building, room_number, capacity)
department(dept_name, building, budget)
course(course_id, title, credits)
instructor(ID, name, salary)
student(ID, name, tot_ cred)
7.6.2 具有複雜屬性的強實體集的表示
當一個強實體集具有複合屬性時,我們並不爲複合屬性自身創建一個單獨的屬性。
例如: instructor的name,由first_name, middle_name, last_name組成; instructor的address由 street, city, state和zip
_code組成,street又由street_number, street_name, apt_number組成。
instructor就可以設計爲:instructor(ID, first_name, middle_name, last_name, street_number, street_name, apt_number, city, state, zip_code, date_of_birth);
對於一個多值屬性M,構建關係模式R,該模式包含一個對應於M的屬性A,已經對應於M所在的實體集或聯繫集的主碼的屬性。
例如 :instructor中每個實體可以具有多個phone_number,那麼可以構建instructor_phone(ID, phone_number)存儲多值屬性
如果一個實體集只有兩個屬性的情況下——一個主碼B和一個多值屬性M——那麼該實體機的關係模式中只包含一個屬性,即:主碼B。此時,可以刪掉這個關係,同時保留具有屬性B和對應M的屬性A的關係模式。
例如:time_slot關係中time_slot_id是主碼,且它只有一個多值屬性。那麼,可以設計爲:time_slot(time_slot_id, day, start_time, end_time)
7.6.3 弱實體集的表示
設A是具有屬性a1, a2,..., am的弱實體集,設B是A所依賴的強實體集,設B的主碼包括屬性b1, b2,..., bn。
我們用名爲A的關係模式表示弱實體集A,該模式的每個屬性對應一下集合中的一個成員:{a1, a2,..., am}∪{b1,b2,...,bn}
關係模式A的主碼爲:弱實體集的分辨碼+A所依賴的參照關係B的主碼
例如:弱實體集section(sec_id, semester, year) ,sec_id, semester和year是其分辨碼;它參照course中的course_id,
那麼可以用下面的關係模式進行表示section(sec_id, semester, year, course_id)
7.6.4 聯繫集的表示
設R是聯繫集,a1, a2,..., am表示所有參與R的實體集的主碼的並集構成的屬性集合。設R的描述性屬性(如有)爲b1,b2,..,bn。
==> 可以用名爲R的關係模式來表示該聯繫集,{a1,a2,...,am}∪{b1, b2,...,bn}
如何爲二元聯繫集選擇主碼?
- 多對多:參與關係的所有實體集的主碼屬性的並集作爲主碼
- 一對一:任何一個實體集的主碼都可以作爲主碼
- 一對多/多對一:聯繫集中“多”的一方的主碼作爲聯繫集的主碼
如何爲n元聯繫集選擇主碼?
- 對於邊上沒有箭頭的n元聯繫集,所有參與實體集的主碼屬性的並集作爲主碼
- 對於邊上有一個箭頭的n元聯繫集,不在“箭頭”側的實體集的主碼屬性爲模式的主碼。(注意:一個聯繫集外只允許有一個箭頭)
我們還在關係模式R上建立外碼約束,R中來自Ei的主碼屬性的那些屬性參照表示關係模式Ei的主碼。
例如:advisor爲例,它參照instructor和student;
- 由於該聯繫集沒有屬性,它只具有s_id和i_id,分別是student和instructor的主碼。
- 由於student和instructor是多對一的,所以advisor的主碼爲s_id
- 另外,需要爲s_id和i_id建立外碼約束
7.6.4.1 模式的冗餘
連接弱實體集和相應強實體集的聯繫集比較特殊:這樣的聯繫集是多對一的,且沒有描述性屬性,並且弱實體集的主碼包括強實體集的主碼。
==》 一般情況下,這類聯繫集的模式是冗餘的,在基於E-R圖的關係數據庫設計時不必給出。
例如:section弱實體集,course強實體集,以及聯繫它們的sec_course聯繫集。==> sec_course模式是冗餘的。
7.6.4.2 模式的合併
考慮從實體集A到實體集B的一個多對一的聯繫集AB。用前面的關係-模式構建算法===》得到三個模式A,B,AB。
進一步假設A在該聯繫集中的參與是全部的,即:A中的每個實體a都必須參與到聯繫集AB中。
那麼==》可以將A和AB模式合併成 單個包含兩個模式所有屬性的並集的 模式。其主碼是其模式中融入了聯繫集模式的那個實體集的主碼。
例如:圖7-15
- inst_dept: inst_dept可以和instructor合併==> instructor(ID, name, dept_name, salary)
- stud_dept:stud_dept可以和student合併===> student(ID, name, dept_name, cred)
- course_dept: course_dept可以和course合併===> course(course_id, title, dept_name, credits)
- sec_class: sec_class可以和section合併===> section(course_id, sec_id, semester, year, building, room_number)
- sec_time_slot: sec_time_slot可以和上一步產生的section合併===> section(course_id, sec_id, semester, year, building, room_number, time_slot_id)
在一對一聯繫的情況下,聯繫集的關係模式可以跟參與聯繫的任何一個實體集的模式合併。
7.7 實體-聯繫設計問題
7.7.1 用實體集還是用屬性
例如:instructor的phone_number,我們既可以通過屬性表示phone_number,也可以通過實體集表示phone_number
這兩種定義的差別是什麼呢?
- 將其作爲屬性時,表示一個教師只能由一個電話號碼
- 將其看成一個實體時,允許每個教師有多個電話號碼,還允許描述電話的額外信息,如:location等。
至於如何選擇,則取決於具體的應用設計。
但是,與之相對的是,將name視作一個實體是不合適的,從概念上講不具有說服力。
具體是作爲屬性還是作爲實體,需要具體問題具體分析,和應用場景有很大的關係。
常見的錯誤:
- 將一個實體集的主碼作爲另一個實體集的屬性。例如: 將student_id作爲instructor的屬性,是不合適的。用advisor維護關係則更直觀容易理解。
- 將相關實體集的主碼屬性作爲聯繫集的屬性。例如:student_id和instructor_id作爲advisor的屬性,這是不合適的,因爲聯繫集中已經隱含的包含了這兩個主碼屬性。
7.7.2 用實體集還是用聯繫集
將一個對象表現爲實體集還是聯繫集有時並不那麼顯而易見。
例如:
- 可以用takes 聯繫集可以被用來表示學生選擇課程(的某一次開課)建模。
- 也可以用registration的實體集表示課程-註冊記錄,再用兩個聯繫集section_reg和student_reg分別表示registration與course和student的關聯。
但是具體哪種方式合適,應該取決於實際應用。如果註冊辦公室通過課程-註冊記錄與其他信息相關聯,那麼最好讓其成爲一個實體。否則,takes會更緊湊,
在決定用實體集還是聯繫集時可以用的一個準則是:
- 當描述發生在實體間的行爲時採用聯繫集。
7.7.3 二元還是n元聯繫集
數據庫中的聯繫通常是二元的,非二元的關係實際上也可以通過多個二元關係來很好的表示。
例如:可以創建一個三元關係parent,來表示一個孩子的父母;也可以使用兩個二元關係mother和father表示孩子的父母。
事實上,一個非二元的(n,n>2)聯繫集總可以用一組不同的二元聯繫集來替代。
例如:一個抽象的三元聯繫集R,它將實體集A,B,C聯繫起來。用實體集E替代聯繫集R,並創建三個聯繫集RA,RB,RC,如下圖:
在概念可以限制E-R模型只包含二元聯繫集,但是這種限制是有缺點的:
- 對於未表示聯繫集而創建的實體集,我們可能不得不爲其創建一個標識屬性。該標識屬性和額外所需的那些聯繫集增加了設計的複雜程度以及對總的存儲空間的需求。
- n元聯繫集可以更清晰的表示幾個實體集參與單個聯繫集
- 有可能無法將三元聯繫集的約束變爲二元聯繫集上的約束。例如:一個約束表明R是從A,B到C多對一的;即:來自A和B上的每一對實體最多與一個實體C相關聯。這種約束就不能用聯繫集RA,RB和RC的基數約束表示
7.7.4 聯繫屬性的佈局
一個聯繫的映射基數比率會影響聯繫屬性的佈局。因此,一對一或一對多聯繫集的屬性可以放到一個參與該聯繫的實體集中,而不是放到聯繫集中。
7.8 擴展的E-R特性
擴展的E-R特性:特化、概化、高層和低層實體集、屬性繼承和聚集
7.8.1 特化
實體集可能包含一些子集,子集中的實體在某些方面區別於實體集中的其它實體。例如:person可分爲employee和student兩類;學生student可分爲undergraduate和graduate。
特化(specialization):在實體集內部進行分組的過程稱爲特化。
一個實體集可以根據多個可區分的特徵進行特化。
特化可分爲:
- 重疊特化(overlapping specialization):一個實體可以屬於多個特化實體集,使用不相交的空心箭頭表示。例如:一個 person可以既是employee也是student
- 不相交特化(disjoint specialization):一個實體只能至多屬於一個特化實體集,使用相交的一個空心箭頭表示。例如:一個student只能是graduate或者是undergraduate中的一種。
7.8.2 概化
特化 - 自頂向下的(top-down)
概化(generalization) - 自底向上的(bottom-up),是一個高層實體集與一個或多個低層實體集間的包含關係。
高層和低層的實體集可稱作超類(superclass)和子類(subclass)。
概化和特化的區別主要在於它們的出發點和總體目標:
- 特化是從單一的實體集出發,通過創建不同的低層實體集來強調同一實體集中不同實體之間的差異。低層實體集可以有不適用於高層實體集中所有實體的屬性,也可以參與到不適用於高層實體集中所有實體的聯繫中。設計者採用特化的原因正是爲了表達這些與衆不同的特徵
- 概化則是基於這樣的一種認識:一定數量的實體集共享一些共同的特徵。概化是在這些共性的基礎上將它們綜合成一個高層實體集。概化用於強調低層實體集之間的相似性並隱藏它們的差異。
7.8.3 屬性繼承
屬性繼承(attribute inheritance):由特化和概化所產生的高層和低層實體的一個重要特徵是屬性繼承。高層實體集的屬性被低層實體集繼承。
例如:employee繼承了person的所有屬性
低層實體集同時還繼承地參與其高層實體/超類所參與的聯繫集。
例如:person和department有person_dept聯繫集。那麼person的子類實體集student,employee,instructor和secretary都與department隱式的參與到person_dept聯繫中。
===》規則:
- 高層實體集所關聯的屬性和聯繫適用於它的所有低層實體集
- 低層實體集特有的性質僅適用於特定的低層實體集
圖7-21是實體集的層次結構(hierarchy)。在層次結構中,給定的實體集作爲低層實體集只參與到一個ISA聯繫中,即:具有單繼承(single inheritance)。
如果一個實體集作爲低層實體集參與到多個ISA聯繫中,則該實體具有多繼承(multiple inheritance),且產生的結構成爲格(lattice)。
7.8.4 概化上的約束
數據庫設計者需要在特定概化上設置某些約束,包括:
- 判定哪些實體能夠成爲給定低層實體集的成員:
- 條件定義的(condition-defined):在條件定義的低層實體集中,成員資格的確定基於實體是否滿足一個顯示的條件/謂詞
- 例如:滿足student_type="研究生",則屬於graduate;student_type=“本科生”,則屬於undergraduate
- 用戶定義的(user-defined): 用戶定義的低層實體集不是由成員資格條件定義的,而是由數據庫用戶將實體指派給某個實體類。
- 例如:大學僱員3個月試用期通過後被認爲分派到到4個小組中的一個。
- 條件定義的(condition-defined):在條件定義的低層實體集中,成員資格的確定基於實體是否滿足一個顯示的條件/謂詞
- 一個實體是否可以屬於多個低層實體集
- 不相交的(disjoint):不相交約束要求一個實體至多屬於一個低層實體集。
- 例如:student實體在student-type上只能滿足一個條件,要麼是本科生要麼是研究生
- 重疊(overlapping):同一個實體可以屬於同一個概化中的多個低層實體集
- 例如:一個employee員工可以被分配到多個工作組中
- 不相交的(disjoint):不相交約束要求一個實體至多屬於一個低層實體集。
- 概化的完全性約束(completeness constraint):定義高層實體集中的一個實體是否必須至少屬於該概化/特化的一個低層實體集。
- 全部概化(total generalization)/ 全部特化(total specialization):每個高層實體必須屬於一個低層實體集
- 部分概化(partial generalization)/部分特化(partial specialization):允許一些高層實體不屬於任何低層實體集。
部分概化是默認的。但是可以在E-R圖中表示全部概化:
在圖中加上關鍵詞total,並畫一條從關鍵詞到相應的空心箭頭(表示不相交概化)的虛線;
或者畫一條到空心箭頭集合(表示重疊概化)的虛線
7.8.5 聚集
如圖7-22:
- eval_for:表示對student, project,instructor和evaluation之間的關係。
- proj_guide:表示student,project和instructor之間的聯繫。
按照這種方法是有冗餘信息存在的,因爲在eval_for中的每個student,project和instructor肯定也在proj_guide中。
如果evaluation是一個值而不是一個實體,我們可以將其作爲proj_guide一個多值屬性;
然而,如果evaluation和其他實體關聯時,則不能採用這樣方法。
解決上述問題===>聚集(aggregation)
聚集:是一種抽象,通過這種抽象,聯繫作爲高層實體。
例如:我們將proj_guide聯繫集看成一個名爲proj_guide的高級實體集,即:一個聚集。如下圖所示,我們就可以在proj_guide和evaluation之間構建一個二元關係,來對這種情況進行表達。
7.8.6 轉化爲關係模式
7.8.6.1 概化的表示
- 爲高層實體集創建一個模式,爲低層實體集創建一個模式。例如:
person(ID, name, street, city)
employee(ID, salary)
student(ID, tot_cred)
此時,高層實體集的主碼也是低層實體集的主碼屬性。低層實體集的主碼也具有外碼約束,參照高層實體集的關係的主碼。
- 如果概化是不相交且完全的——如果不存在同時屬於兩個同級的低層實體集的實體,且如果高層實體集的任何實體也都是某個低層實體集的成員,則可以採用另一種方式:
- 不爲高層實體集創建任何模式,只爲低層實體集創建一個模式。例如:
employee(ID, name, street, city, salary)
student(ID, name, street, city, tot_cred)
- 缺點:
- 定義外碼約束
- 例如: 如果person有一個聯繫集R,那麼在這種情況下R需要參照兩個關係,即:employee和student都有外碼約束。但是如果是使用第一種方法,則可以只與person做外碼約束。
- 如果這種方法用於重疊概化,某些值就會被存儲多次。
- 如果概化是不相交的但不是全部的,那麼就需要一個額外的模式person去存儲那些既不屬於employee也不屬於student的實體,這樣就是第一種方法一樣。
- 定義外碼約束
7.8.6.2 聚集的表示
聚集的表示是很直接的。例如7-23中,eval_for的模式包含:對應實體集evaluation的主碼+聯繫集proj_guide主碼+描述性屬性。
聚集的主碼是定義該聚集的聯繫集的主碼。不需要使用單獨的關係來表示聚集;而使用從定義該聚集的聯繫創建出來的關係就可以了。
7.9 數據建模的其它表示法
E-R圖和UML圖均可應用於對數據建模進行圖形化表示。
E-R圖還沒有一個統一的規範。
7.9.1 E-R圖的其它表示法
7-24列出來本書中E-R圖用過的符號。7-25列出來一部分廣泛可用的E-R圖符號
7.9.2 統一建模語言UML
統一建模語言(Unified Modeling Language, UML),是由對象管理組織(Object management group, OMG)支持開發的一個標準,它是爲了建立軟件系統不同部分的規範定義而提出的。UML的組成部分:
- 類圖class diagram: 類圖和E-R圖類似。
- 用例圖use case diagram:說明了用戶和系統之間的交互,特別是用戶所執行的任務中的每一步操作。
- 活動圖Activity diagram:說明了系統不同部分之間的任務流
- 實現圖implementation diagram:在軟件結構圖和硬件構建層說明了系統的各組成部分以及它們之間的聯繫
本節主要介紹類圖。
- +,-,#分別表示共有、私有和受保護的訪問。
- UML中,聯繫集稱爲關聯(association)
下圖列出來UML類圖和E-R圖表示法的對比和等價表示。
值得注意的是基數約束那個子圖,表示的是E2到E1是多對一的!!!
E1邊上的約束0..*表示,每個E1實體可以參與多個關係;即:一個E1可以對應多個E2。
E2邊上的約束0..1表示,每個E2實體至多可以參與一個關係,即:一個E2可以對應一個E1。
7.10 數據庫設計的其他方面
7.10.1 數據約束和關係數據庫設計
SQL可以表達多種數據約束,包括:主碼約束、外碼約束、check約束、斷言和觸發器。約束的最重要的一個目的是爲了自動保持數據的一致性。
數據約束在確定數據的物理結構時也同樣有用:可以將彼此緊密關聯的數據存儲在磁盤上鄰近的區域,以便在磁盤訪問時提高效率。當索引建立在主碼上時,索引結構工作的很好。
每次數據庫更新時,執行約束會在性能上帶來潛在的高代價。
7.10.2 使用需求:查詢、性能
數據庫系統的性能非常重要,性能不僅和計算能力的有效利用以及所使用的存儲硬件有關,而且受到與系統交互的人的效率、以及依賴數據庫數據的處理效率的影響。
度量效率的兩個方法:
- 吞吐量(throughput)——每單位時間能夠處理的查詢或更新(通常指事務)的平均數量
- 響應時間(response time)——單個事務從開始到結束所需的平均時間或者最長時間。
以批量的方式處理大量事務的系統更關注高吞吐量。
與人交互或者時間苛責的系統則更關注響應時間。
查詢和性能會影響數據庫的設計。例如:索引能夠加快查詢,但同時也會影響更新的速度。
7.10.3 授權需求
授權索引同樣會影響數據庫的設計。不同用戶對不同視圖具有不同的訪問權限,如何進行數據劃分和存儲非常重要。
7.10.4 數據流、工作流
工作流:表示一個流程中的數據和任務的組合。
數據庫不僅可以存儲工作流操作的數據,還可以存儲工作流自身的數據,包括:工作流的任務以及它們在用戶之間移動的路徑。
在數據庫設計時,不僅需要理解數據的語義,還要理解業務流程。
7.10.5 數據庫設計的其它問題
一個好的數據庫設計能夠考慮到將來的需求和變化,儘量避免或最小化由預計或有可能發生的改變而導致的改動。
區分預期持久的基本約束和預期要改變的約束非常重要。
如何協調多個數據庫之間的交互也需要考慮。
總結
- 數據庫設計主要涉及到數據庫模式的設計。E-R數據模型是一個廣泛用於數據庫設計的數據模型。它提供了一個方便的圖形化表示方法以查看數據、聯繫和約束
- E-R模型主要用於數據庫設計過程。它的發展是爲了幫助數據庫設計,這是通過允許定義企業模式(Enterprise schema)實現的。這種企業模式代表數據庫的全局邏輯結構,該邏輯結構可以用E-R圖表示。
- 實體(entity)是在現實世界中存在並區別於其他對象的對象。我們通過把每個實體同描述該實體的一組屬性相關聯來表示區別。
- 聯繫(relationship)是多個實體的關聯。
- 相同類型的聯繫的集合稱爲聯繫集(relationship set);相同類型的實體的集合稱爲實體集(entity set)。
- 屬於超碼(superkey),候選碼(candidate key)和主碼(primary key)不僅適用於關係模式,也適用於實體和聯繫集。在確定一個聯繫集的主碼時要小心,因爲它由來自一個或多個相關的實體集的主碼組成
- 映射的基數(mapping cardinality):表示通過聯繫集可以和另一個實體相關聯的實體的個數。
- 不具有足夠屬性構成主碼的實體稱爲弱實體集(weak entity set)。具有主碼的實體集稱爲強實體集(strong entity set)。
- E-R圖的各種性質爲數據庫設計者提供了大量的選擇,使得設計人員可以最好的表示被建模的企業。在某些情況中,概念和對象可以用實體、聯繫和屬性來表示。企業總體結構的某方面可以用弱實體集、概化、特化或聚集很好的描述。設計者通常需要在簡單的,緊湊的模型與更精確但也更復雜的模型之間進行權衡。
- 用E-R圖定義的數據庫設計可以用關係模式的集合來表示。數據庫的每個實體集合聯繫集都有唯一的關係模式與之對應,其名稱即爲相應的實體集或聯繫集的名稱。這是從E-R圖轉換爲關係數據庫設計的基礎。
- 特化(specialization)和概化(generalization)定義了一個高層實體集合一個或多個低層實體集之間的包含關係。特化是取出高層實體集的一個子集來形成一個低層實體集;概化是用兩個或多個不相交的低層實體集的並集形成一個高層實體集。高層實體集的屬性被低層實體集繼承。
- 聚集(aggregation)是一種抽象,其中聯繫集被看做高層實體集,並且可以參與聯繫
- UML是一種常用的建模語言,UML類圖廣泛的用於對類建模以及一般的數據建模