設計關系型資料庫時,遵從不同的規範要求,設計出合理的關系型資料庫,這些不同的規範要求被稱為不同的範式,各種範式呈遞次規範,越高的範式資料庫備援越小。
目前關系型資料庫有六種範式:第一範式(1NF)、第二範式(2NF)、第三範式(3NF)、巴斯-科德範式(BCNF)、第四範式(4NF)和第五範式(5NF,又稱完美範式)。一般來說,資料庫隻需要滿足第三範式就行了。
第一範式:保證每列的原子性
第一範式是最基本的範式。如果資料庫表中的所有字段值都是不可分解的原子值,就說明該資料庫滿足了第一範式。
第一範式需要根據系統的實際需求來定,比如有一張使用者資訊表:
一般來說"住址"設計成一個字段就行,但是如果經常通路"住址"中城市的部分,那麼就非要将"住址"這個屬性重新拆分為"省份"、"城市"、"位址"等多個部分進行存儲,這樣在對"住址"中某一部分進行操作的時候将非常友善。這麼設計才算滿足了資料庫的第一範式,修改之後的表結構如圖:
第二範式:保證一張表隻描述一件事情
這是通俗的說法,用第二範式的定義描述第二範式,說的是在滿足第一範式的基礎上,資料庫表中不存在非關鍵字段對任一候選關鍵字段的部分函數依賴,也即所有非關鍵字段都完全依賴于任一組候選關鍵字。
看不懂是嗎,沒關系,我也看不懂,下面舉一個例子,有一張表如下圖:
上表滿足第一範式,即每個字段不可再分,但是這張表設計得并不好,或者說,這張表的設計并不滿足第二範式。因為這張表裡面描述了兩件事情:學生資訊、課程資訊,"學分"完全依賴于"課程名稱"、"姓名"與"年齡"完全依賴于"學号"。這麼做的後果是:
1、資料備援:同一門課程由n個學生選修,"學分"重複n-1次;同一個學生選修了m門課程,姓名和年齡重複m-1次
2、更新異常:若調整了某門課程的學分,資料表中所有行的"學分"值都需要更新,否則會出現同一門課程學分不同的情況
3、插入異常:假設要開一門新課程,暫時沒有人選修,那麼由于沒有"學号"關鍵字,"課程"與"學分"也無法記錄入資料庫
4、删除異常:假設一批學生已經完成課程的選修,這些選修記錄就應該從資料庫表中删除。但是,與此同時,"課程"和"學分"也被删除了,顯然,這最終可能會導緻插入異常
是以,此表的結構必須修改,修改後如下:
增加了表,将學生資訊與課程資訊通過一張中間表關聯,很好地解決了上面的幾個問題,這就是第二範式的中心----保證一張表隻講一件事情。
第三範式----保證每列都和主鍵直接相關
第三範式又和第二範式相關,用第三範式的定義描述第三範式就是,資料庫表中如果不存在非關鍵字段任一候選關鍵字段的傳遞函數依賴則符合第三範式,所謂傳遞函數依賴指的是如果存在"A-->B-->C"的決定關系,則C傳遞函數依賴于A。也就是說表中的字段和主鍵直接對應不依靠其他中間字段,說白了就是,決定某字段值的必須是主鍵。
舉個例子,看一下如下的表結構:
第三範式和第二範式有點像,從這張資料庫表結構中可以看出,"姓名"、"年齡"、"學院"和主鍵"學号"直接關聯,但是"學院地點"、"學院電話"卻不直接和主鍵"學号"相關聯,和"學院電話"直接相關聯的是"學院",如果表結構這麼設計,同樣會造成和第二範式一樣的資料備援、更新異常、插入異常、删除異常的問題。
修改之後的表結構如下圖:
同樣,這麼設計表結構将合理地多,也解決了前面的四個問題。
後記
定理是死的,人是活的,在前人給我們總結出這些範式的前提下,使用這些範式靈活地應用到實際需求中,才是最重要的。