數據庫規(guī)范化 Normalization
一個數據庫會包含很多張表咬崔,那么這些表要如何因應需求來做設計呢税稼?該設計哪些表烦秩?該設計哪些字段?這兩節(jié)會告訴大家郎仆。
數據庫規(guī)范化(Normalization)是數據庫設計的一個非常重要的基本概念只祠,目的是要去除重復的數據,增加數據的一致性丸升。實際的作法是會將重復的字段铆农,抽出來變成另一個新的表牺氨。
規(guī)范化還分成一階規(guī)范化狡耻、二階規(guī)范化、三階規(guī)范化猴凹、DK/NF規(guī)范化等等不同級別夷狰,一般來說我們的應用軟件會做到二階或三階規(guī)范化。
讓我們用實際的例子來看:假設我們要設計一個場景是紀錄「使用者 User」參與多個「活動 Event」
未規(guī)范化
這種 Table 設計缺點很多:
ihower 如果需要參加第四個活動郊霎,就必須變更 Table 的 Schema 增加更多字段沼头。但是變更 Schema 是一件成本很高的事情 :(
john 沒有參加這么多活動,多馀的字段都是 NULL书劝,對數據庫來說是浪費空間
ihower 跟 john 都有參加 RubyConf进倍,但是 2015/9/11 這個活動日期重復存了。而且如果活動改日期购对,表示這些值都要改
一階: 移除重復語意的 columns
剛剛的 event 1, event 1 date, event 2, event 2 date, event 3, event 3 date 倆倆都是重復的猾昆,讓我們消滅它們:
缺點:
相比于沒有規(guī)范化的,現在新報名不需要修改 Schame 了
但是重復的資料更多骡苞,包括用戶數據和活動數據
二階: 移除重復語意的 row
接下來需要拆表了垂蜗,一口氣我們拆成三張表:users 表、events 表解幽、registration 表贴见,并且 users 和 events 要加上可識別的 id 字段。
相信對 Rails 已經很熟悉的同學躲株,這就是 User model 和 Event model 透過 Registration model 來達成多對多關系片部。
這好多了,看起來沒有重復的資料了霜定,如果要改 user 或 event 的數據吞琐,只需要改一個地方。
但是還有一個小地方可以改進然爆,讓我們繼續(xù)看下去:
三階: 移除不依賴主 ID 的資料
在 users table 中站粟,city 名字其實只跟 zipcode 相關,跟 user id 沒關系曾雕,因此這個 city 可以拆出來奴烙。在 users table 中只需要留著 zipcode 就好了。
小結
規(guī)范化讓數據不會重復和高度一致性,節(jié)省空間切诀、增加修改數據時的效率揩环、避免數據不一致的錯誤。