# 范式
## 為什么要用范式
我們在學習關系型數據庫的時候一定有感覺,關系數據庫不就是一個二維表格嗎,那么數據庫有什么用?
數據庫看上去像一個表格,其實不然,比如如下的`訂單表`,一個訂單號X2001對應一個用戶,但是還對應了兩行產品,非常不規范。

要想把這個表規范化,可以使用`范式`。引入范式的主要目的在于:**解決冗余的問題**
## 第一范式
那么如何`規范化`呢?可以拆分成兩個表格。
一個是`訂單表`

**一個訂單號可以唯一的確定一行**
一個是`細節表`,一個訂單號+產品編碼才可以唯一的確定一行。

拆分以后就可以保證**一個單元格只有一個值了**
所以我們說`訂單表`的主鍵是 (訂單號), `細節表`的主鍵是(訂單號,產品編碼), 這是一個復合主鍵
## 第二范式
再看看`訂單細節表`, `產品名稱`和`單價` 實際上并不依賴于 `訂單號`。
如果想添加一個新的產品, 你會發現沒法放入這張表, 因為沒有訂單號!

所以還需要再次拆分。

拆分以后,表4.1`訂單細節表`的主鍵還是(訂單號,產品編碼),但是剩下的屬性(數量)肯定是完全依賴于主鍵的。
表4.2產品表也類似,主鍵是`產品編碼`,剩下的屬性都依賴于`產品編碼`
> 所有屬性都依賴于`主鍵`的情況就是`第二范式`
## 第三范式
我們再回過頭來看一下表格3 `訂單表`,它的主鍵是`訂單號`,所有的屬性都依賴于主鍵,已經是第二范式。 但是我們發現,訂單號能決定用戶ID,用戶ID能決定用戶名稱,這就出現了`依賴傳遞`:**訂單號->用戶ID->用戶名稱**

那么可以再拆分

> 沒有傳遞依賴了, 我們可以稱之為 第三范式
為了滿足范式要求,需要把一張大表拆分開,到時候查詢豈不是非常麻煩?是的,需要將這些表`Join`起來,如果數據量大的時候,連接非常耗時。有時我們需要違反范式,做點數據冗余。
# 總結
總結一下:
- 第一范式:字段是不可再分的,也就是不存在一個字段中存在兩個及以上**值**的情況。
- 第二范式:**所有屬性都依賴于主鍵**,其他不相關的都拆分出去了。
- 第三范式:不存在某個列不依賴于`非主鍵`的列,沒有依賴傳遞了
# 參考
主要改編自[張大胖學數據庫]( https://mp.weixin.qq.com/s?__biz=MzAxOTc0NzExNg==&mid=2665513430&idx=1&sn=2cb004652353d08db7f3724c7efd26a1&chksm=80d67995b7a1f08313d2f8d2c000c27ee480596849a5bee20d2f82b8409f6da8ec7348c69e5a&scene=21#wechat_redirect)