1. 程式人生 > 其它 >關係資料庫設計

關係資料庫設計

好的關係設計

上一篇筆記記錄了由ER圖直接生成關係模式的過程,生成的關係模式完全依賴ER圖的質量,如果ER圖質量夠高,有可能直接生成還不錯的關係模式。

在關係設計中,還有其它的一些設計關係模式的方法。

設計選擇:更大的模式

假設我們將instructordepartment兩個模式組合,使用inst_dept來代替它,inst_dept模式如下

\[inst\_dept (ID, name, salary, dept\_name, building, budget) \]

顯然inst_dept試圖把教員和系的資訊儲存在一個關係模式中,這樣做的好處就是我們在查詢時可以使用更少的連線,通常查詢效率會更高。但是這會造成很多冗餘,比如多個相同系的教師,它們的系名、樓名和預算在這個設計出來的表中要重複多次,而且當我們修改時,很有可能由於疏忽造成資料不一致的問題,比如兩個相同系的教師但它們的系預算budget欄位不同。

很多查詢頻率遠遠大於修改更新的系統允許一部分的冗餘資料,尤其是現在這個需要短時間處理大量請求的時代,但是採用這種冗餘還需要注意的一點是我們沒法表示一個新系,除非這個新系有了一個教師。

設計選擇:更小的模式

假設現在我們設計出了inst_dept關係模式,我們可以將它們分解成原來的instructordepartment關係模式的情況,並通過在instructor中儲存department的主碼作為外碼來表示兩個關係模式之間的連線。

問題是我們如何發現我們的關係模式中可以繼續做這種分解,當我們的關係模式中有一個非主碼,比如inst_dept中的dept_name,它能唯一確定該關係模式中的另幾個值,比如dept_name

能夠唯一確定budget(只要inst_dept中的任意兩個元組的dept_name屬性相同,那麼它們的budget屬性一定也相同),那麼dept_name能夠單獨拿出來作為它能唯一確定的那些屬性的主碼。

dept_namebudget舉例,就是如果存在模式(dept_name, budget),則dept_name可以作為主碼,這個規則就叫函式依賴(functional dependency),記作:

\[dept\_name \to budget \]

原子域和第一正規化

正規化(normal form),你一看英文名就明白了,就是給出我們定義關係模式的一般形式,我們可以遵循這些形式去定義關係模式。

在說正規化之前,先說,正規化是一些好的關係設計模式,但也不完全絕對,現在為了獲得更高的查詢效率而做反正規化設計很常見。

原子域就是我們的域不可再分,ER模型中允許多值屬性和組合屬性,而這些屬性都不叫原子域。如果一個關係模式R的所有屬性都是原子的,那麼關係模式R符合第一正規化(1NF)。

一個例子:

假設一個機構給僱員的編號形如所在崗位+編號的形式,比如CS1101EE2018那麼這個編號就不是原子的。

非原子域帶來的壞處就是僱員所在崗位需要應用層自行設計演算法通過編號來解析,而且一個僱員如果更換崗位了,那麼它的編號還有所有引用到它編號的位置都要更改。

但如果該資料庫系統只是這樣編碼編號,並沒有單純通過編號來表示崗位,而是通過一個其它的欄位,比如sec_id來表示員工所在崗位,那麼這也不算非原子域。

所以是否是非原子域只看資料庫系統有沒有依賴一個屬性來表示多個值。

我們的大學資料庫系統中雖然採用CS-101這種字串為課程編號,但它仍保留了表示所在系的屬性dept_name,所以我們的大學關係模式設計符合第一正規化。

使用函式依賴進行分解

符號

  • \(R\)代表一個關係的屬性集
  • \(r(R)\)代表關係\(r\)的關係模式,\(R\)\(r\)的全部屬性,當我們不關心關係的名字時,也會只用\(R\)代表一個關係。
  • \(K\)表示超碼,經常看到\(K\)\(r(R)\)的超碼這種表述

用這些符號重新說明超碼的概念

如果\(R\)的子集\(K\)\(r(R)\)的超碼,那麼對於\(r\)中的任意兩個元組\(t_1\neq t_2\),都滿足\(t_1[K] \neq t_2[K]\)

就是說在一個關係中不可能存在兩個元組在屬性集K上完全相同,稱K為\(r(R)\)的超碼。

函式依賴

我們再用上面的符號重新說明函式依賴

函式依賴能夠確定一個關係中一些屬性對另一些屬性的約束,比如一個系(dept_name)只能有一個預算值(budget)

考慮\(r(R),\alpha \subseteq R, \subseteq R\)

  1. \(\alpha \to \beta\)的條件是:對於\(r(R)\)的關係例項中的所有元組對\(t_1,t_2\),若\(t_1[\alpha] = t_2[\alpha]\),則\(t_1[\beta] = t_2[\beta]\)
  2. 如果\(r(R)\)中的每個合法例項都滿足函式依賴\(\alpha \to \beta\),那麼稱該函式依賴在\(r(R)\)成立(hold)

使用函式依賴來表達超碼的概念,則是:若函式依賴\(K\to R\)\(r(R)\)上成立,那麼\(K\)\(r(R)\)的超碼。

