範式的英文名稱是Normal Form,它是英國人E.F.Codd(關係數據庫的老祖宗)在上個世紀70年代提出關係數據庫模型後總結出來的。範式是關係數據庫理論的基礎,也是咱們在設計數據庫結構過程當中所要遵循的規則和指導方法。目前有跡可尋的共有8種範式,依次是:1NF,2NF,3NF,BCNF,4NF,5NF,DKNF,6NF。一般所用到的只是前三個範式,即:第一範式(1NF),第二範式(2NF),第三範式(3NF)。數據庫
第一範式實際上是關係型數據庫的基礎,即任何關係型數據庫都是符合第一範式的。簡單的將第一範式就是每一行的各個數據都是不可分割的,同一列中不能有多個值,若是出現重複的屬性就須要定義一個新的屍實體。
下面數據庫便不符合第一範式:設計
+------------+-------------------+ | workername | company | +------------+-------------------+ | John | ByteDance,Tencent | | Mike | Tencent | +------------+-------------------+
上面描述的數據所表達的意思是,Mike在Tencent工做,而John同時在ByteDance和Tencent工做(假設這是可能的)。可是這種表達方式並不符合第一範式,即列的數據必須是不可分的,要知足第一範式,必須是下面的這種形式:code
+------------+-----------+ | workername | company | +------------+-----------+ | Mike | Tencent | | John | ByteDance | | John | Tencent | +------------+-----------+
首先,一個數據庫要知足第二範式必需要先知足第一範式。
咱們先看一個表格:orm
+----------+-------------+-------+ | employee | department | head | +----------+-------------+-------+ | Jones | Accountint | Jones | | Smith | Engineering | Smith | | Brown | Accounting | Jones | | Green | Engineering | Smith | +----------+-------------+-------+
這個表描述了被僱傭者,工做部門和領導的關係。這個表所表示的關係在現實生活中是徹底可能存在的,如今讓咱們考慮一個問題,若是Brown接任Accounting部門的領導,咱們須要怎樣對錶進行修改?這個問題將會變得很是麻煩,由於咱們會發現數據都耦合在一塊兒了,你很難找到一個很好的能惟一肯定每一行的判斷條件來執行你的UPDATE語句。而咱們把可以惟一表示數據庫中表的一行的數據成爲這個表的主鍵。 所以,沒有主鍵的表是不符合第二範式的,也就是說符合第二範式的表須要規定主鍵。
所以咱們爲了使上面的表符合第二範式,須要將它拆分爲兩個表:索引
+----------+-------------+ | employee | department | +----------+-------------+ | Brown | Accounting | | Green | Engineering | | Jones | Accounting | | Smith | Engineering | +----------+-------------+ +-------------+-------+ | department | head | +-------------+-------+ | Accounting | Jones | | Engineering | Smith | +-------------+-------+
在這兩個表中,第一個表的主鍵爲employee,第二個表的主鍵爲department。在這種狀況下,完成上面的問題就顯得很是簡單了。內存
一個關係型數據庫要知足第三範式必需要先知足第二範式。
將第三範式前,咱們一樣先看兩個表:it
+-----------+-------------+---------+-------+ | studentid | studentname | subject | score | +-----------+-------------+---------+-------+ | 1 | Mike | Math | 96 | | 2 | John | Chinese | 85 | | 3 | Kate | History | 100 | +-----------+-------------+---------+-------+ +-----------+-----------+-------+ | subjectid | studentid | score | +-----------+-----------+-------+ | 101 | 1 | 96 | | 111 | 3 | 100 | | 201 | 2 | 85 | +-----------+-----------+-------+
上面的兩個表格的主鍵分別爲studentid和subjectid,很顯然兩個表都符合第二範式。
可是咱們會發現這兩個表有重複冗餘的數據score。所以第三範式就是要消除冗餘的數據,具體到上面的狀況,就是兩個表只有一個可以存在score這一列數據。那麼怎麼將這兩個表聯繫起來呢,這裏就出現了外鍵。若是兩個表中有冗餘重複的列,並且這個表中的一個非主鍵列在另外一個表中是主鍵,那麼咱們爲了消除冗餘列能夠把這個非主鍵列做爲聯繫兩個表的橋樑,也就是外鍵。 經過觀察能夠發現,studentid在第一個表中是主鍵,在第二個表中是非主鍵,因此他就是第二個表的外鍵。所以上述狀況咱們有了如下符合第三範式的寫法:基礎
+-----------+-------------+---------+ | studentid | studentname | subject | +-----------+-------------+---------+ | 1 | Mike | Math | | 2 | John | Chinese | | 3 | Kate | History | +-----------+-------------+---------+ +-----------+-----------+-------+ | subjectid | studentid | score | +-----------+-----------+-------+ | 101 | 1 | 96 | | 111 | 3 | 100 | | 201 | 2 | 85 | +-----------+-----------+-------+
能夠發如今設定了外鍵以後,第一個表即便刪除了score列,也能夠經過studentid在第二個表中查找到相應的score的值,這樣即消除了數據的冗餘,又不會影響查找,知足第三範式。方法
範式化的缺點就是一般須要關聯。稍微複雜一些的查詢語句在符合範式的數據庫上均可能須要至少一次關聯,也許更多,這不但代價昂貴,也可能使一些索引策略無效。總結