從這學期開始,張大胖開始學習數據庫, 聽說這門課很重要, 很基礎, 但是大胖學的很煩。
其實剛開始的時候還行, 課程先講了講數據庫的作用, 他聽的津津有味, 但講到后邊, 當那些文縐縐的術語像關系演算、函數依賴、規范化...... 出現的時候, 大胖徹底的懵了。
他實在是不明白, 這個看起來像一個表格的東西為什么搞這么多數學的公式, 最煩數學了。
周末大胖跑去向大神好基友Bill訴苦 :“這關系數據庫不就是一個二維的表格嗎, 就像Excel那樣, 一行一列的, 為什么搞的這么復雜, 還有數學的東西?”
Bill 笑了笑說: “看起來確實像個表格, 但是和表格很不一樣, 你看看這個例子, 然后想想能直接用關系數據庫來保存嗎?”

(表格1 訂單表 )
大胖說: “似乎不行,你看一個訂單號X2001對應一個用戶,U001(白展堂), 還對應兩行產品, P101(路由器), P102(充電寶) , 不過, 我能不能改成這樣: ”

(表格2 點擊看大圖)
Bill一看, 這張大胖竟然把多行合并成了一行, 中間用逗號分開, 不由的又氣又笑:
“你要是參加工作了, 設計出這樣的數據庫表, 老板非罵死你不可。 你要記住呀, 我們關系數據庫最忌諱的就是在一個單元格里存儲多個值。 這是典型的‘非規范化’的設計”
“非規范化? 那怎么辦? ”
“拆分, 把它拆成規范化的 ” 說著,Bill 搞了兩個表格出來:
(表3: 訂單表)
(表4: 訂單細節表)
“明白了, 這樣的拆分就可以保證一個單元格只有個值了” 張大胖說。
“這種形式的表, 我們就叫做第一范式, 不止如此, 你看看表格3 訂單表, 是不是一個訂單號就能唯一的確定一行? ”
“對, 訂單表確實是這樣的, 但是表格4 單單用訂單號就不行了, 還得加上產品編碼, 才能確定同一行的其他值。”
Bill 說: ”所以我們說表3的主鍵是 (訂單號), 表4的主鍵是(訂單號,產品編碼), 這是一個復合主鍵“
大胖高興的說: “啊, 這第一范式看來很簡單嘛”
“別急, 你再看看表格4:訂單細節表, 雖然說 (訂單號,產品編碼) 是主鍵, 能確定其他屬性的值, 但是 產品名稱和單價 實際上并不依賴于 訂單號。 如果我們想添加一個新的產品比如ipad, 你會發現沒法放入這張表, 因為沒有訂單號!”
“奧, 必須先有訂單才能有產品, 這確實是太扯了, 難道再拆分?” 大胖問?
“必須拆, 要不然就沒法工作”

(表4.1 訂單細節表)

(表4.2 產品表)
“我明白了, 現在表4.1 中主鍵還是(訂單號,產品編碼), 剩下的屬性(數量)肯定依賴于這個主鍵了, 表4.2也類似。”
Bill總結說:“這種所有屬性僅僅依賴于主鍵的情況就是 第二范式 。 ”
“這些范式術語聽起來一本正經的, 很學究, 背后還是挺有用的嘛。 那表格3中主鍵是(訂單號), 其他所有屬性都依賴于主鍵, 已經是第二范式了吧”
Bill 說 :“可以這么認為, 但是這個表有個好玩的情況, 就是訂單號能決定用戶ID, 而用戶ID 能決定用戶名稱, 這就出現了傳遞依賴: 訂單號->用戶ID->用戶名稱。 你看看用戶信息其實也無法單獨管理了, 也得拆分, 這個很簡單, 你來試試? ”
張大胖迅速的鼓搗出兩張表來:

(表3.1 訂單表)

(表3.2 用戶表)
Bill說:“不錯, 現在就沒有傳遞依賴了, 我們可以稱之為 第三范式 了”
“我有個疑問啊” 大胖問道, ”為了滿足所謂的范式要求, 我們把最初的大表拆的如此‘分散’, 到時候查詢的時候豈不非常麻煩??“
“可不是, 把這些‘分散表’連接(Join)起來才能形成最初的那張表, 如果在數據量特別巨大的時候, 這種連接挺耗時的。 在實踐中我們有時候不得不違反范式,做點數據的冗余。 比如說我們雖然把表3.2 用戶表單獨拆分了出來, 但是有時候為了性能, 還會在表3.1 中把用戶名也加上, 為一個冗余。 ”
相關文章:
小李的數據庫之旅(上)
小李的數據庫之旅(下)
張大胖學socket
張大胖學遞歸
from: http://chuansong.me/n/1246048751921
新聞熱點
疑難解答