我其實對這系列要不要開坑有點猶豫,我知道這一開下去就是不得了的大坑
吃完冰了來討論一下正規化
一般分為第一正(1NF)規化第二正規化(2NF)....第N正規化
任何正規化必須符合前面所有正規化的條件,才可以成立
一言蔽之的話就是
若只有第一正規化,我每一筆交易都會包含客戶名稱
他一改名我要搜尋所有交易紀錄然後改名,非常的沒效率
並且其實很浪費儲存空間
wiki 的定義是 第二正規化
用其他複合鍵作為主鍵,我不喜歡這麼做
因為 int 欄位拿來當 pk 效率比較高,還有把兩個有意義的東西放在一起當PK是很蠢的想法
等到出報表就會生不如死
最重要的是有些框架ORM不支援複合主鍵 XDDD 這蠻嚴重的吧
不符合第二正規化造成最簡單的問題,就是萬一交易紀錄上
我有客戶同名同姓怎麼辦?所以就會加開一張表來記錄客戶資料
並且給定一個唯一主鍵來判斷,例如身分證字號!
我們在完成第二正規化,確定所有非主鍵欄位都已經和主鍵有了相依性後
會進行第三正規化
有點像是你們這個里的人都相依於這個里,但是你不能和隔壁老王發生關係
例如:你去寄店到店包裹,這筆資料若同時有店舖編號、店鋪地址、店鋪名稱
他們都相依於這筆交易資料,但是地址和店名又和店舖編號有關係
這時候就會把店鋪編號作為另一張表的 index 把店名和地址輸入進去
如此就符合第三正規化
還有一種特殊情況是主鍵是複合鍵值
這種時候還會再進行 Boyce-Codd 正規化 (BCNF)
主要原則就是
我們還要考慮系統的需求自行作一些變化
因為過多的資料表可能會降低系統執行的效能
尤其是當資料量增加到一定程度時,就會明顯感受到系統效能降低
參考資料
http://140.118.9.79/UML-SASD/正規化.pdf
http://au1252.epage.au.edu.tw/ezfiles/294/1294/img/2823/102052570.pdf
http://soon.logdown.com/posts/685164-sql-normalization
一路從早上起床就想開工,然後中間睡了午覺還去吃了冰
沒意外還沒打完就要吃晚餐了
但非資訊背景自學程式很容易遺漏的內容
一切的起因都是因為接手的程式太美,資料庫甚至連第一正規畫都沒做
基本上就是我遇到什麼前面人的大便,或是學會有趣的名詞就寫一下
可以把 RDB開得像NoSQL,我也覺得是天才啦
這樣亂開的確可以非常有彈性的解決一直變動的需求
但是這樣在資料庫方面就會增加不必要的負荷
所以這次就來說說資料庫的正規化
先說說為什麼要做資料庫正規化 (Normalization)
正規化是在資料庫中組織資料的程序。
簡單的說就是要將資料的重覆性降至最低,當你要修改一筆資料的內容
不需要在多個地放重複修改
舉例來說:
今天你有多個地方都儲存了學生姓名,如果今天發生學生改名
那你就要找出所有出存有該學生姓名的地方一併修改
若有做了正規化,那只需要改一次!為什麼呢?
打了這麼長先吃個冰休息一下好了,這就是我下午吃的剉冰
點了芋頭、花豆、綠豆跟軟花生,一家冰店的好壞決定在芋頭
不需要在多個地放重複修改
舉例來說:
今天你有多個地方都儲存了學生姓名,如果今天發生學生改名
那你就要找出所有出存有該學生姓名的地方一併修改
若有做了正規化,那只需要改一次!為什麼呢?
打了這麼長先吃個冰休息一下好了,這就是我下午吃的剉冰
點了芋頭、花豆、綠豆跟軟花生,一家冰店的好壞決定在芋頭
吃完冰了來討論一下正規化
一般分為第一正(1NF)規化第二正規化(2NF)....第N正規化
任何正規化必須符合前面所有正規化的條件,才可以成立
第一正規化(1NF)
實務上來說至少要做到1NF,先來看看wiki 定義 第一正規化一言蔽之的話就是
一個欄位(column)只能有單一值
每一列(row) 必須要具有可供識別的唯一識別碼(主鍵)
第二正規化(2NF)
通常我會至少做到第二正規化,這樣遇到例如客戶改名若只有第一正規化,我每一筆交易都會包含客戶名稱
他一改名我要搜尋所有交易紀錄然後改名,非常的沒效率
並且其實很浪費儲存空間
wiki 的定義是 第二正規化
每一非鍵屬性必須「完全相依」於主鍵如果我的主鍵是複合主鍵呢?
有些人喜歡把流水號 (就是auto-increment產生的index) 刪除若是非主鍵的欄位只和部分主鍵有關
則必須獨立出來成為一個資料表
或歸類到該主鍵的資料表
用其他複合鍵作為主鍵,我不喜歡這麼做
因為 int 欄位拿來當 pk 效率比較高,還有把兩個有意義的東西放在一起當PK是很蠢的想法
等到出報表就會生不如死
最重要的是有些框架ORM不支援複合主鍵 XDDD 這蠻嚴重的吧
不符合第二正規化造成最簡單的問題,就是萬一交易紀錄上
我有客戶同名同姓怎麼辦?所以就會加開一張表來記錄客戶資料
並且給定一個唯一主鍵來判斷,例如身分證字號!
第三正規化(3NF)
常常會把第二正規化和第三正規化搞混,2NF就順便做3NF我們在完成第二正規化,確定所有非主鍵欄位都已經和主鍵有了相依性後
會進行第三正規化
各欄位與主鍵間沒有間接相依的關係要求各個非鍵值屬性間,只能和鍵值有關係,互相不可具有相關性
例如:你去寄店到店包裹,這筆資料若同時有店舖編號、店鋪地址、店鋪名稱
他們都相依於這筆交易資料,但是地址和店名又和店舖編號有關係
這時候就會把店鋪編號作為另一張表的 index 把店名和地址輸入進去
如此就符合第三正規化
結論:
其實上面這些都是很粗淺的說明而已,還是要實際動手做才會理解還有一種特殊情況是主鍵是複合鍵值
這種時候還會再進行 Boyce-Codd 正規化 (BCNF)
主要原則就是
主鍵中的各欄位不可以相依於其他非主鍵的欄位。正規化也不是做得越多越好
我們還要考慮系統的需求自行作一些變化
因為過多的資料表可能會降低系統執行的效能
尤其是當資料量增加到一定程度時,就會明顯感受到系統效能降低
參考資料
http://140.118.9.79/UML-SASD/正規化.pdf
http://au1252.epage.au.edu.tw/ezfiles/294/1294/img/2823/102052570.pdf
http://soon.logdown.com/posts/685164-sql-normalization
留言
張貼留言