为了彻底搞清楚数据库 E-R 模型设计,我肝了这篇万字长文
文章簡介
本文主要描述了關系型數據庫設計的各個階段及重要概念,并重點介紹了 概念設計 和 邏輯設計 兩大核心階段,著重強調了 E-R 模型的構造 步驟,除此之外還補充了 關系模式的規范化 及如何 求解關系模式的候選碼 等重要知識點。
1 數據庫設計概述
1.1 何為數據庫設計?
數據庫設計是指對于一個給定的應用環境,構造最優的數據庫模式,建立數據庫及其應用系統,使之能夠有效地存儲數據,滿足各種用戶的應用需求(信息要求和處理要求)。
數據庫是信息系統的核心和基礎,它把信息系統中大量的數據按一定的模型組織起來,并提供存儲、維護、檢索數據的功能,最終使信息系統可以方便、及時、準確地從數據庫中獲得所需的信息。即數據庫的設計目標是:為用戶和各種應用系統提供一個信息基礎設施和高效率的運行環境,這里的高效率代表的是冗余少、易維護和便于使用。
數據庫設計大致可分為如下幾個階段:
需求分析 → 概念設計 → 邏輯設計 → 物理設計 → 數據庫實現 → 運行與維護階段。
總而言之,數據庫設計是一個不斷迭代和逐步求精的過程。而在這個過程中,重中之重的階段為概念設計與邏輯設計,且本文也是圍繞這兩個階段著重展開敘述的。
1.2 必須要明確的幾個概念
本文主要討論分析的數據庫設計為關系型數據庫,在正式開始了解數據庫設計階段之前先來明確幾個關系型數據庫的重要概念。
關系 :關系型數據庫關系的數據結構就是一張二維表,通俗的講,二維表名稱就是關系名。
屬性 :二維表中的列稱為屬性(字段),每個屬性都有一個屬性名。
值域 :二維表中屬性的取值范圍稱為值域,每個屬性都有一個值域。
關系模式 :二維表的結構稱為關系模式。設關系名為 R,其屬性為 A1,A2,…,An,則關系模式可以表示為:R(A1,A2,…,An),一個具體的例子:職工(職工號,姓名,性別,部門)。
候選碼 :如果一個屬性集的值能唯一標識一個關系的元組而又不含多余的屬性,則稱該屬性集為候選碼。在一個關系上可以有多個候選碼。
主屬性 :包含在任一候選碼中的屬性。
非主屬性 :不包含在任一候選碼中的屬性。
主鍵 :有時一個關系有多個候選碼,可以選擇其中一個作為主鍵。每個關系有且只有一個主鍵。
外鍵 :如果關系模式 R 中的屬性 K 是其他關系模式的主鍵,那么 K 在關系模式 R 中稱為外鍵。
2 需求分析
需求分析階段就是分析用戶的需要與要求,它是設計數據庫的起點,需求分析的結果能否準確地反映用戶的實際要求,將直接影響到后面各個階段的設計,并影響到設計結果是否合理和實用。
需求分析的主要任務就是要通過詳細調查現實世界中要處理的對象,來充分了解明確用戶的各種需求,最終確定系統的功能,并且必須充分考慮系統在今后可能的擴充和改變,不能僅僅按當前應用需求來設計數據庫。
需求分析階段的最終產物是要有明確的系統需求分析報告,一般會包括數據流圖、功能模塊圖、數據字典等內容,并且它是指導開展數據庫設計后續階段活動的重要依據。
由于本文主要介紹數據庫的 E-R 模型設計,所以關于需求分析的相關內容就不再展開敘述。
3 概念設計
3.1 現實世界向機器世界的過渡
概念設計是設計形成一個獨立于 DBMS 的概念數據模型,用來表述數據與數據之間的聯系,它直接面向現實世界,因而很容易被用戶所理解,方便用于數據庫設計者與用戶的交流。該階段先設計與用戶具體應用相關的數據結構——用戶視圖,然后再不斷對視圖進行集成修改,最終得到一個能正確、完整地反應該單位數據及聯系并滿足各種處理要求的數據模型,之后再把概念模型轉換成具體機器上 DBMS 支持的數據模型。
概念結構設計的特點:
- 能真實、充分地反映現實世界;
- 易于理解;
- 易于更改;
- 易于向關系、網狀、層次等各種數據模型轉換。
概念設計的階段的主要描述工具就是 E-R 模型(Entity-Relationship Model)。
3.2 E-R 模型
經過上文可知 E-R 模型是概念設計階段的主要描述工具,起到『承上啟下』的一種過渡作用,其重要性不言而喻,所以現在我們先來了解一下 E-R 模型中的幾個重要概念。
3.2.1 實體和屬性
實體是 E-R 模型的基本對象,是對現實世界中各種事物的抽象。它可以是物理存在的事物,例如人、汽車等;也可以是抽象的概念,例如學校、部門等。
屬性是不可分割的數據單位,用于描述實體所具有的特征,例如教師實體具有姓名、性別、地址等屬性。
能夠唯一表示實體的屬性集稱為碼。
在 E-R 模型中,實體一般是長方形來體現,而屬性則是橢圓形,如果屬性是主碼(主鍵),則在屬性名稱下用畫下劃線來表示。如下圖所示。
這張圖描述了一個教師的實體對象以及它擁有的姓名、性別等屬性,是對現實世界信息的直觀描述。
某些屬性還可以劃分具有獨立意義的子屬性,那這類屬性就稱為復合屬性。例如人的姓名可劃分為“姓”和“名”;地址屬性可以劃分為郵政編碼、省名、市名、區名和街道這些子屬性,而街道又可劃分為街道名和門牌號,其層次結構如下:
復合屬性的用途有兩個:
- 準確模擬現實世界的復合信息結構;
- 當用戶需要把復合屬性作為一個整體使用又需要單獨使用各子屬性時,屬性的復合結構就顯得十分重要。
例如發郵件時稱呼對方可能只需要復合屬性“姓名”中的“姓”就足夠了。
屬性按照取值的個數還可以分為單值屬性和多值屬性。單值屬性是指此屬性對于同一個實體只能取一個值,大多數的屬性都屬于單值屬性,例如同一個人只能具有一個年齡和一種性別。但是在某些情況下,實體的屬性可能取多個值,這時候的屬性就稱為多值屬性,例如人的聯系方式信息就是一個多值的,有的人有 1 個電話,有的人有 2 個或者 3 個等等,或者可以分為移動電話聯系方式、固定電話聯系方式和郵件聯系方式等。
注意:多值屬性的描述與單值屬性不一致,它采用雙線橢圓表示,并且在實際開發過程中,如果有多值屬性出現,一般要將其另歸為實體或聯系。
實體屬性之間可能具有某種聯系,例如人的年齡屬性和出生日期有一種相互依賴關系,根據出生日期可以推導出人的年齡,我們就稱年齡為導出屬性或派生屬性。導出屬性不僅可以從另外的屬性中導出,也可以從相關的實體導出。例如一個公司實體的員工數量屬性的值可以通過累計該公司所有員工數得到。
還有一種屬性稱為可選屬性,即并不是所有的屬性都必須有值,有些屬性的可以沒有值,這就是可選屬性,在橢圓的文字后用“(O)”來表示。
3.2.2 實體型和鍵
同一類實體構成實體類或實體集,實體類的特征用實體型來表示,實體型本質上是一個具有相同屬性的實體集合,由一個實體型名字和一組屬性來定義,用于描述一組實體的公共結構,該實體集合中的任一實體稱為該實體型的一個實例。
例如,一個公司有上千名員工,需要在數據庫中存儲每個員工的信息,而這些員工的信息又都是類似的,如姓名、年齡等是這些員工相同的屬性,只不過對于不同的員工其具體的屬性值不同而已,此時我們就可以把這些類似的實體抽象為一個實體型,如:員工(員工編號、姓名、部門、性別、年齡、職稱)。
由此看來,實體型這一概念也就是上文我們所提到的關系模式,只是換了個馬甲而已,實體型名字也就是關系模式名字。
為了區別實體型中的不同實體,又引入了“鍵”的概念,它要求對于不同的實體,“鍵”的值必須不同,例如不同的員工必須要有一個不同的“員工號”來作為區別。一個實體型可以有多個鍵,例如“人”的姓名和生日屬性是一個鍵,而身份證號屬性是另一個鍵。
實體型的每個簡單屬性都具有一個可能的取值范圍,稱為值域,例如“人”的年齡值域可以為 1-150 的整數范圍。
3.2.3 實體間的聯系
(1)聯系的種類
現實世界中,事物內部或事物之間總是有聯系的,聯系反映了實體內部或實體之間的關系。
聯系的度數指的是一個聯系所涉及的實體數。比如:單實體聯系、兩實體聯系和多實體聯系。
比較常見的為兩實體聯系,兩個實體之間可能存在以下聯系:
- 一對一聯系(1 : 1),例如部門和負責人之間的聯系,一個部門有一個負責人,一個負責人負責一個部門;
- 一對多聯系(1 : n),例如部門和員工之間的聯系,一個部門有多個員工,而每個員工只屬于一個部門;
- 多對多聯系(m : n),例如項目和員工之間的聯系,一個項目可以需要多個員工參加,而一個員工也可以參加多個項目。
聯系一般使用菱形來進行描述,上面的這幾種聯系可用如下 E-R 圖來表示。
單實體聯系也可分為一對一、一對多、多對多聯系,如員工和員工之間的“領導”關系就是一對多聯系,員工與員工之間的配偶關系是一種一對一聯系。
一般地,兩個以上的實體之間也存在一對一、一對多和多對多的聯系。例如學生選課系統中有三個實體:學生、教師、課程,此時它們之間的聯系如下:
它表示一個教師可以教授多門課程,一個課程可以被多個教師教授;一個學生可以選擇多門課程,一門課程可被多個學生選擇,學生在選課的同時選擇教師。
(2)聯系的存在性
除了上面聯系的種類之外,還要考慮一個實體在一個聯系中的存在性。存在性在轉換成邏輯模式后表現為某個屬性是否可以為空值,空值為不明確的值,在 DBMS 中用 NULL 表示。
一般的,聯系有如下幾種存在性:
- 強制存在:在連線上劃“1”,表示最小的基數為1。如果聯系一端的實體的實例對于該聯系的其他實體的實例必須存在,則稱該實體為強制的。
- 可選存在:連線上劃“0”,表示最小基數為0。如果聯系一端的實體的實例對于該聯系的其他實體的實例不要求一定存在,則稱該實體為可選的。
- 未知存在:連線上不劃“1”或“0”,表示目前不知道是強制還是可選的。
例如上述員工參加項目的 E-R 圖,可以補充完善其聯系的存在性:
它表示一個項目至少要有一個員工參加(強制性的),而一個員工可能不參加任何一個項目(可選的)。
3.2.4 高級 E-R 構造
高級 E-R 構造指的是對 E-R 模型的擴充,簡稱 EER 模型(extend-ER),EER 模型包括了 E-R 模型的所有概念,此外,它還包括泛化層次、匯集層次和弱實體等概念。
(1)泛化層次
泛化層次涉及到子類、超類、泛化和特化等概念,讓我們先來了解一下。
子類和超類
在很多應用中,一個實體型的實體需要進一步劃分為多個子集合,并要明確表示出來。例如,實體型教師的成員實體可以分為教授、副教授、講師和助教 4 個實體集合,這些集合都是教師實體集合的子集合(可定義為子實體型),稱之為實體型教師的子類,而實體型教師稱為這些子實體型的超類。
子類與超類之間的關系稱為 IS-A 關系,子類的成員必須是超類的成員,否則不能在數據庫中出現,但是超類的某些成員可以不屬于任何子類。
這一概念和 Java 繼承關系中的子類與父類概念是很類似的。
泛化(歸納)
泛化也稱為歸納,它是將幾個實體中的某些公共屬性概括出來,提升為一個高一層次的超類,而原先的實體類則變為子類,子類除了它自己的屬性以外還繼承超類的屬性。
泛化層次可分為互斥泛化層次和重疊泛化層次兩種。互斥泛化層次是指子類之間是互斥的,即一個實例不可能出現在兩個以上的子類中,互斥泛化層次在泛化層次圖中的圓圈中寫入字母 D(Disjoint); 重疊泛化層次在泛化層次圖中的圓圈中寫入字母 O(Overlapping)。
例如,實體型飛機、火車和汽車可以泛化出超類運輸工具,圖中的雙線表示運輸工具實體型的每個實體必須屬于一個子類,即表示子類完全包含了超類,超類中的每一個實例,子類中都有該實例,這種情形稱為完全性限制。
特化(演繹)
特化是泛化的逆過程,它也稱為演繹,是根據超類而演繹出子類的過程。例如,實體型教師可以演繹形成子類教授、副教授、教師和助教,這個過程是按照教師職稱對教師實體的分類,它還可以使用不同的分類規則進行多種演繹。例如,可以按照教師的專業對教師實體進行演繹,得到文科教師、理科教師和外語教師等等。
(2)匯集層次
匯集(Aggregation)是另一種重要的信息抽象手段,描述了整體和部分之間的聯系,即實體之間“…是…的一部分(is part of)”的聯系,或者“……是由……組成的”。
匯集層次中沒有繼承,所以也不以超類、子類來稱呼相關的實體,而是稱為父實體和成份實體。
匯集的概念類似于面向對象概念中的聚合關系。例如,一個教室由房間、門窗、電腦、投影儀等等組合而成,它們之間沒有繼承關系。
(3)弱實體
在實際領域中經常存在這樣一些實體型,它們沒有自己的鍵(即所有屬性都不足以形成主鍵),這種實體型的實體不能獨立存在,必須要依賴于一個強實體,則稱這種實體型為弱實體型。在 E-R 圖中用雙線框表示弱實體。
弱實體型的不同實體的屬性值可能完全相同,難以區別,所以它才需要與一般的實體型進行關聯,目的就是用來區分不同的弱實體。
如在人事管理系統中,職工家屬的信息就是以職工的存在為前提的,家屬實體是弱實體,子女與職工的聯系是一種依賴聯系。又如,學生家長是一種弱實體,因為只有學生實體存在,家長實體才會存在。
上圖就表示了家屬實體是弱實體,不能單獨存在必須依賴與職工實體,這里的標示的依賴信息為存在依賴(E)和標識依賴(ID):
存在依賴:若某個實體 X 的存在依賴于另外一個實體 Y 的存在而存在,則稱 X 存在依賴于 Y。這是一種特殊的聯系,用 E 表示,并用箭頭表示方向,其中 X 稱為弱實體,用雙框表示,稱 Y 為 X 的父實體。
標識依賴:如果一個實體不能用它自己的屬性來唯一標識,即沒有自己的主鍵,而只能用與其他實體的聯系來標識,則稱該實體標識依賴于其他實體。這也是一種特殊的聯系,用 ID 表示,并用箭頭表示方向。
3.3 概念設計方法與步驟
在了解了 E-R 模型的相關概念之后,我們就需要了解一下概念設計中的幾種常用設計方法和策略,總體策略和方法可以歸納為 4 種。
(1)自頂向下:首先定義全局概念結構的框架,然后逐步細化。
(2)自底向上:首先定義各局部應用的概念結構,然后將它們集成起來,最終得到全局概念結構。
(3)逐步擴張:首先定義最重要的核心概念結構,然后向外擴充,以滾雪球的方式逐步生成其他概念結構,直至總體概念結構。
(4)混合策略:將應用劃分為相對獨立的不同功能,針對每一種功能設計相應的局部 E-R 模型,最終通過歸納合并,消去冗余和不一致,形成全局 E-R 模型。
最常用的策略是自底向上法,即先進行自頂向下的需求分析,再進行自底向上的概念設計,如下圖所示。
正如上圖所示,一般我們會根據需求中的一個獨立的小模塊進行概念模式的設計,然后再對這些局部視圖進行集成,最終匯總成一個符合需求分析要求的全局概念模式。
自底向上概念結構設計步驟:
3.4 局部 E-R 模型設計
按照上述的概念設計策略,一般情況下我們會先按照需求模塊進行局部 E-R 模型的構建,然后在集成匯總為全局 E-R 模型。
局部 E-R 模型設計首先要確定局部 E-R 圖描述的范圍,一般要遵循獨立性原則和規模適度原則。
獨立性原則指的是劃分在一個范圍內的應用功能具有獨立性與完整性,與其他范圍內的應用有最少的聯系。規模適度原則是指局部 E-R 圖規模應適度,一般以 6 個左右的實體為宜。
建立 E-R 模型的步驟:區分實體和屬性 → 找出匯集層次 → 找出泛化層次 → 找出弱實體 → 定義聯系。
(1)區分實體和屬性
實體要有描述信息。如果一個對象有多個描述信息,則應考慮將其作為實體;但如果一個對象只有一個描述信息,則應考慮將其作為屬性。
如果某些非標識屬性有多個值與實體對應,即屬性的多個值與標識屬性的一個值對應,則稱其為多值屬性。將多值屬性歸為另一個實體
將屬性歸到它最直接描述的實體中。例如屬性“辦公樓名”應歸到實體部門中,而不是歸到實體職工中。
(2)找出匯集層次
對基本實體進行分析,如有某個實體是由其他實體組成,則將它們構造成一個匯集層次,通常的做法是將已有的實體匯集出一個新實體。
(3)找出泛化層次
一旦完成了基本實體的劃分,就可以用泛化和特化(兩者都要用)來構造類層次,如果基本實體有了變化,則要重新考慮有關的泛化層次和新產生的泛化層次。要做好泛化和特化的工作,經驗起著重要的作用。
(4)找出弱實體
對于弱實體,建議在建立泛化層次后再考慮,比如說一個公司的職工家屬相對于公司就是一種弱實體存在。
(5)定義聯系
上述工作完成之后就可以來定義實體之間的聯系了。當然泛化層次、匯集層次等也是特殊類型的聯系,只是做泛化、匯集等分析時通常會產生新實體,而普通的聯系是指實體之間發生作用,不會產生新實體也不會減少實體。這就是為什么要到最后才考慮聯系的原因。應該說定義聯系是ER模型的關鍵,大部分的信息關聯都是由聯系表述出來的。
注意:聯系應該是最后分析定義的階段,在區分實體和屬性的時候不要過早考慮聯系。
實體之間有多個聯系是可能的,但不要表示相同的概念,否則將會出現聯系的冗余。冗余聯系是指表示相同概念的多個聯系,從 E-R 圖生成關系模式時,冗余聯系會導致生成的關系模式不規范,有過多的冗余。
此外,多個實體之間存在聯系也是可能的,這就是多實體聯系,例如上文的學生選課就是一個多實體聯系的實例。
(6)建立 E-R 模型注意的幾點原則
在創建 E-R 模型的過程中,一般我們要遵守以下幾點原則:
- 屬性是不可分割的;
- 每個實體有唯一的標識,而聯系沒有標識,一般聯系的標識依賴于相關實體的標識;
- 每個子類有唯一的超類,子類本身不定義標識,而從超類中繼承標識;
- 不允許弱實體作為子類,但可作為超類;
- 實體名、聯系名和屬性名在一個 E-R 圖(局部或全局)中應唯一;
- 相同實體之間的多個聯系應是可區別的。
3.5 E-R 模型的集成
由于局部 E-R 模型反映的只是局部子功能對應的數據視圖,且局部 E-R 圖之間可能存在不一致之處,還不能作為邏輯設計的依據,此時可以進行 E-R 模型的集成,去掉不一致和重復的地方,最終合并為全局視圖。
局部 E-R 模型的集成方法有如下兩種:
- 多元集成法:一次性將多個局部 E-R 圖合并為一個全局 E-R 圖;
- 二元集成法:用累加的方式一次集成兩個局部 E-R 圖。
在實際應用中一般根據系統的復雜程度選擇集成的方法,并可以混合選擇使用。無論采用哪種集成方法,每次集成都分為兩個階段:
視圖集成最好由一個人完成,或始終在一個人主持下完成,否則不但舊的問題解決不了,新的問題也會不斷產生。
下面就這兩個階段的內容進行展開敘述。
3.5.1 合并
由于各個局部應用所面臨的問題不同,且通常是由不同的設計人員進行局部 E-R 圖的設計,這就導致各個局部 E-R 圖之間必定存在許多不一致的地方,即存在沖突。合理地消除沖突,形成一個能為全系統中所有用戶共同理解和接受的統一的概念模型,成為合并局部 E-R 模型的主要工作。
沖突主要分為三類:屬性沖突、命名沖突和結構沖突。
(1)屬性沖突
① 屬性域沖突,即屬性值的類型、取值范圍不一致。例如,員工的工號是使用數值型還是字符型。
② 屬性取值沖突。例如,學生的成績有的以百分制計,有的以五分制計。
這類沖突是由于用戶在業務上的約定而引起,必須由用戶協商解決。
(2)命名沖突
命名沖突可能發生在實體、屬性和聯系上,常見的為屬性沖突。
① 同名異義:不同意義的對象在不同的局部應用中具有相同的名字。例如,“單位”既可以表示人員所在部門,也可以作為長度、重量等度量的屬性。
② 異名同義:同一意義的對象在不同的局部應用中具有不同的名字。例如學校的“系別”與“學院”實際上是同一實體。
這類沖突通常可以采取行政手段進行協商解決。
(3)結構沖突
① 同一對象在不同局部應用中具有不同的身份。例如局部模型A中的某實體在另一局部模型 B 中被設計為屬性,這就造成了結構上的沖突。
解決方法:將實體轉化為屬性或將屬性轉化為實體,保持結構的統一。
② 同一對象在不同局部應用中的屬性組成不完全相同。例如,對同一類“員工”這一對象,在局部模型 A 中其屬性為工號、姓名、性別、年齡4個屬性,而在另一局部模型 B 中的屬性為工號、姓名、所在部門 3 個屬性組成。
解決方法:對實體的屬性取其在不同局部應用中的并集,并適當設計好屬性的次序。
③ 相同實體之間的聯系在不同局部模型中不一致。例如,在局部應用 A 中實體 E1 和 E2 是一對多聯系,而在局部應用 B 中卻是多對多聯系。
解決方法:根據應用語義對實體聯系的類型進行綜合或調整。
3.5.2 優化
數據冗余和聯系冗余是 E-R 模型的主要冗余問題,能被其他數據推導(派生)出來的數據就是冗余數據,能被其他聯系推導(派生)出來的聯系就是冗余聯系。例如,員工實體同時具有“出生年月”和“年齡”屬性,“年齡”可以從“出生年月”中推導出來,因此是冗余數據。
冗余的存在容易破壞數據的完整性,造成數據庫的維護困難,應予以消除。可以利用多種方法來消除冗余,在關系型數據庫中更常用規范化理論來進行分析。
4 邏輯設計
概念設計階段得到的 E-R 模型是針對用戶的概念模型,它獨立于具體的 DBMS,而邏輯設計階段的主要任務就是將其轉化為具體 DBMS 所支持的數據模型。
這里以關系型數據庫模型進行討論,其邏輯結構設計階段主要分為:將 E-R 圖轉化為關系數據模型、關系模式的規范化和優化。
4.1 將 E-R 圖轉化為關系數據模型
數據關系模型是一組關系模式的集合,將 E-R 圖轉化為關系數據模型實際上是要將實體、屬性和聯系轉化為關系模式。一般有如下轉化原則。
(1)轉化實體
一個實體轉化為一個關系模式,實體屬性就是關系屬性,實體的碼(主鍵)就是關系的碼。
例如,一個職工的關系模式為“職工(職工號、姓名、性別、年齡、職稱、部門)”。
(2)轉化弱實體
如果存在弱實體,則一個弱實體轉化為一個關系模式,并以其依賴的強實體的碼作為該關系的碼。
例如,職工的家屬是弱實體,則可轉化成關系模式:家屬(職工號,家屬名,家屬關系)。
(3)轉化匯集層次
對于匯集層次,將基數為1的成份實體的鍵加入到其父實體中作為外部鍵,將父實體的鍵加入到基數為M的成份實體中,作為其外部鍵。
(4)轉化泛化層次
對于泛化層次,將每個超類的鍵作為其子類的鍵和外部鍵。
(5)轉化多值屬性
如果存在多值屬性,則多值屬性要轉化成一個獨立的關系,并以其實體的碼作為該關系的碼。
例如,職工的聯系方式是個多值屬性,那么可以轉化成“職工聯系方式(職工號,聯系方式)”。
(6)轉化聯系
一個 1:1 聯系 可以轉化為一個獨立的關系模式,但更常用的是把聯系與任意一端對應的關系模式合并。
如果轉化為一個獨立的關系模式,則與該聯系相連的各實體的碼以及聯系本身的屬性均轉化為關系的屬性,每個實體的碼均是該關系的候選碼。
如果把聯系與一端實體的關系模式合并,具體選擇哪一端需要根據應用環境確定,但應以盡量減少連接操作為目標。
例如,一個負責人管理一個部門:
一個 1:n 聯系 可以轉化為一個獨立的關系模式,但更常用的是把聯系與 n 端對應的關系模式合并。
如果轉化為一個獨立關系模式,則與該聯系相連的各實體的碼以及聯系本身的屬性均轉化為關系的屬性,而關系的碼為 n 端實體的碼。
在實際應用中比較常用的轉化方式是把聯系與 n 端實體的關系模式合并。例如,對于一個部門由多個員工組成:
可以轉化為關系模式:部門(部門號,部門名稱)、員工(工號,姓名,性別,部門號)。
一個 m:n 聯系 轉化為一個獨立的關系模式,與該聯系相連的各實體的碼以及聯系本身的屬性均轉換為關系的屬性,關系的碼為各實體碼的組合。
例如學生選課操作:
選課聯系可以轉化為模式:選課(學號,課程號,課程成績),其中的課程成績是聯系中帶的屬性。
4.2 關系模式的規范化
通常情況下,數據庫邏輯設計的結果(關系模式)并不唯一,為了進一步減少關系模式中的存在的異常、提高應用系統的性能,規范化理論是重要理論基礎和有力工具。
4.2.1 搞清楚什么是函數依賴
在進行下面內容之前,我們先來看如下 3 種函數依賴的概念。我們假設:R(U) 是屬性集 U 上的一個關系模式,X、Y 是 U 的子集。
函數依賴:用 X→Y 表示,稱為“X 決定 Y”或者稱為“Y 函數依賴于 X”。例如:{工號} → {職工姓名}。
完全函數依賴:如果“Y 函數依賴于 X”,且對于 X 的任一真子集 X’,都不能決定 Y,那么稱“Y 完全函數依賴于 X”。例如:(學號,課程號,成績)關系模式中,存在函數依賴 {學號,課程號} → 成績,并且 {學號,課程號} 的任意真子集,都不能決定成績,所以這個函數依賴即為完全函數依賴。
傳遞函數依賴:如果X→Z,Z→Y,且 Z 不包含 X,那么稱“Y 傳遞函數依賴于 X”。假設有關系模式:(學號,學生姓名,班級,班主任),由學號可以得到學生所在班級,而又班級又可得到班主任,反之則不成立,所以此模式中存在傳遞函數依賴:{學號} → {班主任}。
4.2.2 學會求解候選碼
如果要對關系模式進行規范化處理,那么我們首先必須要明確什么是候選碼、主屬性、非主屬性等概念。又因為根據定義,屬于候選碼的屬性就是主屬性,不屬于候選碼的屬性就是非主屬性,所以最重要的一點就是學會求解關系模式中的候選碼。
設有關系模式 R<U, F>,U 是組成該關系的屬性名的集合,F 是屬性間函數依賴關系的集合。
現在假設有:R<U, F>,且 U = {A, B, C , D , E}; F = {A→B , AC→D , CD→E , E→C},來求解此關系模式的候選碼。
由上述信息可得出:UL = {A}, UR = {B}, UB ={C, D, E}。
其中 UL 表示僅在函數依賴集 F 中各依賴關系式左邊出現的屬性的集合,若 UL 非空,則 UL 中的任一屬性必定包含在關系模式 R 的候選碼中;UR 表示僅在函數依賴集 F 中各依賴關系式右邊出現的屬性的集合,若 UR 非空,則 UR 中的任一屬性必定不包含在關系模式 R 的任一個候選碼中;UB = U -UL - UR ,它表示在依賴關系式左右兩邊都出現的屬性的集合。
結合本例,A 屬性只出現在依賴關系的左側,所以它一定包含在候選碼中,而 B 屬性只出現在依賴關系的右側,所以它一定不包含在候選碼中,其余的為左右兩側都有出現,所以它們可能包含在候選碼中也可能不包含在候選碼中。所以我們還要繼續如下步驟。
如果 UL+ = U,即 UL 的閉包是該關系模式的整個屬性集合,那么 UL 就為關系模式 R 唯一的候選碼,而如果 UL+ ≠ U,那就要將 UL 依次與 UB 中的屬性組合進行閉包求解了。
我們還是依照本例,UL = {A},則 UL+ = {A, B},即由屬性 A 并根據 F 中的依賴關系只能推導出來屬性 B(因為 F 中存在 A→B),所以此閉包結果為 {A, B} ≠ U(閉包運算其實就是由當前元素可以推導出的元素總集合),所以此時還需要 UL 中的元素與 UB 中的元素依次組合再繼續求解,如下:
(AC)+ = {A, B, C, D, E} = U,所以 AC 為此關系模式的一個候選碼,從而 ACD,ACE,ACDE 都不為候選碼(為什么求解出來了 AC 后,就確定后面這幾個不是候選碼了?這還要死摳候選碼的定義,見 1.2 內容)
(AD)+ = {A,B,D} ≠ U,所以 AD 不為候選碼;
(AE)+ = {ABCDE} = U,所以 AE 為候選碼,從而 ADE 不為候選碼。
算法結束,所以當前關系模式的候選碼為 AC 和 AE,那么主屬性就為 A、C、E,非主屬性為 B、D。
求解到了候選碼、主屬性和非主屬性,就可以利用下面規范化理論的步驟,消除非主屬性對碼的不同函數依賴(主要是拆分模式),以此來達到不同的范式層次。
4.2.3 規范化理論
通常把關系數據庫的規范化過程中為不同程度的規范化要求設立的不同標準稱為范式。根據關系模式滿足的不同性質和規范化的程度,把關系模式分為 1NF(第一范式)、2NF、3NF、BCNF、4NF 和 5NF,它們是層層遞進的關系,通常把模式 R 的第 n 范式簡記為:R∈nNF。
經過上述函數依賴概念的了解以及學會候選碼的求解之后,我們就可以根據范式的定義來對模式進行規范化處理:
第一范式 :如果關系模式 R 的所有屬性均為簡單屬性,即每個屬性都是不可再分(原子性)的,則稱R屬于第一范式,記作 R∈1NF。
第二范式 :如果關系模式 R∈1NF,且每個非主屬性都完全函數依賴于 R 的碼,則稱 R 屬于第二范式,記作 R∈2NF。
第三范式 :如果關系模式 R∈2NF,且每個非主屬性都不傳遞函數依賴于 R 的候選碼,則稱 R 屬于第三范式,記作 R 屬于 3NF。
BC 范式 :如果關系模式 R∈1NF,且對于所有的函數依賴 X→Y(Y ? X),決定因素 X 都包含了 R 的一個候選碼,則稱 R 屬于 BC 范式,記作 R∈BCNF。
如上幾種范式的遞進過程如下圖所示。
4.3 關系模式的優化
為了提高數據庫應用系統的性能,需要對關系模式進行修改、調整,通常采用合并與分解兩種方法。
(1)合并
合并多個關系模式的主要是減小連接操作而提高查詢效率。它一般的應用場景為多個關系模式具有相同的主鍵,并且這些關系模式主要處理多關系的查詢操作。
(2)分解
為了提高數據操作效率和存儲空間的利用率,可以對關系模式進行水平分解和垂直分解。
水平分解:把關系模式按照分類查詢的條件分解成幾個關系模式,這樣可以減少應用系統每次查詢需要訪問的記錄數,從而提高效率。
例如,某大學學生數據庫存在關系模式:學生(學號,姓名,年齡,籍貫),但是事實情況是多數查詢一次僅涉及其中一類學生,則可以把學生按類別進行水平分割:本科生(…);碩士生(…);博士生(…)。
垂直分解:把關系模式R的屬性分解為若干子集合,形成若干子關系模式。
例如,職工情況的關系模式:職工(職工編號,姓名,性別,年齡,職務,工資,工齡,住址,電話),但事實情況是經常查詢前六項,較少使用后三項,則可以把此關系模式垂直分解:職工信息1(職工編號,姓名,性別,年齡,職務,工資),職工信息2(職工編號,工齡,住址,電話)。
同時存在經常查詢和非經常查詢的屬性,均可采用垂直分割的方法。其優點是減少數據傳遞量,提高查詢速度。
5 物理設計
數據庫在物理設備上的存儲結構與存取方法稱為數據庫的物理結構,它依賴于給定的計算機系統。
數據庫物理設計一般包含兩個步驟:確定數據庫的物理結構(存取方法和存儲結構)、對物理結構進行評價(時間和空間效率)。
(1)確定數據庫物理結構
① 確定數據的存儲結構和存放位置
包括確定:
- 關系、索引、聚簇、日志、備份等;
- 考慮因素:存取時間、存儲空間利用率和維護代價。
根據應用情況將易變部分與穩定部分、存取頻率較高部分與存取頻率較低部分分開存放,以提高系統性能。
② 設計合適的存取路徑;
③ 確定系統配置,DBMS產品一般都提供了一些系統配置變量和存儲分配參數。
(2) 評價物理結構
① 評價內容
對數據庫物理設計過程中產生的多種方案的時間效率、空間效率、維護代價和各種用戶需求進行細致的評價,從中選擇一個較優的方案作為數據庫的物理結構。
② 評價方法
定量估算各種方案的存儲空間、存取時間以及維護代價,對估算結果進行權衡、比較,選擇出一個較優的合理的物理結構,如果該結構不符合用戶需求,則需要修改設計。
6 數據庫實現
數據庫的邏輯和物理結構設計好以后,就要在實際的計算機系統中建立數據庫并試運行了,這個階段的主要工作有如下幾點。
7 數據庫運行和維護
數據庫經過試運行后,如果符合系統設計的目標,就可以正式投入運行了。在數據庫運行過程中,應用環境、數據庫的物理存儲等會不斷發生變化,這時應由 DBA 不斷地對數據庫設計進行評價、調整、修改,概括起來,數據庫維護工作包括以下內容。
(1)數據庫的轉儲和恢復
轉儲和恢復是系統正式運行后最重要的維護工作之一。DBA 要針對不同的應用要求制定不同的轉儲計劃,定期對數據庫和日志文件進行備份。一旦發生介質故障,即利用數據庫備份及日志文件備份,盡快將數據庫恢復到某種一致性狀態。
(2)數據庫的安全性、完整性控制
DBA 必須根據用戶的實際需要授予不同的操作權限。在數據庫運行過程中,由于應用環境的變化,對安全性的要求也會發生變化,DBA 需要根據實際情況修改原有的安全性控制。
由于應用環境的變化,數據庫的完整性約束條件也會變化,需要 DBA 不斷修正,以滿足用戶要求。
(3)數據庫性能的監督、分析和改進
在數據庫運行過程中, DBA 必須監督系統運行,對監測數據進行分析,找出改進系統性能的方法。
利用監測工具獲取系統運行過程中一系列性能參數的值,通過仔細分析這些數據,判斷當前系統是否處于最佳運行狀態,如果不是,則需要通過調整某些參數來進一步改進數據庫性能。
(4)數據庫的重組織和重構造
重組織的形式分為全部重組織和部分重組織(只對頻繁增、刪的表進行重組織),它指按原設計要求重新安排存儲位置、回收垃圾、減少指針鏈等,以提高系統性能,但其不會修改原設計的邏輯和物理結構。
重構造主要指部分重構造(若變化太大,重構無用),它的主要工作是根據新環境調整數據庫的模式和內模式,比如:增加新的數據項、改變數據項的類型、改變數據庫的容量、增加或刪除索引、修改完整性約束條件。重構造的實質是修改數據庫的部分模式和內模式。
8 總結
本文主要總結了數據庫設計的階段步驟及關系型數據庫的部分重要概念,重點總結論述了概念設計和邏輯設計兩大核心階段,著重強調了 E-R 模型的構造,除此之外還補充了關系模式的規范化及如何求解關系模式的候選碼等重要知識點。
通過本文,首先需要做到的是明確數據庫中相關術語或概念的具體含義,比如實體型、關系、關系模式等;其次需要掌握相關的設計策略與理論,比如自底向上分析、規范化理論等;最終,需要通過不斷的實操練習,把理論知識運用的實際應用中。
巨人的肩膀
1. 雷景生, 葉文珺, 樓越煥. 數據庫原理及應用[M]. 北京:清華大學出版社, 2015.
2. 張永, 顧國慶. 關系模式中候選碼的求解[J], 上海電力大學學報, 2002.3, 18(1): 38-40
作者信息
大家好,我是 CoderGeshu,一個熱愛生活的程序員,如果這篇文章對您有所幫助,別忘了點贊收藏哦 👍👍👍
另外,歡迎大家點擊關注👉CoderGeshu,可以第一時間獲取最新分享喲~
總結
以上是生活随笔為你收集整理的为了彻底搞清楚数据库 E-R 模型设计,我肝了这篇万字长文的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: oracle 按时间每五分钟分割,Ora
- 下一篇: linux环境下,实现公共聊天室功能