規範化/範式 - 一個欄位可以描述另一個欄位嗎?
像這樣:
CREATE TABLE persons( id serial8 NOT NULL PRIMARY KEY, name varchar, -- A lot of other fields date_of_birth timestamp with time zone, date_of_birth_precision varchar(16), CHECK (date_of_birth_precision IN ('Years','Months','Days','Hours','Minutes')) );
date_of_birth_precision
描述 的精度date_of_birth
。我想知道它是否違反了這個規則(因為我不完全理解這個規則):
R 的每個非主屬性都非傳遞依賴(即直接依賴)於 R 的每個超鍵。
我不同意這個問題的其他答案,也不認為這違反了 3NF。這是因為 date_of_birth_precision 不暗示 date_of_birth,date_of_birth 也不暗示 date_of_birth_precision。
重要的是要注意函式依賴的定義:
給定一個關係 R,當且僅當每個 X 值都與一個 Y 值相關聯時,R 中的一組屬性 X 被稱為在功能上確定另一組屬性 Y,也在 R 中,(寫作 X → Y);然後說 R 滿足函式依賴 X → Y。等效地,投影是一個函式,即 Y 是 X 的函式。1簡單地說,如果 X 屬性的值是已知的(假設它們是 x),那麼對應於 x 的 Y 屬性的值可以通過在包含 x 的 R 的任何元組中查找它們來確定。通常將 X 稱為行列式集,將 Y 稱為從屬集。
所以讓我們問問自己,對於給定的 date_of_birth_precision 值,這是否意味著 date_of_birth? 當然不是。對於給定的 date_of_birth 值,這是否意味著 date_of_birth_precision? 它沒有,否則你甚至不會問這個問題。由於兩者都沒有暗示另一個,因此兩者之間沒有功能依賴關係。因此,這並沒有破壞 3NF,因為 3NF 僅限定了函式依賴的規則;它沒有說明在功能上不相互依賴的屬性。
我個人發現 3NF 的替代定義更容易理解:
Carlo Zaniolo 在 1982 年給出了一個與 Codd 等價但表達方式不同的 3NF 定義。該定義表明一個表在 3NF 中當且僅當對於它的每個函式依賴 X → A,至少有一個以下條件成立:
- X 包含 A(即 X → A 是平凡的函式依賴),或
- X 是一個超級鍵,或
- AX 的每個元素,即 A 和 X 之間的集合差,是一個素數屬性(即,AX 中的每一列都包含在某個候選鍵中)
確實如此,
date_of_birth_precision
它確實描述date_of_birth
了比persons
實體更多的內容。但從整體設計的角度來看,我會像您擁有它一樣保留它,這就是為什麼-在遵循規範化規則時,您可以推斷您應該創建一個
date_of_birth
表來保存date_of_birth_id
、date_of_birth
和date_of_birth_precision
。然後,您將date_of_birth_id
在persons
表中包含 a,並帶有引用date_of_birth
表的外鍵。這條路徑是有意義的,直到您分析數據並意識到幾乎每一行都是唯一的。理所當然地,很少有人
persons
會共享相同的date_of_birth
,因此引用它並沒有多大意義,因為它不會對減少冗餘有太大作用。您還可以詢問自己在查詢時將如何使用這些數據。您想查看查詢
date_of_birth_precision
的時間嗎?persons
還是date_of_birth
分開處理?同樣,您的案例可能表明將它們放在一起是有利的,並且可以避免執行另一個查詢或 JOIN。在對您的應用程序有意義的地方進行規範化,而不是為了規範化本身。