開頭先講講概念
計算機相關專業(yè)科班出身的同學們肯定都學過數據庫原理,在數據庫原理中肯定會學關系代數,學到范式部分的時候,都會通過關系代數來解釋什么是范式。
估計大部分人學的時候理解了,過不了多久,這樣的概念用得不多自然也就忘了。
凡是跟數學有關的內容估計都會有種不明覺厲的感覺?
暫且不說關系代數,用一種不燒腦的方式再來看看范式吧。
進行范式化的目的:
去除冗余和提高靈活性!去除冗余和提高靈活性!去除冗余和提高靈活性!
那么問題來了什么是冗余,怎么去除冗余呢?
冗余(Redundancy)就是數據的重復,范式的目的是去除冗余,但,不是將重復的數據變成零,而是,通過關聯(lián)的方式,保留最少的關聯(lián)信息之后,將冗余降低到最少。
還有一個問題是如何提高靈活性?
在去除冗余的過程中,建立的關系,通過數據和數據之間進行關聯(lián)和設計的方法來提高靈活性。
范式有哪些?
理論上范式分為第一范式、第二范式、第三范式、BCNF范式、第四范式和第五范式。
這樣的理論就不具體說了,百度或者谷歌吧。
實際在數據模型設計的過程中,做到第三范式就OK了,記住這點就行。
具體講講各種范式
第一范式:解決冗余數據組(Repeating Group)
先看一組數據。

客戶編號是這張表的主鍵,保證每個客戶的唯一性。
興趣愛好的種類很多,每個人有很多個愛好,每個愛好都被放進了一個屬性里面。
如果某個人又多了一個愛好的話怎么辦?“再添加在現有愛好的后面,更新進去”?
現在興趣的數量少而且長度短,如果哪個人愛好特別多,并且說明的內容特別長,組合起來超過了這個屬性的長度了咋辦?又如何保證每個人同種興趣愛好只放一次呢?
從計算機處理和存儲的角度來看,會有很多問題。
怎么辦?

像圖里一樣,把一個屬性里只放一個興趣,每個屬性單獨再復制一份興趣愛好信息,這樣的話,100個屬性也不怕。
好吧,這樣做的話不用我說,也能看出問題吧?100個興趣愛好,同一個人的信息就得重復100遍。而且,客戶編號也無法保證數據的唯一性。
解決方案如圖:

把興趣愛好單獨放一張表里,每個人的信息也都放在一個表里,通過一張關系表,建立客戶和興趣愛好的關聯(lián)性,這樣是不是不但提高了靈活性,也解決了冗余問題?
在數據模型中形態(tài)的變化如下。

第二范式:解決部分依賴現象(Partial Dependency)
第二范式的前提是滿足第一范式并且表中存在組合鍵(兩個屬性組合起來,一起作為主鍵使用)。
部分依賴現象用一句話來說是:表中的非主鍵字段不僅全部依賴于主鍵,其中的一部分字段還依賴于組合主鍵中的一部分。
依賴的意思是指能夠被唯一識別。通過主鍵能夠唯一地識別每一行數據,也就可以說表中的非主鍵字段依賴于主鍵。
理論總結完了,看看數據吧。


客戶表里的主鍵是客戶編號,訂單表里面的主鍵是訂單編號和商品編號(一個訂單可以包含多個商品)。
好吧,客戶張三的編號是CUST0001,所以,可以看出來這三個商品都是張三買的,如果張三買了100個不同的商品的話,請問僅僅和這個訂單相關的信息(如購買數量,訂貨時間,訂貨人,當然實際上還有其他更多的屬性)是不是就得重復100遍?
再看看這張表的主鍵是訂單編號和商品編號,通過這兩個屬性就能保證表中每一行數據的唯一性,但是,商品名稱和商品描述其實并不需要同時依賴這兩個屬性,也就是說只要有商品編號這一個主鍵,就能保證商品名稱和商品描述這兩個屬性的唯一性。換句話說,其實產生數據冗余的原因也就是因為把兩張表合到了一張表。
相信到這一步理解的話,怎么解決也就明白了,拆拆拆~


這樣的結構,即使張三買一萬個商品,商品名稱和商品描述信息都不會冗余。
在數據模型中形態(tài)的變化如下。

第三范式:解決傳遞性函數依賴現象(Transitive Dependency)
第三范式的前提肯定是滿足前兩個范式,第二范式解決的是部分依賴問題,而第三范式要解決的叫傳遞依賴問題。


想想在學校里選課的場景,從表里能看出來,張三選了三門課,李四選了一門課。
選課表里面的主鍵是學生編號和序號,通過這兩個字段就能保證每行數據的唯一性。
可以看見表里每一門課的課程名稱也都放在這張表里面,如果有課程說明相關的內容也都放在這里的話,學生選幾門課都會把所有的信息都放在這里。張三和李四都選了“數據結構和算法”這門課,如果100個學生都選這門課的話,是不是這門課程相關的信息就會被重復存儲100遍?
解法也很簡單,拆拆拆唄~


把課程相關的信息單獨拿出來,選課的時候只保存課程編號,這樣的話,所有的課程相關信息都只保留一次,課程想怎么選就怎么選~
在數據模型中形態(tài)的變化如下。

整理一下三種范式的規(guī)律
第一范式要解決的是如下狀態(tài):

A為主鍵,A能夠保證數據唯一性,但是,其中有一個字段中保存了A1,A2,A3這樣的數據。
第二范式中說的部分依賴如下:

A和B為組合鍵,共同保證數據的唯一性,但是其中D可以單獨依賴主鍵中的B來識別。
第三范式中的傳遞性依賴示例如下:

A和B為組合鍵,共同保證數據的唯一性,但是其中E可以單獨依賴非主鍵屬性C來識別。
A+B => C, D, E 的同時 C => E,這樣的關系就被成為傳遞性依賴。
總結一下
通過范式化,可以最大程度上消除數據中的冗余,僅僅保留他們之間的關聯(lián)性。
這是關系型數據庫中最基本的原理知識,在數據模型設計的過程當中,按照設計方法論,可以最大程度上使數據達到這樣的狀態(tài),這也是邏輯模型設計過程中,必需的過程。
還有一個和范式化緊密聯(lián)系的理論知識也很重要,就是通過范式可以解決數據的變更異常(Modify Anomaly)現象,其中包含插入異常(Insertion anomaly)、更新異常(Update anomaly)、刪除異常(Deletion anomaly),道理其實很簡單,去除冗余之后就能夠保證同樣的數據不會被分散存儲到多個地方,這樣的話,不管是插入、更新還是刪除都可以只針對一個地方做變更就可以了,如果不這樣的話,每次變更就需要變更分散在各個地方的數據,無法嚴格地保證數據的一致性,還得通過其他手段去做。
邏輯模型設計的前期,通過這樣的手段保證數據模型遵守最基本的規(guī)則。但是,在模型設計的后期,會考慮到性能和使用的便利性,通過反范式的手段,適當地增加冗余,反范式的方法和設計的方法以后再說吧。