為什麼認為集合絕對非規範化數據庫?
為了使關係處於 1NF 上,它需要所有值都是原子的,如果有一個集合,它甚至不是第一個範式:
但直覺上,我認為具有該集合的表會比不只要該集合的值僅用作實體的屬性的表更規範化。
例如,讓我們想像一下這張關於繪畫的表格:
繪畫名稱,作者,使用的技術,使用的顏色
現在,如果我們使用一組顏色,例如 {blue、Green、yellow、black、White、purple},我們會得到一個甚至不在 1NF 中的表格。
如果我們將表傳遞給 1NF,那麼我們需要有 6 行,每行重複 Painting_name、Author 和 Used 技術。
這看起來比甚至不在 1NF 中的表更不規範化,我不明白為什麼在那裡有一個集合會損害任何可能的規範化,因為這些集合只會在該表中使用。
那麼需要原子值才能擁有規範化表的原因是什麼?
這篇文章的參考資料是一本很棒的書,名為Database System Concepts 6th Edition,我建議您閱讀。
在書中,第 328 頁,它指出:
如果域的元素被認為是不可分割的單元,則域是原子的。如果 R 的所有屬性的域都是原子的,我們說關係模式 R 是第一範式 (1NF)。
您可能想知道“但是為什麼!?”,最好用一個實際的例子來解釋。
讓我們用顏色來看看你的例子。假設我們有 2 個場景,1.) 表不在1NF 中,2.) 表在 1NF 中。
1.)
Id Painting_name Author Used_colors ----------- ------------------------------ ------------------------------ --------------- 1 Some_Painting John Blue, red, Yellow 2 Monalisa Leonardo da Vinci orange, black, White, red, Yellow
儘管這對您來說似乎很直覺,但請考慮當您要查詢此表時會發生什麼。一,你的大小寫不一致(你必須用你的查詢來檢查這兩種情況)二,如果
used_colors
不是一個數組,你要麼必須將它轉換為一個數組,要麼使用額外的步驟來檢查您需要的數據(例如string_split
在 SQL Server 2014 及更高版本中使用函式)。這會導致性能問題,並且每次您想要檢查某些東西時都會很麻煩。如果您想知道是什麼阻止了一個人輸入
black_white_yellow
?這個問題在 2NF 和 3NF、外鍵約束等中得到了回答……2.)
Id Painting_name Author Used_colors ----------- ------------------------------ ------------------------------ --------------- 3 Some_Painting John Blue 4 Some_Painting John red 5 Some_Painting John Yellow 6 Monalisa Leonardo da Vinci orange 7 Monalisa Leonardo da Vinci black 8 Monalisa Leonardo da Vinci White 9 Monalisa Leonardo da Vinci red 10 Monalisa Leonardo da Vinci Yellow
在這種情況下,每一行都是原子的且唯一的。我們這樣做有什麼收穫?您不必考慮處理數組,因為現在每一行都是原子的,您可以清楚地快速有效地檢查您需要的內容。
為了讓您了解它可能會帶來多大的麻煩,這裡有一些與在逗號分隔的列中搜尋值的問題相關的文章:
還有許多不同的方法,至少可以說沒有一個是真正優雅的(至少與 1NF 問題有關)。因此,基本上通過使用 1NF,您可以從使用上面那些文章中提到的程式碼到簡單的東西,例如:
SELECT * FROM Paintings WHERE Used_colors LIKE 'BLUE'
這有助於提高可讀性和性能。
您需要記住一件事,1NF 只是標準化過程的起點。單獨的 1NF 實際上從未在任何數據庫中使用過,在 1NF 出現之後,您必須將這個表拆分為兩個單獨的表的 2NF。
Used_colors
將被製成自己的表稱為Colors
. 在這一點上,您將遇到上面提到的書中也涉及的基數問題。最後一件事,在很多情況下,您會遇到在一個或多個表上破壞 1NF 的數據庫,同時遵守 2NF、3NF 甚至 4NF 的規則。例如PostgreSQL的
json
數據類型會立即打破 1NF 規則(因為您可以在 json 中保存多個鍵和值)。一般的經驗法則是這樣的:除非您真的知道自己在做什麼,否則請始終遵循正常形式。從您引入此類變數的那一刻起,您可能會導致整個數據庫出現不一致,並且您很可能會失去性能。此外,正如保羅在下面的評論中所說,克里斯托弗還有另一種觀點。J. Date 支持(他是關係數據庫理論的著名研究員和作家,也是與 Ted Codd 一起幫助推動關係模型的人之一)。這種觀點刺穿了 1NF 中原子值的概念,稱整個術語“原子”是模棱兩可的。這背後的想法很簡單,可以說在目前的 1NF 定義下幾乎沒有數據類型是原子的。為了解釋這一點,讓我們看一個例子:
假設你有一個字元串
Hello World
。您在每個 DBMS 中都有將這個字元串分解為更小的塊(如SUBSTRING
orLEFT
/RIGHT
函式)的函式,這意味著它string
並不是真正的原子值,因為所有內容都可以分解。這種前景類似於數據類型,例如json
,您可以分解字元串和json,那麼為什麼一種被認為是原子的而另一種則不是呢?這就是為什麼 CJ Date 認為 1NF 的目前定義是模棱兩可的,因為幾乎所有數據類型都可以以一種或另一種方式分解。如果您作為一個整體訪問json
或xml
數據類型而不分解它們,則沒有什麼可以說json
或xml
數據類型不是原子的。您可以在The Third Manifesto上找到一篇有趣的論文,他們(CJ Date 和 Hugh Darwin)公開發表了關於數據庫、類型和關係模型的論文 The Third Manifesto。這也是一本有趣的讀物,它將帶您閱讀其他有趣的文章和主題。