5、数据库设计的三大范式
為了建立冗余較小、結(jié)構(gòu)合理的數(shù)據(jù)庫,設(shè)計數(shù)據(jù)庫時必須遵循一定的規(guī)則。在關(guān)系型數(shù)據(jù)庫中,這種規(guī)則就是范式。范式是符合某一種級別的關(guān)系模式的集合。關(guān)系型數(shù)據(jù)庫中的關(guān)系必須滿足一定的要求,即滿足不同的范式。
目前關(guān)系型數(shù)據(jù)庫有六種范式,分別為:
第一范式(1NF)、
第二范式(2NF)、
第三范式(3NF)、
第四范式(4NF)、
第五范式(5NF)、
第六范式(6NF)。
要求最低的范式是第一范式。第二范式在第一范式的基礎(chǔ)上又進(jìn)一步的添加了要求,其余范式依次類推。
一般說來,數(shù)據(jù)庫只需滿足第三范式就行了,而通常我們用的最多的就是第一范式、第二范式、第三范式,也就是接下來要講的“三大范式”。
1)第一范式
第一范式(1NF)用來確保每列的原子性,要求每列(或者每個屬性值)都是不可再分的最小數(shù)據(jù)單元(也稱為最小的原子單元)。
例如,客人住宿信息表 (姓名, 客人編號, 地址, 客房號, 客房描述, 客房類型, 客房狀態(tài), 床位數(shù), 入住人數(shù), 價格)。
其中,“地址”列還可以細(xì)分為國家、省、市、區(qū)等,甚至有的程序還把“姓名”列也拆分為“姓”和“名”等。如果業(yè)務(wù)需求中不需要拆分“地址”和“姓名”列,則該數(shù)據(jù)表符合第一范式,如果需要將“地址”列拆分,則下列寫法符合第一范式:
客人住宿信息表(姓名, 客人編號, 國家, 省, 市, 區(qū), 門牌號, 客房號, 客房描述, 客房類型, 客房狀態(tài), 床位數(shù), 入住人數(shù), 價格)。
2)第二范式
第二范式(2NF)在第一范式的基礎(chǔ)上更進(jìn)一層,要求表中的每列都和主鍵相關(guān),即要求實體的唯一性。如果一個表滿足第一范式,并且除了主鍵以外的其他列全部都依賴于該主鍵,那么該表滿足第二范式。
客人住宿信息表中的數(shù)據(jù)主要用來描述客人住宿信息,所以該表主鍵為(客人編號,客房號):
- “姓名”列、“地址”列?“客人編號”列。
- “客房描述”列、 “客房類型”列、“客房狀態(tài)”列、“床位數(shù)”列、“入住人數(shù)”列、“價格”列?“客房號”列。
其中,“?”符號代表依賴。以上各列沒有全部依賴于主鍵(客人編號,客房號),只是部分依賴于主鍵,不符合第二范式。
使用第二范式后,客人住宿信息表可以分解成以下兩個表:
- 客人信息表(客人編號,姓名,地址,客房號,入住時間,結(jié)賬日期,押金,總金額),主鍵為“客人編號”列,其他列都全部依賴于主鍵列。
- 客房信息表(客房號,客房描述,客房類型,客房狀態(tài),床位數(shù),入住人數(shù),價格),主鍵為“客房號”列,其他列都全部依賴于主鍵列。
3)第三范式
第三范式(3NF)在第二范式的基礎(chǔ)上更進(jìn)一層,第三范式是確保每列都和主鍵列直接相關(guān),而不是間接相關(guān),即限制列的冗余性。如果一個關(guān)系滿足第二范式,并且除了主鍵以外的其他列都依賴于主鍵列,列和列之間不存在相互依賴關(guān)系,則滿足第三范式。
為了更好的理解第三范式,這里我們需要了解傳遞依賴。假設(shè)A、B 和 C 是關(guān)系 R 的三個屬性,如果 A?B 且 B?C,則從這些函數(shù)依賴中,可以得出 A?C。如上所述,依賴 A?C 稱之為傳遞依賴。
以第二范式中的客房信息表為例,初看該表時沒有問題,滿足第三范式,每列都和主鍵列“客房號”相關(guān),再細(xì)看會發(fā)現(xiàn):
- "床位數(shù)” 列、“價格”列?“客房類型”列。
- “客房類型”列?“客房號”列。
- “床位數(shù)”列、“價格”列?“客房號”列
為了滿足第三范式,應(yīng)該去掉“床位數(shù)”列,“價格”列和“客房類型”列,將客房信息表分解為如下兩個表。
- 客房表(客房號,客房描述,客房類型編號,客房狀態(tài),入住人數(shù))
- 客房類型表(客房類型編號,客房類型名稱,床位數(shù),價格)
主鍵與外鍵在多表中的重復(fù)出現(xiàn)不屬于數(shù)據(jù)冗余,非鍵字段的重復(fù)出現(xiàn)才是數(shù)據(jù)冗余。在客房表中客房狀態(tài)存在冗余,需要進(jìn)行規(guī)范化,規(guī)范化以后的表如下:
- 客房表(客房號,客房描述,客房類型編號,客房狀態(tài)編號,入住人數(shù))。
- 客房狀態(tài)表(客房狀態(tài)編號,客房狀態(tài)名稱)
最后,滿足三大范式的 E-R 圖如下所示:
滿足三大范式的數(shù)據(jù)庫模型圖如下所示:
4)反范式化
不滿足范式的數(shù)據(jù)庫設(shè)計,就是反范式化。
我們需要知道對于項目的最終用戶來說,用戶關(guān)心的是方便,清晰的數(shù)據(jù)結(jié)果。所以在設(shè)計數(shù)據(jù)庫時,設(shè)計人員和客戶在數(shù)據(jù)庫的設(shè)計規(guī)范化和性能之間會有一定的矛盾。
上面我們通過三大范式將客房表分解出兩個表,為了滿足客戶的需求,最終可能需要通過三個或四個表之間的連接查詢,來得到客戶需要的數(shù)據(jù)結(jié)果,插入數(shù)據(jù)同樣如此,對于客戶輸入的數(shù)據(jù),我們需要分開插入到三個或四個不同的表中。
由此可以看出,為了滿足三大范式,我們的數(shù)據(jù)操作性能會受到相應(yīng)的影響。
所以,在實際的數(shù)據(jù)庫設(shè)計中,既要考慮三大范式,避免數(shù)據(jù)的冗余和各種數(shù)據(jù)操作異常,又要考慮數(shù)據(jù)訪問性能。為了減少表連接,提高數(shù)據(jù)庫的訪問性能,也可以允許適當(dāng)?shù)臄?shù)據(jù)冗余列,這也許就是最合適的數(shù)據(jù)庫設(shè)計方案。
比如,有一張存放商品的基本表,數(shù)據(jù)表中包括“單價”、“數(shù)量”“金額”等字段。“金額”這個字段就說明該表的設(shè)計不滿足第三范式,因為“金額”可以由“單價”乘以“數(shù)量”得到,說明“金額”是冗余字段。
與第三范式中介紹的冗余相比,前面介紹的冗余屬于低級冗余,我們反對低級冗余,但這里的冗余為高級冗余,目的是提高數(shù)據(jù)的處理速度,增加“金額”列后,可以提高查詢統(tǒng)計的速度,這是以空間換取時間的做法。
注意:不要輕易違反數(shù)據(jù)庫設(shè)計的規(guī)范化原則,如果處理不好,可能會適得其反,使應(yīng)用程序運行速度更慢。
優(yōu)缺點
最后我們來總結(jié)一下范式化和反范式化的優(yōu)缺點。
1)范式化
優(yōu)點如下:
- 減少數(shù)據(jù)冗余
- 范式化后的表中只有很少的重復(fù)數(shù)據(jù),更新時只需要更新較少的數(shù)據(jù),所以范式化的更新操作比反范式化更快
- 范式化的表通常比反范式化更小
缺點如下:
- 范式化的表在查詢時經(jīng)常需要很多的關(guān)聯(lián),這回導(dǎo)致性能降低
- 增加了索引優(yōu)化的難度
2)反范式化
優(yōu)點如下:
- 可以減少表的關(guān)聯(lián)
- 可以更好的進(jìn)行索引優(yōu)化
缺點如下:
- 數(shù)據(jù)表存在數(shù)據(jù)冗余及數(shù)據(jù)維護(hù)異常
- 對數(shù)據(jù)的修改需要更多的成本
總結(jié)
以上是生活随笔為你收集整理的5、数据库设计的三大范式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 3、绘制E-R图:数据库概要设计阶段
- 下一篇: 6、数据库设计为什么要使用三大范式