文章目錄
一,第一範式
如果某個域中元素被認爲是不可分的,則這個域稱爲是原子的
- 非原子域的例子:
---- 複合屬性:名字集合
---- 多值屬性:電話號碼
---- 複合數據類型:面向對象的
如果關係模式R中的所有屬性的域是原子的,則R稱爲屬於第一範式(1NF)
非原子值存儲複雜並易導致數據冗餘
- 我們假定所有關係都屬於第一範式
如何處理非原子值
- 對於組合屬性:讓每個子屬性本身稱爲一個屬性
- 對於多值屬性:爲多值集合中的每個項創建一條元組
原子性實際上是由域元素在數據庫中被使用決定的
- 例,字符串通常是被認爲是不可分割的
- 假設學生被分配這樣的標識號:CS0012或EE1127,如果前兩個數字表示系所,後四位表示學生在該系所內的唯一號碼,則這樣的標識號不是原子的
- 當採用這種標識號時,是可取的。因爲這需要額外的編程,而且信息是在應用程序中,而不是在數據庫中編碼。
二,關係數據庫設計中易犯的錯誤
關係數據庫設計要求我們找到一個“好的”關係模式集合。一個壞的設計可能導致:
- 數據冗餘
- 插入、刪除、修改異常
假設我們用以下模式代替instructor模式
和department模式
:
inst_dept(ID, name, salary, dept_name, building, budget)
2.1 數據冗餘
每個系的dept_name
,building
,budget
數據都要重複一次
缺點:浪費空間,可能會導致不一致問題
2.2 插入、刪除、修改異常
更新異常
- 更新複雜,容易導致不問題。
- 例修改
dept_name
,很多相關元組都需要修改。
插入/刪除異常
- 使用空值
null
:存儲一個不知道所在系所的教師信息,可以使用空值表示dept_name
,building
,budget
數據,但是空值難以處理。
三,模式分解(I)
例,可以將關係模式(A,B,C,D)分解爲:(A,B)和(B,C,D),或(A,C,D)和(A,B,D),或(A,B),(B,C)和(C,D)等等…
例,將關係模式inst_dept
分解爲:
instructor(ID, name, dept_name, salary)
department(dept_name, building, budget)
原模式(R)的所有屬性都必須出現在分解後的(R1,R2)中:R = R1 ∪ R2
無損連接分解
- 對關係模式R上的所有可能的關係r
目標:設計一個理論
- 以判斷關係模式R是否爲“好的”形式(不冗餘)
- 當R不是“好的”形式時,將它分解爲模式集合{ R1,R2,…,Rn }使得:
---- 每個關係模式都是“好的”形式
---- 分解是無損鏈接分解 - 我們的理論基於:
---- 函數依賴(function dependencies)
---- 多值依賴(multivalue dependencies)
四,函數依賴(FD)
4.1 什麼是函數依賴
設R是一個關係模式,且有屬性集 α包含於R,β包含於R
在R上成立當且僅當對任意合法關係r(R)
,若r的任意兩條元組t1和t2在屬性集α上的值相同,則它們的屬性集β上的值也相同。
- 即:t1[α] = t2[α] → t2[β] = t2[β]
- 稱:β函數依賴於α,α函數決定β
- 如下圖,圖中的α和β滿足函數依賴關係
函數依賴:一種完整性約束,表示特定的屬性值之間的關係,可以用來判斷模式規範化和建議還進
- 函數依賴是碼概念的推廣
- K是關係模式R的超碼,當且僅當 K → R
- K是R的候選碼當且僅當
---- K → R,並且
---- 沒有 α 包含於 K,使 α → R(不存在K的真子集α,使之滿足 α → R)
函數依賴使我們可以表達用超碼無法表達的約束,考慮模式
inst_dept(ID, name, salary, dept_name, building, budget)
- 我們希望下列函數依賴成立:
---- dept_name → building
---- ID → building(碼是一個比較特殊的FD,可以函數決定所有的屬性) - 而不希望下列函數依賴成立:
---- dept_name → salary
4.2 函數依賴的使用
若果在關係模式R上所有合法關係都滿足F,則稱F在R上成立。
- 其中 R = { r1®,r2®,… }
注:容易判斷一個r是否滿足給定的F。不易判斷F是否在R上成立。不能僅由某個r推斷出F。R上的函數依賴F,通常由定義R的語義決定。
被所有的關係實例所滿足的函數依賴稱爲平凡的
- 例,A → A,AB → A,(ID,name)→ ID,ID → ID
- 一般的,若β包含於α,則α → β是平凡的。即,
平凡的函數依賴:若β包含於α,α → β。
非平凡的函數依賴:若β不包含於α,α → β。
4.3 函數依賴集的閉包
Armstrong 公理
計算 F+
下列過程計算函數依賴集F的閉包:
F+ = F
repeat
for each F+中的函數依賴f
對應f應用'自反率'和'增補率',將結果函數依賴加入F+
for each F+中的一對函數依賴f1和f2
if f1和f2可以使用'傳遞性'結合起來,則將結果函數依賴加入F+
until F+不再變化
由於包含n個元素的集合含有2n子集,因此共有 2n * 2n個可能的函數依賴。
後邊會介紹完成此任務的另一過程。
五,屬性集的閉包
如何判斷集合α是否爲超碼
- 一種方法是:計算F+,在F+中找出所有的α → β,檢查{ β1β2β3 … } = R;
但這麼做開銷很大,因爲F+可能很大。 - 另一種方法是:計算α的閉包。
5.1 什麼是屬性集的閉包
定義:給定一個屬性集α,在函數依賴集F下由α函數確定的所有屬性的集爲F下α的閉包(記作α+)
- 檢查函數依賴α → β是否屬於F+ ↔ β包含於α+
- 判斷α是否爲超碼:α → β屬於F+ ↔ R包含於α+
計算α+的算法
result := a;
while(result有變化) do
for each β → γ in F do
begin
if β包含於result
then result := result ∪ γ
end
a+ := result
避免了找F+(反覆使用公理)的麻煩。
示例講解
最終,AG可以表示R中的所有屬性,則說AG是R的一個key。
5.2屬性閉包的用途
六,正則覆蓋
數據庫管理系統(DBMS)總是檢查確保數據庫更新不會破壞任何函數依賴。但如果F很大,其開銷就會很大。因此我們需要簡化函數依賴集
直觀地說,F的正則覆蓋(記作Fc)是指與F等價的“極小的”函數依賴集合
- Fc中任何函數依賴都不包含無關屬性
- Fc中函數依賴的左半部都是唯一的
- 例,α1 → β1,α1 → β2,可以寫爲α1 → β1β2
無關屬性
定義:考慮函數依賴集合F及其中的函數一來α → β
- 如果A∈α並且F邏輯蘊含F’ =(F - { α → β })∪ {(α → A )→ β},則稱A在α中是無關的
---- 例,給定F = { A → C,AB → C },其中B在AB → C中是無關的,因爲A → C邏輯蘊含了AB → C。 - 如果A∈β並且F’ =(F - { α → β })∪ { α →(α → A )}邏輯蘊含F,則稱A在β中是無關的
---- 例,給定F = { A → C,AB → CD },其中C在AB → CD中是無關的,因爲即使刪除C也能推出A → C。
檢測屬性是否無關
計算F的正則覆蓋
repeat
對F中的依賴利用'合併'規則
α1 → β1 和 α1 → β2 替換成 α1 → β1β2
找出含有無關屬性的函數依賴 α → β(在α或β中)
如果找到無關屬性,從α → β中刪除
until F不再變化
注:刪除某些無關屬性之後,可能導致合併規則可以使用,則必須重新應用。
七,模式分解(II)
規範化的目標
- 以判斷關係模式R是否爲“好的”形式(不冗餘,誤插入,刪除,更新異常)
- 當R不是“好的”形式時,將他分解成模式集合{ R1,R2,…,Rn }使得:
– 每個關係模式都是“好的”形式
– 分解是無損連接分解
– 分解是保持依賴的
分解應有的特性
八,總結
- 描述了原子域和第一範式假設;
- 給出了數據庫設計中易犯的錯誤,這些錯誤包括信息重複和插入、刪除、修改異常;
- 介紹了函數依賴的概念,展示瞭如何用函數依賴進行推導;
- 理解F+,α+,FC;
- 介紹瞭如何分解模式,一個有效的分解都必須是無損的;
- 如何分解是保持依賴的,則給定一個數據庫更新,所有的函數依賴都可以由單獨的關係進行驗證,無須計算分解後的關係鏈接。