關係數據庫的範式和反範式設計

範式是關係數據庫理論的基礎,也是咱們在設計數據庫結構過程當中所要遵循的規則和指導方法。數據庫的設計範式是數據庫設計所須要知足的規範。只有理解數據庫的設計範式,才能設計出高效率、優雅的數據庫,不然可能會設計出錯誤的數據庫。數據庫

目前關係數據庫有六種範式:第一範式(1NF)、第二範式(2NF)、第三範式(3NF)、巴斯-科德範式(BCNF)、第四範式(4NF)和第五範式(5NF,還又稱完美範式)。知足最低要求的叫第一範式,簡稱1NF。在第一範式基礎上進一步知足一些要求的爲第二範式,簡稱2NF。其他依此類推。各類範式呈遞次規範,越高的範式數據庫冗餘越小。設計模式

一般所用到的只是前三個範式,即:第一範式(1NF),第二範式(2NF),第三範式(3NF)。數據庫設計

第一範式(1NF):強調的是列的原子性,即列不可以再分紅其餘幾列。簡而言之,======第一範式就是無重複的列======性能

第二範式(2NF):首先要知足它是1NF,另外還須要包含兩部份內容:一是表必須有一個主鍵;==二是沒有包含在主鍵中的列必須徹底依賴於主鍵,而不能只依賴於主鍵的一部分。==
即要求實體的屬性徹底依賴於主關鍵字。所謂徹底依賴是指不能存在僅依賴主關鍵字一部分的屬性。設計

第三範式(3NF):在1NF基礎上,任何非主屬性不依賴於其它非主屬性[在2NF基礎上消除傳遞依賴]。第三範式(3NF)是第二範式(2NF)的一個子集,即知足第三範式(3NF)必須知足第二範式(2NF)。事務

簡而言之,第三範式(3NF)要求一個關係中不包含已在其它關係已包含的非主關鍵字信息。例如,存在一個部門信息表,其中每一個部門有部門編號(dept_id)、部門名稱、部門簡介等信息。那麼在員工信息表中列出部門編號後就不能再將部門名稱、部門簡介等與部門有關的信息再加入員工信息表中。若是不存在部門信息表,則根據第三範式(3NF)也應該構建它,不然就會有大量的數據冗餘。==簡而言之,第三範式就是屬性不依賴於其它非主屬性,也就是在知足2NF的基礎上,任何非主屬性不得傳遞依賴於主屬性。==table

關於範式的討論效率

第二範式和第三範式如何區別?基礎

第二範式:非主鍵列是否依賴主鍵(包括一列經過某一列間接依賴主鍵),要是有依賴關係的就是第二範式;方法

第三範式:非主鍵列是不是直接依賴主鍵,不能是那種經過傳遞關係的依賴的。要是符合這種就是第三範式;

使用範式有哪些優勢和缺點?

==範式能夠避免數據冗餘,減小數據庫的空間,減輕維護數據完整性的麻煩。==

範式再給咱們帶來的上面的好處時,同時也伴隨着一些很差的地方:==按照範式的規範設計出來的表,等級越高的範式設計出來的表越多。==

如第一範式可能設計出來的表可能只有一張表而已,再按照第二範式去設計這張表時就可能出來兩張或更多張表,若是再按第三範式或更高的範式去設計這張表會出現更多比第二範式多的表。

表的數量越多,當咱們去查詢一些數據,必然要去多表中去查詢數據,這樣查詢的時間要比在一張表中查詢中所用的時間要高不少。也就是說咱們所用的範式越高,對數據操做的性能越低。

因此咱們在利用範式設計表的時候,要根據具體的需求再去權衡是否使用更高範式去設計表。在通常的項目中,咱們用的最多也就是第三範式,第三範式也就能夠知足咱們的項目需求,性能好並且方便管理數據;

當咱們的業務所涉及的表很是多,常常會有多表發生關係,而且咱們對錶的操做要時間上要儘可能的快,這時能夠考慮咱們使用「反範式」。

關於反範式

不知足範式的模型,就是反範式模型。

反範式跟範式所要求的正好相反,在反範式的設計模式,咱們能夠容許適當的數據的冗餘,用這個冗餘去取操做數據時間的縮短。本質上就是用空間來換取時間,把數據冗餘在多個表中,當查詢時能夠減小或者是避免表之間的關聯;

RDBMS模型設計過程當中,經常使用範式約束咱們的模型,但在NOSQL模型中則大量採用反範式。

範式和反範式的對比

模型 優勢 缺點
反範式化模型 數據冗餘將帶來很好的讀取性能(由於不須要join不少表,並且一般反範式模型不多作更新操做) 須要維護冗餘數據,從目前NoSQL的發展能夠看到,對磁盤空間的消耗是能夠接受的
範式化模型 數據沒有冗餘,更新容易 當表的數量比較多,查詢設計須要不少關聯模型(join)時,會致使查詢性能低下

舉個栗子


書上講了好多, 歸結起來3句話:

1NF:字段不可分;
2NF:有主鍵,非主鍵字段依賴主鍵;
3NF:非主鍵字段不能相互依賴;

解釋:
1NF:原子性 字段不可再分,不然就不是關係數據庫;
2NF:惟一性 一個表只說明一個事物;
3NF:每列都與主鍵有直接關係,不存在傳遞依賴;

不符合第一範式的例子(關係數據庫中create不出這樣的表):

表:字段1, 字段2(字段2.1, 字段2.2), 字段3 ......

存在的問題: 由於設計不出這樣的表, 因此沒有問題;

不符合第二範式的例子:

表:學號, 姓名, 年齡, 課程名稱, 成績, 學分;

這個代表顯說明了兩個事務:學生信息, 課程信息;

存在問題:

數據冗餘,每條記錄都含有相同信息;
刪除異常:刪除全部學生成績,就把課程信息全刪除了;
插入異常:學生未選課,沒法記錄進數據庫;
更新異常:調整課程學分,全部行都調整。

修正:

學生:Student(學號, 姓名, 年齡);

課程:Course(課程名稱, 學分);

選課關係:SelectCourse(學號, 課程名稱, 成績)。

知足第2範式只消除了插入異常。

不符合第三範式的例子:

學號, 姓名, 年齡, 所在學院, 學院聯繫電話,關鍵字爲單一關鍵字"學號";

存在依賴傳遞: (學號) → (所在學院) → (學院地點, 學院電話)

存在問題:

數據冗餘:有重複值;

更新異常:有重複的冗餘信息,修改時須要同時修改多條記錄,不然會出現數據不一致的狀況

刪除異常

修正: 學生:(學號, 姓名, 年齡, 所在學院); 學院:(學院, 地點, 電話)。

相關文章
相關標籤/搜索