- 01 確定所有資料表都有主鍵
- 02 消除重複儲存資料
- 03 去除重複組群
- 04 每個欄只儲存一個屬性
- 05 儲存計算出的資料通常不是好主意
- 06 定義外來鍵以保護參考完整性
- 07 確保資料表關係的合理
- 08 3NF不夠時,更多的正規化
- 09 對資料倉儲使用反正規化
「你無法用母豬的耳朵製作絲綢包」-Stephen Gosson
01 確定所有資料表都有主鍵
什麼才是好的主鍵?欄應該具有下列特徵 :
- 儲存獨特值
- 不能為空
- 穩定(也就是不會改變)
- 盡可能簡單
建議不要使用複合主鍵,它們因兩個理由而比較沒效率 :
- 定義主鍵時,大部分資料庫系統會強制索引定義。一個欄以上的獨特索引需要資料庫系統執行更多的工作。
- 對主鍵執行聯集是相當常見的,但在多欄主鍵上執行則更為複雜與緩慢。
02 消除重複儲存資料
- 資料庫正規化的目的是消除重複資料並減少處理資料時所需的資源。
- 消除重複資料可消除新增、修改、與刪除異常。
- 消除重複資料可減少不一致的資料。
03 去除重複組群
- 資料庫正規化的目標是消除重複資料群組並減少schema的變動。
- 消除重複資料群組後,你可以使用索引來防止重複的資料並大幅簡化查詢。
- 消除重複資料群組讓設計更為彈性,因為加入新的群組只需要另一個資料列而不用改變資料表設計以增加欄。
04 每個欄只儲存一個屬性
- 正確的資料表設計會將個別屬性放在獨立的欄中,因為欄帶中有多個屬性時,搜尋與彙整會變得困難甚或不可能。
- 對某些應用程式,過濾地址或電話欄的部分內容的需求會決定細分的程度。
- 需要重新組合資料屬性時使用連接函式。
05 儲存計算出的資料通常不是好主意
- 許多系統讓你在定義資料表時定義計算出的欄,但你必須了解效能的影響,特別是使用非決定性表示式或函示時。
- 你也可以定義與一般欄相同的計算欄並以觸發器維護,但程式會相當複雜。
- 計算欄會對資料庫系統產生負擔,因此只能在好處大於成本時使用。
- 通常你會想要對計算欄製作索引,以儲存空間與較慢的更新換得一些好處。
- 不做索引時,使用檢視表來定義計算通常比在資料表中儲存計算是更好的做法。
06 定義外來鍵以保護參考完整性
參考完整性(DRI)約束,有兩個目的:
- 使用設計工具建議新的檢視表或預存程序時,資料庫的圖形化查詢設計工具可得知如何建構正確的JOIN句子。
- 對關係中的”多”測的資料表新增或刪除或”一”測的資料表修改或刪除時,資料庫系統可得知如何施行資料完整性。
07 確保資料表關係的合理
- 仔細檢視結合帶有類似欄的資料表是否合理以簡化關係。
- 只要兩個資料表的欄有相同的資料型別(或者可以間接的轉換)就可以連接,但關係只有在欄具有相同的值域時才有效。然而,連接的兩方最好是具有相同的資料型別。
- 在資料模型引用前要檢查是否為結構化資料。若資料為半結構化,則要做出必要的規定。
- 清楚的辨識資料模型的目標可幫助你評估是否為了簡化應用程式的設計而提升了複雜性與異常可能。
08 3NF不夠時,更多的正規化
- 大部分的資料模型可能已經達成更高的正規化。因此,你必須注意明顯違反更高的正規化的情況。比較有可能的是具有複合鍵或參與多個多對多關係的資料表。
- 一個實體的兩個無關聯屬性的所有排列組合必須列舉的特殊情況下可能會違反第四正規化。
- 第五正規化確保所有連接相依性來自候選鍵,表示你應該能夠根據個別元素約束候選鍵的有效值。這只會發生在複合鍵上。
- 第六正規化將關係減至只有一個非鍵屬性,因此會導致資料表爆發,但我們不必定義可為空的欄。
- 無損分解是判斷資料是否違反更高正規化的有效工具。
09 對資料倉儲使用反正規化
- 決定要複製什麼資料與複製的理由。
- 規劃如何保持資料同步。
- 重新撰寫查詢以使用反正規劃欄。
Reference
Effective SQL Ch1