Database-Design

一個列的值取決於另外兩列的值,其中恰好有一列可以為空

  • July 3, 2017

Person表中,Citizen_IdentityIDForeigner_WorkPermitID將包含 NULL 標記。

PersonID_ID保存Citizen_IdentityIDor的值Foreigner_WorkPermitID(以不保留 NULL 標記的為準)。

換句話說,PersonID_ID取決於Citizen_IdentityID或的值Foreigner_WorkPermitID,並且還有其他屬性(例如IDColor)僅取決於PersonnID_ID

我應該如何建構規範化設計?

上述實體只是實際案例的簡單替換。

如果我理解您的描述,PersonID_IDCitizen_IdentityIDor的副本Foreigner_WorkPermitID(以不為 NULL 的為準)。如果這是真的,我會建議類似於DCook建議的內容:

  • 刪除Citizen_IdentityIDForeigner_WorkPermitID(消除重複數據)
  • 添加一個Person_Type(char(1) not NULL) 列;目前值可以分別是公民/外國人的“C”或“F”

根據您的數據來自哪裡,此設計將允許包含未來的人員類型(例如,在美國,您有公民、簽證持有人、綠卡持有人;在某些國家/地區,公民與居民與訪客之間存在明顯差異與非訪客簽證 - 更不用說不同類型的簽證了)。顯然,對其他人員類型的需求將取決於您要建模的內容。


多看這個……

個人的類型/身份會隨著時間而改變(例如,外國人成為公民;公民放棄公民身份並成為外國人)?

我問的原因是您顯然需要更改Person_TypeandPersonID_ID列的值…可能沒什麼大不了的…但是根據您的模型,您似乎PersonID_ID至少將在 PK 中使用另一個表,因此該表的 PK 也需要更新……雖然當然可行,但這可能會很快變得混亂,具體取決於需要修改其 PK 的表和記錄的數量,以及解決 RI 約束的麻煩。如果您還需要為某個人維護某種歷史/審計記錄(例如,必須儲存/映射 PK 的變化……糟糕!),那麼混亂會變得更糟。

所以現在我想知道是否PersonID_ID應該是一個獨立的、真正獨特的價值,獨立於Person_Type? 如果是這樣,那麼您可能需要保留Citizen_IdentityID/Foreigner_WorkPermitID值,但也許給它一個更通用的名稱。

因此,這會將我的建議更改為:

  • 添加一個Person_Type(char(1) not NULL) 列;目前值可以分別是公民/外國人的“C”或“F”
  • 更改PersonID_ID為它自己的唯一值(可以通過身份列或唯一PK生成器之類的東西來完成);這個值永遠不會改變,即使Person_Type隨著時間的推移而改變
  • Citizen_IdentityID/列替換為作為/表Foreigner_WorkPermitID的 FK 的單個通用 ID (視情況而定);也許像(int not NULL)?Citizen``Foreigner``Person_TypeID

好的,還有一個問題/問題…

一個人可以與超過 1 個Person_Type(C/F) 相關聯嗎?

例如,如果外國人通過入籍程序成為公民,這將如何在您的模型中表示?

該人現在是否會同時擁有 aForeigner_WorkPermitID和 a Citizen_IdentityID,因此需要將這兩個值都儲存在Person表中?

或者您會更新Person表格以顯示從“外國人”到“公民”的更改(即更改Person_TypePerson_TypeID)?

您能否將 CitizenIdentityID 和 ForeignWorkPermitID 消除到單個欄位並使用它來決定哪個表?假設使用帶有 C 或 F 的 varchar,然後是 ID 號。所以這封信會告訴你哪個表和 ID 號會告訴你哪條記錄。除非您在做數學運算,否則沒有理由將其作為整數進行。如果您想確保它被正確輸入,您可以為它建構一個驗證。這將為您擺脫一個領域。

引用自:https://dba.stackexchange.com/questions/177830