2016-05-17 54 views
3

我需要設計我的數據庫表的幫助。設計條件關係

員工
編號
EmployeeTypeId

EmployeeType
編號
名稱

汽車
編號
僱員

我該如何強制在Car表中只有一種類型的員工(司機)可以是外鍵?還是我應該重新設計表格?

+0

我認爲這取決於你的rdbms。在Sql服務器中,你不能只用外鍵約束來完成它,你必須在Car表中添加一個檢查約束來檢查EmployeeType。其他數據庫可能有其他解決方案(例如,我知道MySql沒有強制檢查約束,所以你將不得不想出一個不同的解決方案)。 –

+1

對我來說,這聽起來像是一個商業規則,我傾向於試圖將業務邏輯放在數據庫之外,以及業務層和/或CRUD操作中。 – Kritner

+0

而我另一方面喜歡在數據庫中有業務規則。一旦數據庫阻止不合理的插入,您就不會犯錯導致不一致的數據。如果你錯誤地想輸入園丁爲公司開車的車,你會得到一個例外。然而,在所給定的星座中執行此操作並不容易。 –

回答

2

我認爲這是一個好主意,前臂的數據庫,使不合情理的數據不能輸入。在這裏執行這一點,但是,是一個有點棘手...

解決方案1:

添加EmployeeTypeId的車表。然後爲Employee表創建(EmployeeId,EmployeeTypeId)外鍵(您可能必須在兩個字段上創建唯一約束,以便能夠將它們用於外鍵引用)。然後在Car.EmployeeTypeId上添加一個約束,以確保它是一個驅動程序。我知道這看起來多餘,但它確實沒有問題,因爲您不能在此處爲Employee分配另一個EmployeeType,所以一致性仍然有保證。但我承認這種方法有點笨拙。

解決方案2:

使用上車表之前,插入跳跳虎,查找員工,並確保它是一個驅動程序,否則拋出異常。在我看來,這是一個更好的解決方案,因爲它的簡單性。然後,您可以在表Car中添加一列,併爲您使用的類型保存一個唯一的名稱,例如UniqueName ='DRIVER',所以你不必使用ID作爲幻數。你看,通常一個EmployeeType與數據庫中的另一個是好的。如果你想在某個條目上構建特殊的邏輯,你需要一個處理這個。唯一的名字是這樣做的一種方式,一個IsDriver = TRUE/FALSE標誌將是另一個。

+1

如果汽車司機必須參與一些特定的關係,我最好創建子類型實體。關於觸發器選項注意一個也需要觸發員工更新來捕捉這個人不再是驅動程序,但仍然從汽車引用。 – Serg

+0

在FOREIGN KEY中引用UNIQUE約束不是不好的做法嗎? – user49126

+0

對不起,如果不明確。 * parent *表具有唯一的一列或一組列。cild表中的外鍵引用此列或這組列。 –