张大胖学数据库
從這學期開始,張大胖開始學習數據庫, 聽說這門課很重要, 很基礎, 但是大胖學的很煩。
其實剛開始的時候還行, 課程先講了講數據庫的作用,?他聽的津津有味, 但講到后邊, 當那些文縐縐的術語像關系演算、函數依賴、規范化...... ?出現的時候, ?大胖徹底的懵了。 ?
他實在是不明白, 這個看起來像一個表格的東西為什么搞這么多數學的公式, 最煩數學了。
周末大胖跑去向大神好基友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
總結
- 上一篇: 漫画:优秀的程序员具备哪些属性?
- 下一篇: 成为一名更好的程序员:如何阅读源代码