一個列的值取決於另外兩列的值,其中恰好有一列可以為空
在
Person
表中,Citizen_IdentityID
或Foreigner_WorkPermitID
將包含 NULL 標記。
PersonID_ID
保存Citizen_IdentityID
or的值Foreigner_WorkPermitID
(以不保留 NULL 標記的為準)。換句話說,
PersonID_ID
取決於Citizen_IdentityID
或的值Foreigner_WorkPermitID
,並且還有其他屬性(例如IDColor
)僅取決於PersonnID_ID
。我應該如何建構規範化設計?
上述實體只是實際案例的簡單替換。
如果我理解您的描述,
PersonID_ID
是Citizen_IdentityID
or的副本Foreigner_WorkPermitID
(以不為 NULL 的為準)。如果這是真的,我會建議類似於DCook
建議的內容:
- 刪除
Citizen_IdentityID
和Foreigner_WorkPermitID
(消除重複數據)- 添加一個
Person_Type
(char(1) not NULL) 列;目前值可以分別是公民/外國人的“C”或“F”根據您的數據來自哪裡,此設計將允許包含未來的人員類型(例如,在美國,您有公民、簽證持有人、綠卡持有人;在某些國家/地區,公民與居民與訪客之間存在明顯差異與非訪客簽證 - 更不用說不同類型的簽證了)。顯然,對其他人員類型的需求將取決於您要建模的內容。
多看這個……
個人的類型/身份會隨著時間而改變(例如,外國人成為公民;公民放棄公民身份並成為外國人)?
我問的原因是您顯然需要更改
Person_Type
andPersonID_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) 相關聯嗎?例如,如果外國人通過入籍程序成為公民,這將如何在您的模型中表示?
該人現在是否會同時擁有 a
Foreigner_WorkPermitID
和 aCitizen_IdentityID
,因此需要將這兩個值都儲存在Person
表中?或者您會更新
Person
表格以顯示從“外國人”到“公民”的更改(即更改Person_Type
和Person_TypeID
)?
您能否將 CitizenIdentityID 和 ForeignWorkPermitID 消除到單個欄位並使用它來決定哪個表?假設使用帶有 C 或 F 的 varchar,然後是 ID 號。所以這封信會告訴你哪個表和 ID 號會告訴你哪條記錄。除非您在做數學運算,否則沒有理由將其作為整數進行。如果您想確保它被正確輸入,您可以為它建構一個驗證。這將為您擺脫一個領域。