一個函式依賴是平凡的,因為它們在所有關係中都滿足,比如\(\alpha \to \alpha\)在所有具有屬性\(\alpha\)的關係中都滿足,再比如\(\alpha\beta \to \alpha\)。一般地說,\(A\to B\)是平凡的,如果\(B\subseteq A\)

需要注意到的是,在現實情況中,一個關係例項可能滿足函式依賴,但在關係模式的定義上不滿足。

比如下圖,\(room\_number \to capacity\)沒什麼問題,但是現實情況是可能不在同一個建築的房間,它們有相同的房間號,但它們能容納的人數不同,所以\(room\_number \to capacity\)不一定成立,而\(building, room\_number \to capacity\)則成立。

如果有\(r(A,B,C)\)\(A\to B\)\(r\)上成立,\(B\to C\)\(r\)上成立,那麼\(A\to C\)\(r\)上也一定成立,因為\(A\)唯一約束\(B\)\(B\)唯一約束\(C\),所以\(A\)也能夠唯一約束\(C\)

Boyce-Codd 正規化

Boyce-Codd正規化(BCNF)能夠消除所有基於函式依賴能夠發現的冗餘。

BCNF規定,具有函式依賴集\(F\)的關係模式\(R\),對\(F\)中所有的函式依賴\(\alpha \to \beta\)\(\alpha, \beta\)都包含於\(R\),那麼下面至少有一項成立:

  1. \(\alpha \to \beta\)是平凡函式依賴
  2. \(\alpha\)是模式\(R\)的一個超碼

一個數據庫設計符合BCNF的條件是構成該設計的關係模式集中的每一個模式都屬於BCNF。

比如如下關係模式不屬於BCNF正規化

\[inst\_dept (ID, name, salary, dept\_name, building, budget) \]

因為\(dept\_name \to budget\)\(inst\_dept\)上成立且\(dept\_name\)不是超碼。

將一個不屬於BCNF正規化的關係模式分解稱屬於BCNF的關係模式分為兩步。

假設\(R\)是不屬於BCNF的一個模式,則至少存在一個非平凡函式依賴\(\alpha \to \beta\)\(\alpha\)不是R的超碼,那麼我們可以將R分解成如下兩個模式:

  1. \((\alpha \cup \beta)\)
  2. \((R-(\beta - \alpha))\)

比如\(inst\_dept\)的例子,\(\alpha=\left \{ dept\_name \right \}\)\(\beta = \left \{building, budget\right \}\)

  1. \((\alpha \cup \beta) = (dept\_name, building, budget)\)
  2. \((R-(\beta - \alpha)) = (ID, name, dept\_name, salary)\)

在該例子中,\(\beta - \alpha\)的作用沒有體現,當一個函式依賴兩面出現相同的屬性時這個就有作用了,可以嘗試自己構造一個。

分解後的模式可能產生一個或多個不屬於BCNF正規化的模式,應繼續分解。

保持依賴

在BCNF正規化下,如果系統的需求更改,那麼函式依賴可能得不到保持。

比如一個學生可以有多位導師,但在指定的系只能有一位,可以用如下符合BCNF的關係模式表示

\[dept\_advisor (s\_ID, i\_ID, dept\_name) \]

上面的關係模式中\(s\_ID, i\_ID \to dept\_name\)

如果現在我們有了附加約束,一位教師只能在一個系擔任導師,那麼上面的關係模式就不符合BCNF了,因為

\[i\_ID \to dept\_name \\ s\_ID, dept\_name \to i\_ID \]

函式依賴左邊的都不是平凡依賴且它們都不是超碼,所以要對dept_advisor進行分解,根據BCNF分解規則,得到如下兩個關係

\[(s\_ID, i\_ID)\\ (i\_ID, dept\_name) \]

這種修改了需求就需要重新計算函式依賴並更新關係模式的設計稱為不是保持依賴(dependency preserving)的,我們需要一種比BCNF更弱的正規化來保持依賴,這個正規化就是第三正規化(3NF)。

第三正規化

第三正規化(third normal form, 3NF)規定,具有函式依賴集\(F\)的關係模式\(R\),對\(F\)中所有的函式依賴\(\alpha \to \beta\)\(\alpha, \beta\)都包含於\(R\),那麼下面至少有一項成立:

  1. \(\alpha \to \beta\)是平凡函式依賴
  2. \(\alpha\)是模式\(R\)的一個超碼
  3. \(\beta - \alpha\)中的每個屬性A都包含於R的一個候選碼中

候選碼即最小的超碼,候選碼是任何真子集都不是超碼的超碼。

第三正規化通過附加的條件3放款了BCNF的限制,任何符合BCNF的設計都符合3NF。

還是上面的例子。

\[i\_ID \to dept\_name \\ s\_ID, dept\_name \to i\_ID \]

這時顯然對於第三正規化的前兩條約束,也就是BCNF的約束都不滿足,但是\(dept\_name - i\_ID = dept\_name\),而\(s\_ID, dept\_name\)又構成了\(dept\_advisor\)的一個候選碼,所以滿足3NF的第三條約束。

未完...