數據標準化(從 0NF 到 1NF)
我正在 mySQL 中設計一個關係數據庫 - 一個圖書館管理系統。我想展示 1NF、2NF、3NF、BCNF 等數據的範例。我的 1NF 範例看起來像這樣
“如果每個屬性的域僅包含原子值,並且每個屬性的值僅包含來自該域的單個值,則關係處於第一範式。”
我不確定數據是否在 1NF 中。例如屬性“ISBN”是原子的嗎?
ISBN 是唯一的數字商業圖書標識符。ISBN 由 4 個部分(如果是 10 位 ISBN)或 5 個部分(對於 13 位 ISBN)組成。不同的部分是前綴元素、註冊組、註冊人、發布和校驗位。你會將標識號分成更小的單位,以保證一個原子值嗎?
是的,它是原子的;您的域是 ISBN。如果您儲存的是 ISBNPrefix、ISBNRegistrationGroup、ISBNRegistrant、ISBNPublication 和 ISBNCheckDigit 的域,那麼您將其拆分。
考慮北美電話號碼
+1-234-567-8901 ext 234567
。許多系統選擇將這樣的號碼儲存在兩個域下,例如PhoneNumber
andPhoneNumberExtension
,可能2345678901
在PhoneNumber
域234567
下和PhoneNumberExtension
域下,完全忽略電話號碼國家程式碼(主要是因為它總是 1 )。由於域是這樣定義的,因此以這種方式儲存它們並沒有錯。在這種情況下,違反 1NF 的一個範例是將多個分機號碼儲存在同一行中,用於PhoneNumber
域中存在的單個實體。| PhoneNumber | PhoneNumberExtension | 2345678901 234567, 890123
相反,為了保留 1NF,
PhoneNumberExtension
屬性是分開儲存的。| PhoneNumber | PhoneNumberExtension | 2345678901 234567 2345678901 890123
具有更細化域的系統可以選擇按
PhoneNumberCountryCode
、PhoneNumberAreaCode
、PhoneNumberPrefix
和儲存電話號碼PhoneNumberLineNumber``PhoneNumberExtension
| CountryCode | AreaCode | Prefix | LineNumber | Extension | 1 234 567 8901 234567
由於域是以這種方式定義的,因此儲存數據本身也不是錯誤的。相同的邏輯適用於各種“複合屬性”,例如您的 ISBN;地理座標數據和市政郵寄地址是一些常見的例子,但這種“域分組”甚至發生在基本數據類型中 - 考慮一下
DATETIME
,例如原始數據類型 - 一部分日期,一部分時間。您選擇定義域的方式很大程度上取決於您打算如何使用它們。在電話範例中,拆分往往沒有什麼價值,
AreaCode
因為通常可以使用其他更合適的人口統計數據,例如City
,儘管拆分域並不是一個“錯誤”的選擇。如果拆分 ISBN 的目的對您來說沒有什麼價值,那麼通過在較小粒度級別上定義域並沒有違反 1NF - 您只是不能將其中兩個儲存在同一行中的同一實體中。
1NF 上下文中的原子僅表示“不是關係”。
ISBN 編號不是關係,因此對於關係運算符而言它是原子的。例如,您不能在 ISBN 編號中插入新行。