回顧數據庫設計三個階段:
概念數據庫設計:生成數據庫的概念表示,包括重要的實體、聯系以及屬性的定義。
邏輯數據庫設計:將概念表示轉換成數據庫額的邏輯結構,包括關系的設計。
物理數據庫設計:如何在目標數據庫管理系統(DBMS)中物理的實現邏輯結構(作為基礎關系)。
1. 數據庫設計方法學簡介
1.1 什么是設計方法學
設計方法學:一種結構化的方法,它用過程、技術、工具以及文檔等輔助手段來支持和簡化設計過程。
設計方法學的每個階段都是由若干步驟組成的,這些步驟指導設計者在工程的各個階段采用相應的合適的技術。設計方法學同樣幫助設計者對數據庫系統開發項目進行計劃、管理、控制和評估。并且,設計方法學是結構化的方法,因為設計方法學用標準化和組織化的方式對數據庫系統的一系列需求進行分析和建模。
1.2 概念、邏輯和物理數據庫設計
在數據庫設計方法學中,設計過程被分為三個主要階段:概念數據庫設計,邏輯數據庫設計,物理數據庫設計。
概念數據庫設計:在不考慮任何物理因素的情況下構建企事業單位數據模型的過程。
概念數據庫設計從創建企事業單位的概念數據模型開始,概念數據模型完全獨立于諸如 DBMS、應用程序、編程語言、硬件平臺、性能問題或其他物理因素等實現細節。
邏輯數據庫設計:在不考慮具體 DBMS 和其他物理因素的情況下基于特定的數據模型構建企事業單位的數據模型的過程。
邏輯數據庫設計階段將概念模型映射為邏輯模型,該邏輯模型受到目標數據庫數據模型(如關系模型)的影響。邏輯數據模型是物理設計階段的基礎,為物理數據庫的設計者進行全面考慮和權衡提供依據,這對涉及高校的數據庫十分重要。
物理數據庫設計:在二級存儲器上實現數據庫的過程,包括定義基礎關系、文件組織、用于實現高效數據訪問的索引,以及相關的完整性約束和安全機制。
在物理數據庫設計階段,設計者可以自行決定實現數據庫的方式。物理設計因 DBMS 而異。在物理設計和邏輯設計之劍存在著反饋過程,因為在物理設計過程中為提高性能所采取的措施可能會影響邏輯數據模型。
1.3 成功設計數據庫的關鍵因素
通常,下面幾點對數據庫設計的成功與否至關重要:
- 盡可能多的和用戶交流。
- 在數據建模的整個過程中遵循結構化的方法學。
- 使用數據驅動方法。
- 在數據模型中綜合考慮結構性和完整性。
- 數據建模方法學應該結合概念化、規范化和事務驗證技術。
- 盡可能多的用圖表來描述數據模型。
- 用數據庫設計語言(Database Design Language,DBDL)來描述難以用圖表表達的數據的語義。
- 建立數據字典對數據模型圖和 DBDL 進行補充說明。
- 自覺地迭代。
2. 數據庫設計方法學概述
數據庫設計方法學包括以下步驟。
概念數據庫設計
- 步驟 1 建立概念數據模型
- 步驟 1.1 標識實體類型
- 步驟 1.2 標識聯系類型
- 步驟 1.3 表示屬性并將屬性與實體或聯系類型相關聯
- 步驟 1.4 確定屬性域
- 步驟 1.5 確定候選關鍵字、主關鍵字和可替換關鍵字屬性
- 步驟 1.6 考慮使用增強的建模概念(可選步驟)
- 步驟 1.7 檢查模型的冗余
- 步驟 1.8 針對用戶事務驗證概念模型
- 步驟 1.9 與用戶一起復查概念數據模型
關系模型的邏輯數據庫設計
- 步驟 2 建立邏輯數據模型
- 步驟 2.1 從邏輯數據模型中導出關系
- 步驟 2.2 使用桂芳化方法驗證關系
- 步驟 2.3 針對用戶事務驗證關系
- 步驟 2.4 檢查完整性約束
- 步驟 2.5 與用戶一起復查邏輯數據模型
- 步驟 2.6 將邏輯數據模型合并為全局模型(可選步驟)
- 步驟 2.7 檢查模型對未來可拓展性的支持
關系數據庫的物理數據庫設計
-
步驟 3 轉換邏輯數據模型以適應目標 DBMS
- 步驟 3.1 設計基礎關系
- 步驟 3.2 設計導出數據的表示方法
- 步驟 3.3 設計一般性約束
-
步驟 4 設計文件組織方法和索引
- 步驟 4.1 分析事務
- 步驟 4.2 選擇文件組織方法
- 步驟 4.3 選擇索引
- 步驟 4.4 估計所需的磁盤空間
步驟 5 設計用戶視圖
步驟 6 設計安全機制
步驟 7 考慮引入可控冗余
步驟 8 監控系統和系統調優
從相對簡單的數據庫系統到高度復雜的數據庫系統,都可以使用上述方法學進行數據庫系統的設計。在數據庫系統開發的生命周期中,數據庫設計被分為三個階段,分別是概念設計、邏輯設計和物理設計。因此,方法學也包括三個相應的階段:步驟 1 是概念數據庫設計,步驟 2 是邏輯數據庫設計,步驟 3 ~ 8 是物理數據庫設計。根據要建立的數據庫系統復雜程度不同,有些步驟可以省略。例如,對于不管是單用戶視圖的數據庫系統,還是用集中式方法處理多用戶視圖的數據庫系統,方法學中的步驟 2.6 都顯然是多余的。因為我們只需要在步驟 1 中創建一個單一的概念數據模型,或者在步驟 2 中創建一個單一的邏輯數據模型就可以了。如果數據庫設計人員在設計數據庫系統時使用了視圖集成的方法處理多個用戶視圖,就需要反復應用步驟 1 和步驟 2,直到完成了所有模型的創建,然后再步驟 2.6 再將這些模型合并。
前面我們使用的術語 “局部概念數據模型” 和 “局部邏輯數據模型” 是指對數據庫系統的一個或者多個(不是全部)用戶視圖建模,術語 “全局邏輯數據模型” 則指對數據庫系統的所有用戶視圖建模。在方法學中,除了可選步驟 2.6 外,適用的都是一般性的術語 “概念數據模型” 和 “邏輯數據模型”,在步驟 2.6 中因為要描述的任務是將各個局部邏輯數據模型合并為全局邏輯數據模型,所以使用了術語。
設計方法學中一個很重要的方面是:不斷地對生成的模型進行驗證,以保證其始終能夠準確地反映被建模的那部分企事業單位的需求。在數據庫設計方法學,可以使用多種方法對數據模型進行驗證,例如規范化、確保對關鍵事務的支持、要求盡可能多的與用戶一起驗證數據模型。
步驟 2 所建立的邏輯模型是步驟 3 到步驟 8 進行物理數據庫設計的基礎。同樣,根據數據庫系統的復雜性以及目標 DBMS 的功能,物理數據庫設計的某些步驟也可以省略。例如,對于基于 PC 的 DBMS,步驟 4.2 就可以省略。
數據庫設計是一個反復迭代的過程,其不斷求精的過程幾乎沒有止境。盡管方法學的步驟是一個程序式的過程,但必須強調的是這并不意味著時記得設計過程就是按照這些步驟進行的。從某一個步驟里獲得的信息有可能改變前一個步驟的結果,同樣的,前一個步驟的修改有可能影響后面的步驟。所以,方法學就是一個框架,他引導設計者有效的進行數據庫設計。
我們使用 DreamHome 案例研究來說明數據庫的設計方法。DreamHome 數據庫包含多個用戶視圖(Director、Manager、Supervisor、Assistant 和 Client),并使用視圖集成和集中的方法來處理它們。應用集中的方法生成了兩類視圖:StaffClient 用戶視圖和 Branch 用戶視圖。這兩類視圖分別包括:
- StaffClient 用戶視圖 —— 包括了主管(Supervisor)、助理(Assistant)和客戶(Client)的用戶視圖。
- Branch 用戶視圖 —— 包含負責人(Director)和經理(Manager)的用戶視圖。
3. 概念數據庫設計方法學
步驟 1 建立概念數據模型
目標——創建一個滿足企事業單位數據需求的概念數據模型。
概念數據庫設計的第一步是建立一個(或多個)滿足企事業單位數據需求的概念數據模型。一個概念數據模型包括:
- 實體類型
- 聯系類型
- 屬性和屬性域
- 主關鍵字和可替換關鍵字
- 完整性約束
概念數據模型由 ER 圖、數據字典等文檔支持,這些文檔是在模型開發過程中逐步生成的。在后面的每個步驟中我們都將說明該步驟生成的支持文檔的類型。步驟 1 的任務是:
- 步驟 1.1 標識實體類型
- 步驟 1.2 標識聯系類型
- 步驟 1.3 表示屬性并將屬性與實體或聯系類型相關聯
- 步驟 1.4 確定屬性域
- 步驟 1.5 確定候選關鍵字、主關鍵字和可替換關鍵字屬性
- 步驟 1.6 考慮使用增強的建模概念(可選步驟)
- 步驟 1.7 檢查模型的冗余
- 步驟 1.8 針對用戶事務驗證概念模型
- 步驟 1.9 與用戶一起復查概念數據模型
步驟 1.1 標識實體類型
目標——標識所需的實體類型
創建概念數據模型的第一步是定義用戶關心的主要對象。這些對象就是模型的實體類型。確定實體的一種方法是審查用戶需求規格說明書。我們可以標出需求規格說明書中的名詞和名詞短語(如員工編號、員工姓名、房產所有者編號、房產所有者地址、租金、房間數等)。當然,我們要找出主要的對象,如人、地址或者是感興趣的概念,排除那些僅僅用來描述對象性質的名詞。比如,我們可以將員工編號和員工姓名組成一個名為 Staff 的對象或者實體,將房產編號、房產地址、租金和房間數組成一個名為 PropertyForRent 的實體。
確定實體的另外一種方法就是查找那些客觀存在的對象。比如說 Staff 是一個實體,因為不管我們知不知道他們的名字、職務以及出生日期,員工都會客觀存在。可能的話,用戶應該協助完成這個任務。
由于用戶的需求規格說明書的表達方式各不相同,所以確定實體有時會比較困難。用戶經常采用例子和類比。比如用戶通常直接提到某人的名字,,而不用我們所需要的一般意義上的 “員工” 這個名詞。有時,用戶使用工作角色之類的名詞,特別是經常使用某個人所屬的單位名稱。這些角色可能是工作頭銜或職務,如負責人、經理、主管或助理等。
用戶經?;煊猛x詞或歧義詞,從而使事情變得更加復雜。意義相同的兩個詞叫同義詞,例如,“branch” 和 “office”。歧義詞是指在不同的上下文中有不同含義的詞。例如,單詞 “program” 有幾種不同的意思,如一種學習的課程、一系列事件、一個工作計劃或一段電視節目。
某個對象是否就是實體、聯系或者屬性并不顯而易見。例如,婚姻應該歸為哪一類?事實上,根據實際需求,它既可以屬于三者眾的任一類型也可同時屬于三種類型。設計是主觀的,不同的設計者可能有不同的設計,但是這些設計都應該同等有效,并且在解釋上也應該是等同的。因此在某種程度上,這個過程依賴于設計者的判斷力和經驗。數據庫設計者必須對現實世界做出一定的取舍,并對所觀察的企事業單位內部的情況進行分類。因此,根據所給的需求規格說明書,不一定總會推導出唯一的實體類型集。但設計過程的不斷迭代至少會選出滿足系統需求的實體。對于 DreamHome 的 StaffClient 用戶視圖,我們標識出如下實體:
- Staff
- PropertyForRent
- PrivateOwner
- BusinessOwner
- Client
- Preference
- Lease
用文檔記錄實體類型
標識出實體類型后,應為其指定有意義并且很容易被用戶理解的名字,并且將這些尸體的名字及描述記錄在數據字典中。如果可能,記錄每個實體期望出現的次數。如果一個實體有多個名字,則把他們定義為 同義詞 或 別名,并記錄到數據字典中去。下圖顯示了數據字典的一部分,記錄了 DreamHome 中 StaffClient 用戶視圖的實體。
步驟 1.2 標識聯系類型
目標——標識實體類型之間的重要聯系
標識實體后,下一步就是表示所有存在與這些實體間的聯系。標識實體的一種辦法就是找出用戶需求規格說明書中出現的名詞。同樣,我們可以用需求規格說明書中的文法來識別聯系。通常,聯系體現在動詞或動詞詞組上面。例如:
- Staff Manages PropertyForRent(員工管理房產)
- PrivateOwnerr Owns PropertyForRent(業主擁有房產)
- PropertyForRent AssociatedWith Lease (房產關聯著租約)
需求規格說明書之所以記錄這些聯系,是因為它們對企事業單位很重要,因此在模型中應該包含他們。我們只對實體之間需要的聯系感興趣。
上例中,我們標識出了 Staff Manages PropertyForRent 和 PrivateOwner Owns PropertyForRent 兩種聯系。當然,也可以考慮 Staff 和 PrivateOwner 之間的聯系(例如 Staff Assists PrivateOwner(員工幫助業主))。盡管它是一種可能的聯系,但從需求規格說明書來看,建模時并不需要它。
大多數情況下,聯系是二元的,即聯系僅存在于兩個實體類型之間。但我們也要注意多個實體類型之間的復雜聯系以及單個實體類型的遞歸聯系。
設計者必須仔細分析,確保識別出用戶需求規格說明書中顯式或隱式說明的所有聯系。原則上說,應該檢查每一對實體類型,找出所有潛在的聯系。但是,這對于一個包含了幾百個實體類型的大系統來說過于復雜。另一方面,不做這樣的檢查又不太明智,這通常是分析員和設計院的責任。不過,當我們針對要支持的事務驗證模型時也應該很容易發現那些遺漏的聯系。
使用實體-聯系(ER)圖
用可視化的方式描述復雜系統通常要比使用冗長的文本描述容易得多。使用 ER 圖來描述實體和它們之間的聯系要更簡單一些。在數據庫設計的整個階段,強烈建議在需要的時候盡量使用 ER 圖來標識企事業單位建模的各個部分。本書使用最新的面向對象表示方法——統一建模語言(UML),不過其他表示方法也可以完成類似的功能。
確定聯系類型的多重性約束
聯系確定以后,下一步就是要確定每一種聯系的多重性。如果已經知道聯系的多重性的取值,或者知道取值的上限和下限,那么直接記錄下來就可以了。
多重性約束主要用于檢查和維護數據。更新數據庫時,可以根據多重性約束判斷此次更新是否違反了企事業單位聲明的規定,因此多重性約束是實體的實例出現能否被錄入的準則。具有多重性約束的模型能夠更加明確的表述聯系的語義,從而更好地表示企事業單位的數據需求。
檢查扇形陷阱和斷層陷阱
必要的聯系確定以后,還要檢查 ER 模型中的每個聯系是否準確的描述了 “現實世界”,確保沒有無意中形成的扇形陷阱和斷層陷阱。
下圖為 DreamHome 案例中用戶視圖 StaffClient 的ER 圖的初步構想。
用文檔記錄聯系類型
確定好聯系類型以后,還要賦予他們有意義并且容易被用戶理解的名字。同時還要在數據字典中記錄聯系的描述以及多重性約束。下表顯示了數據字典中關于 DreamHome 的用戶視圖 StaffClient 的部分內容。
步驟 1.3 標識屬性并將屬性與實體或聯系類型相關聯
目標——將屬性與相應的實體和聯系類型關聯在一起。
方法學的下一個步驟就是要確定那些已經被選定要在數據庫中表示的實體和聯系的屬性。類似于實體的確定,我們繼續在用戶需求規格說明書中尋找名詞和名詞短語。若名詞或名詞短語是實體或聯系的一種特性、性質、標識符或特征時,即可標識為屬性。
當我們已經在需求規格說明書中標識出了實體(x)或聯系(y)以后,接下來就可以問自己 “對于 x 或 y,我們需要保留它們的哪些信息?” 到現在為止這是確定屬性最簡單的方法,而問題的答案應該在需求規格說明書中有清楚的描述。但是在某些情況下,可能還有必要請用戶對需求進行澄清。遺憾的是,用戶對這些問題的回答又可能會涉及一些其他的概念,因此對用戶的回答必須仔細斟酌。
簡單 / 組合屬性
判別屬性是簡單屬性還是組合屬性十分重要。組合屬性由簡單屬性構成。例如,address 屬性可以是簡單屬性,它將所有的地址細節作為一個單值,如 “115 Dumbarton Road,Glasgow, G11 6YG”。然而,該地址也可被視為一個組合屬性,它由若干簡單屬性組成,比如 street(“115 Dumbarton Road”)、city(“Glasgow”)和 postcode(“G11 6YG”)。選擇用簡單屬性還是組合屬性描述地址,取決于用戶需求。如果用戶不需要單獨訪問地址中的某個組成部分,就可以將 address 作為一個簡單屬性處理,反之,address 就要作為組合屬性,由所需的簡單屬性構成。
在這個步驟中,重要的是我們要表示出概念數據建模中的所有簡單屬性,包括那些組成組合屬性的屬性。
單值 / 多值屬性
屬性除了有簡單和合成之分外,還有單值或多值的分別。大多數屬性都是單值的,但也會有一些多值屬性,即一個實體的某個屬性可能有多個值。例如,實體 Client 的 telNo(電話號碼)屬性就可以是多值屬性。
另一方面,客戶的電話號碼也可被視為獨立于客戶的另一實體。在設計模型時,這兩種方案都是可行的,而且同樣有效。在步驟 2.1 中我們會看到,多值屬性被映射為關系,所以兩種方法產生的結果是一樣的。
導出屬性
其值依賴與其他屬性值得屬性稱為導出屬性。導出屬性的例子包括:
- 員工的年齡
- 一個員工管理的房產數量
- 押租(一般按兩倍月租計算)
一般情況下,導出屬性不在概念數據模型中描述。但有時候導出屬性依賴的屬性和屬性值會被刪除或修改,此時導出屬性就必須在概念數據模型中描述,以避免可能的信息丟失。如果一個導出屬性出現在模型中,就必須注明它是導出的。導出屬性的表示形式將在物理數據庫設計時考慮。根據導出屬性使用方式的不同,導出屬性的值可在每次被訪問時計算,或者在其所依賴的屬性值發生變化時計算。不過,概念數據庫設計并不關心這個問題,這部分內容將在討論步驟 3.2 是講述。
潛在問題
在為視圖標識實體、聯系和屬性時,常常會從最初是的選擇中遺漏一個或多個實體、聯系或者屬性。這種情況下,我們需要返回到前面的步驟,記錄新確定的實體、聯系或屬性,并重新檢查所有相關的聯系。
通常屬性的數量要比實體和聯系多,最好先對用戶需求規格說明書中給出的所有屬性做個列表。一旦發現某個屬性和某個實體或聯系相關聯,就從列表中刪除該屬性。這樣能確保一個屬性只與一個實體或聯系類型關聯。當列表為空時,所有屬性就都和實體或聯系類型關聯起來了。
要當心可能存在一個屬性與多個實體或聯系類型相關聯的情況,原因可能是:
我們已經確定了多個實體,其實這些實體可以被抽象為一個實體。例如,我們可能已經確定了實體 Assistant 和 Supervisor,它們都包含屬性 staffNo、name、sex 和 DOB,其實這兩個實體都可以用實體 Staff 來表示,而 Staff 的屬性包括 staffNo、name、sex、DOB 和 position(其值是助理或主管)。另一方面,這些尸體也可能共同擁有某些屬性,然后有各自擁有一些特殊屬性。這時,我們必須決定是將這些實體泛化為一個單一的實體(如 Staff),還是將它們作為分別表示不同職業角色的特殊化實體來對待。關于特殊化還是泛化實體的問題已經在增強實體-聯系建模部分討論過,在步驟 1.6 中還會有更詳細的說明。
我們在實體類型間已確定了一個聯系。此時,屬性只能與唯一一個實體,就是父實體關聯,并確保該聯系已在前面的步驟 1.2 中被標識。如果不是這樣,就應該更新文檔,將新確定的聯系寫入文檔。例如,假設我們已經確定了實體 Staff 和 PropertyForRent 及其屬性:
Staff staffNo, name, position, sex, DOB
PropertyForRent propertyNo, street, city, postcode, type, rooms, rent, managerName
PropertyForRent 中,屬性 managerName 表示聯系 Staff Manages PropertyForRent。此時,應該將屬性 managerName 從 PropertyForRent 中刪除掉,并增加聯系 Manages。
DreamHome 中實體的屬性
對于 DreamHome 的用戶視圖 StaffClient,我們可以確定以下實體及其屬性:
Staff staffNo, name(fName, lName), position, sex, DOB
PropertyForRent propertyNo, address(street, city, postcode), type, rooms, rent
PrivateOwner ownerNo, name(fName, lName), address, telNo
BusinessOwner ownerNo, bName, bType, address, telNo, contactName
Client clientNo, name(fName, lName), telNo, eMail
Preference prefType, maxRent
Lease leaseNo, paymentMethod, deposit(deposit = PropertyForRent.rent * 2), depositPaid, rentStart, rentFinish, duration(duration = rentFinish - rentStart)
DreamHome 中聯系的屬性
一些屬性不應該和實體關聯,而應該和聯系相關聯。對于 DreamHome 的用戶視圖 StaffClient,屬性與聯系關聯的情況如下:
Views viewDate, comment
用文檔記錄屬性
確定了屬性以后,還要為他們指派對用戶而言有意義的名字。每個屬性需要被記錄的信息包括:
- 屬性名和說明。
- 數據類型和長度。
- 該屬性已知的所有別名。
- 屬性是否為組合的,如果是則給出組成它的簡單屬性。
- 該屬性是否為多值得。
- 該屬性是否為導出的,如果是應該如何計算它。
- 該屬性的默認值。
下圖給出了數據字典中記錄 DreamHome 中用戶視圖 StaffClient 的屬性的部分內容。
步驟 1.4 確定屬性域
目標——確定概念數據模型中屬性的域
步驟 1.4 的目的視為模型中的所有屬性確定域。域是值集,一個或多個屬性可以從中取值。例如,可以定義:
- 合法員工編號(staffNo)的屬性域是五個字符長的字符串,頭兩個是字母,接著三個是數字,數字范圍是 1 ~ 999。
- 實體 Staff 的屬性 sex 的可能值要么是 “M”, 要么是 “F”。這個屬性的域是單字符的字符串,由 “M” 或 “F” 構成。
完善的數據模型應為每個屬性指定域,包括:
- 屬性的合法值的集合。
- 屬性的存儲空間大小和格式。
還有更多的信息可用于說明域,如屬性上允許的操作,哪些屬性可以相互比較,或者那些屬性可以相互結合。不過,如何在 DBMS 中實現屬性域的這些特性仍然處于研究階段。
文檔記錄屬性域
確定屬性域后,在數據字典中記錄屬性域的名字和特性。更新數據字典,用屬性域替代屬性的數據類型和長度信息。
步驟 1.5 確定候選關鍵字、主關鍵字和可替換關鍵字屬性
目標——為每個實體類型確定候選關鍵字,如果有多個候選關鍵字,則選擇一個作為主關鍵字,其他作為可替換關鍵字。
這個步驟主要考慮為實體確定候選關鍵字,并選擇其中一個作為主關鍵字。候選關鍵字 是實體中可以唯一確定該實體每個出現的最小屬性集合。我們可以確定出多個候選關鍵字,然而必須從中選擇一個作為 主關鍵字,剩下的候選關鍵字稱為 可替換關鍵字。
人名通常做不了候選關鍵字。例如,讀者可能認為組合屬性 name 即員工的姓名適合作為實體 Staff 的候選關鍵字。然而,DreamHome 中有可能兩個人同名,很顯然,name 作為候選關鍵字是不合適的。同樣,DreamHome 中的業主的名字也有類似的問題。這種情況下,盡管我們可以考慮將若干屬性組合在一起以滿足唯一性,但更好的方法是使用一個已經存在并能保證唯一性的屬性,如實體 Staff 的屬性 staffNo 和實體 PrivateOwner 的屬性 ownerNo,或者定義一個新的能保證唯一性的屬性。
從候選關鍵字中選擇主關鍵字時,可以參考以下原則:
- 包含屬性個數最少的候選關鍵字。
- 屬性值被修改的可能性最小的候選關鍵字。
- 字符數最少的候選關鍵字(對于文本屬性)。
- 最大值最小的候選關鍵字(對于數值屬性)。
- 從用戶的角度看最容易使用的關鍵字。
在確定主關鍵字的過程中,要注意實體的強弱。如果能為一個實體指定關鍵字,該實體就是 強實體,否則就是 弱實體??梢酝ㄟ^設置外部關鍵字,將弱實體和其所有者實體關聯起來,然后確定弱實體的主關鍵字。步驟 2.1 描述了將實體和實體間的聯系映射為關系的過程,到這一步才能為弱實體指定主關鍵字。
DreamHome 的主關鍵字
下圖給出了 DreamHome 的 StaffClient 用戶視圖的主關鍵字。注意 Preference 實體是個弱實體,聯系 Views 由兩個屬性:viewDate 和 comment。
用文檔記錄主關鍵字和可替換關鍵字
在數據字典中記錄主關鍵字和所有可替換關鍵字標識。
步驟 1.6 考慮使用增強的建模概念(可選步驟)
目標——考慮使用增強的建模概念,如特殊化 / 泛化、聚合和組合。
在這個步驟中,可選擇使用增強實體-聯系建模中討論的特殊化 / 泛化、聚合和組合等高級建模概念,繼續改進 ER 模型。如果使用特殊化方法,就要定義一個或多個 子類 或 超類 實體來體現實體間的不同。如果使用泛化方法,就要尋找實體間的共同特征,以定義一個泛化的超類實體??梢允褂镁酆媳硎緦嶓w間的 “擁有” 或 “屬于” 聯系,其中一個實體是 “整體”,另一個則是 “部分”??梢允褂媒M合(一個特殊的聚合)表示在 “整體” 和 “部分” 之間具有強附屬關系以及相同的生命周期。
對于 DreamHome 的 StaffClient 用戶視圖,對 PrivateOwner 和 BusinessOwner 這兩個實體進行泛化,創建一個包含公共屬性 ownerNo、address 和 telNo 的超類 Owner。超類 Owner 和它的子類之間是強制參與和不相交的聯系,記為 {Mandatory,Or}:超類 Owner 的每一個成員必須是其中一個子類的成員,但不能同時屬于兩個。
此外,我們創建 Staff 的一個特殊化子類 Supervisor,并特別構建聯系 Supervises。超類 Staff 和子類 Supervisor 的聯系是可選參與的,超類 Staff的成員不必是子類 Supervisor 的成員,為了使設計簡單,我們不使用聚合和組合。修改后的 DreamHome 的 StaffClient 用戶視圖的 ER 圖如下所示。
在選用高級建模概念開發 ER 模型時沒有嚴格的規定,基本上取決于設計者的主觀意志以及所建模型的特征。從經驗上來說,選擇使用這些概念時,要能使 ER 圖盡可能清楚的表示重要的實體以及它們之間的聯系。因此,應根據 ER 圖的可讀性,以及描述重要實體和聯系時的清晰程度決定高級建模概念的選用。
雖然這些概念是和增強的 ER 模型相關的,但因這一步是可選的,所以在整個方法學中仍然簡單地用 “ER 圖” 代表數據模型的圖形表示。
步驟 1.7 檢查模型的冗余
目標——檢查模型中任何存在的冗余
步驟 1.7 檢查概念數據模型中是否存在任何冗余,若有,則刪除它們。這一部主要的活動有:
- 重新檢查一對一(1:1)聯系。
- 刪除冗余的聯系。
- 考慮時間因素。
1. 重新檢查一對一(1:1)聯系
在確定實體的過程中,可能發現兩個實體表示企事業單位中的同一個對象。例如,可能確定兩個實際上相同的實體 Client 和 Renter,換句話說,Client 和 Renter 是同義詞。這種情況下,兩個實體應該合為一個。如果主關鍵字不同,選擇一個作為主關鍵字,將另外一個作為可替換關鍵字。
2. 刪除冗余的聯系
如果一個聯系表示的信息能夠通過其他聯系獲得,這個聯系就是冗余的。我們要努力創建最小的數據模型,所以冗余的聯系是不必要的,應該刪除。注意,雖然確定兩個實體間是否存在多個路徑比較容易,但這不意味著某個聯系就是多余的,他們完全可能表示兩個實體間不同的關聯。例如,考慮下圖中的實體 PropertyForRent、Lease 和 Client 之間的聯系。
在實體 PropertyForRent 和 Client 之間有一條間接路徑,即通過中間實體 Lease 的聯系 Holds 和 AssociatedWith。在判斷這兩條路徑是否都需要之前,我們要先弄清楚創建者兩條路徑的目的。聯系 Rents 表示某個客戶租用某處房產。另一方面,聯系 Holds 表示某個客戶是一個租用關系的實施者,聯系 AssociatedWith 則表示該租用關系的租用對象是某處房產?,F實生活中,盡管在客戶和他們租用的房產之間確實存在聯系,但一般不是直接聯系,這種聯系通過租用關系關聯顯得更加準確。因此,聯系 Rents 是一個冗余聯系,因為它并沒有表示出實體 PropertyForRent 和 Client 之間更多的、用通過實體 Lease 的間接關聯無法正確表示的信息。為了創建最小化的模型,冗余聯系 Rents 必須刪除。
3. 考慮時間因素
在考慮冗余時,聯系的時間因素很重要。例如,考慮這樣的情形——在實體 Man、 Woman 和 Child 之間建立聯系,如下圖所示。
很明顯,在 Man 和 Child 之間有兩個路徑:一個是通過直接聯系 FatherOf,另一個則是通過聯系 MarriedTo 和 MotherOf。進而,我們會認為聯系 FatherOf 是不必要的,然而這并不正確,原因是:
- 父親可能會因為先前的婚姻而有孩子,而該模型中只用一個一對一聯系表述父親當前的婚姻情況。
- 父親和母親可能沒有結婚,或者父親與不是孩子母親的人jiehun(或者母親與不是孩子父親的人結婚)。
無論哪種情況,沒有 FatherOf 聯系的話,所需要的聯系就不能構建出來。這個例子說明在考慮冗余時,檢查實體間的每個聯系含義都很重要。最后,我們通過刪除任何內在的冗余簡化了局部概念數據模型。
步驟 1.8 針對用戶事務驗證概念模型
目標——確保概念模型支持所需要的事務。
至此我們已經有了一個表示企事業單位數據需求的概念數據模型。本步驟的目的是檢查模型以確保模型支持所需要的事務。在這個模型的基礎上,我們嘗試以手工的方式模擬運行企事業單位的業務。如果能用這種方法完成所有事物,我們就能驗證這個概念數據模型是支持這些食物的。然而,如果某個事物不能手工完成,則數據模型可肯定存在必須解決的問題。出現這種情況的原因可能是數據模型中遺漏了某個實體、聯系或屬性。
可以通過兩個步驟驗證概念數據模型是否支持所需要的事務:
- 描述事務。
- 使用事務路徑。
描述事務
在這個步驟中,用文檔寫出模型中每個事務的需求,我們就可以檢驗該模型是否支持每個事務所需要的所有信息(實體、聯系和屬性)。
使用事務路徑
第二步是針對所需的事務驗證概念模型,驗證方法是在 ER 圖中直接標出每個事務所有的路徑。
步驟 1.9 與用戶一起復查概念數據模型
目標——和用戶一起復查概念數據模型以確保該模型真實地描述了企事業單位的數據需求。
在步驟 1 完成之前,我們和用戶一起復查概念數據模型。概念數據模型包括 ER 圖和描述數據模型的支持文檔。如果數據模型中存在任何問題,我們必須進行適當的修改,這可能需要重復前面的步驟。這個過程可能需要重復多次,直到用戶確認該模型確實 “真實地” 表現了被建模的那部分企事業單位需求。