2013-04-26 24 views
1

我正在尋找設計具有通用實體的數據庫的建議,這些通用實體要與多種不同的其他實體類型相關。可怕的介紹句子,我知道......所以請讓我以身作則。按表類型的數據庫設計建議

想想看,我有兩個不同的實體員工和客戶提供表DEFS:

Employees 
---------- 
EmployeeID int PK 
FirstName varchar 
LastName varchar 
... other Employee specific fields 

Customers 
---------- 
CustomerID int PK 
FirstName varchar 
LastName varchar 
... other Customer specific fields 

更好的設計可能具有共同的領域,名字和姓氏,在相關基本表,但是這不是一部分,我正在掙扎。現在

,考慮到我希望能夠存儲地址和PHONENUMBERS我的員工和客戶的數量不受限制,並定義表:

Addresses 
---------- 
AddressID int PK 
AddressLine varchar 
City varchar 
State varchar 
PostalCode varchar 

PhoneNumbers 
------------- 
PhoneNumberID int PK 
PhoneNumber varchar 
PhoneExtension varchar 

然後另外兩個表,相關地址和PHONENUMBERS對員工:

EmployeeAddresses 
------------------ 
EmployeeAddressID int PK 
EmployeeID int FK Employees.EmployeeID 
AddressID int FK Addresses.AddressID 
EmployeeAddressType enum 

EmployeePhoneNumbers 
--------------------- 
EmployeePhoneNumberID int PK 
EmployeeID int FK Employees.EmployeeID 
PhoneNumberID int FK PhoneNumbers.PhoneNumberID 
EmployeePhoneNumberType enum 

和兩個類似的表,CustomerAddresses和CustomerPhoneNumbers,對相關地址和PHONENUMBERS到Customers表。地址和電話號碼的任何員工特定或客戶特定方面(如上面的EmployeeAddressType)也位於最後四個表中。從我發現研究互聯網的角度來看,這種設計被稱爲按表格類型(TPT)或每個子類別表格(TPS)。多態優勢看起來很吸引人,例如,我可以將AddressLine2添加到地址表中,我的企業和客戶都會自動獲得額外地址行的好處。

這些TPT提供的缺點是查詢速度慢,難以實現。而現在我的相當開放式呼籲建議......

我還沒有考慮其他缺點嗎?您可以嘗試基於此設計來維護和發展應用程序?最後,最有經驗的數據庫設計師會使用上述設計嗎?

謝謝。

回答

0

員工和客戶都是People類的子類,如前面的回覆中所述。這兩個子類可能不是相互排斥的。

有一種叫做類表繼承的技巧。在這種技術中,將會有三個表,People,Employees和Customers。所有人共用的屬性,如地址,將存在於人員表中。

您可以通過訪問此標籤 並查看「Info」標籤下的詳細信息。

+0

感謝您的回覆。是的,班級表繼承聽起來更像我想的。看到我對HLGEM的迴應 - 我們直接向人們提供地址的問題在於,我有專門針對每個人的子類的地址專門化。 – splouie 2013-04-29 14:39:46

+0

如果您認爲這是正確的答案,即使您沒有獲得上傳的權利,也可以將其標記爲正確。 – 2013-04-29 19:39:17

+0

啊哈!將此響應標記爲正確,因爲它命名數據建模方法 - 類表繼承。此外,與HLGEM的這一建模策略相一致的是良好的信息和建議。感謝大家的反饋。 – splouie 2013-04-29 20:28:06

1
  1. 使用單表繼承來啓動。它是最簡單,最簡單,最快速的。

  2. 使用Party模型。個人和組織都是締約方,並且可以扮演客戶或員工的角色

  3. 將電子郵件地址,電話號碼,網站和郵寄地址都視爲「聯繫方式」或地址的子類型。

  4. 如果您使用的工具如JBoss Hibernate(java)或NHibernate(.net),那麼這會爲您完成大部分工作。

+0

+1用於暗示堅持單表繼承。 – Aheho 2013-04-26 18:43:13

+0

謝謝你的迴應,尼爾。我不熟悉單表繼承。說實話,我心中的C++程序員對於一個單一的全能表格的想法有些c c。但我可以想象它的簡單性,速度和易擴展性的好處,因此不得不考慮採取這種方法。再次感謝。 – splouie 2013-04-29 14:32:24

0

您是好得多開始一個人表,然後有客戶表,員工表等的電子郵件地址,地址和電話號碼,然後會涉及到百姓餐桌不是客戶或一些其他專業表。

與多父表相關的一個地址表的問題是,您無法設置正確的外鍵約束,並且將不可避免地以不良數據結束。

您可以正確創建外鍵,並使用單獨的表格進行查詢,但查詢會變得更加困難(假設您需要了解CA中的每個人),那麼會爲多個類別中的人員獲取重複記錄(員工也可能是客戶),並且在需要更改表結構時確保表全部更新很困難。

+0

謝謝HLGEM,我會在一個基本的人物桌上計劃。但是我將地址直接關聯到People表的問題是我有專門針對People的子類的地址專門化。例如,僅適用於客戶的地址記錄的「送貨」地址的CustomerAddressType。我如何獲得這個特定於子類的信息,並將地址直接關聯到People表? – splouie 2013-04-29 14:25:04

+0

您可以在用戶界面中執行該操作(如果不是用戶,則不允許用戶插入該地址類型的選項),也可以使用觸發器強制執行該操作。或者做兩個。 – HLGEM 2013-04-29 14:35:58

+0

明白了,謝謝!我會投票,但我缺乏名譽 – splouie 2013-04-29 14:43:13

0

當前數據庫設計的一個缺點是數據庫不會阻止員工擁有2個或更多的家庭地址。它也不會阻止客戶沒有地址。

您可以通過更改爲EmployeeAddresses表(PK = EmployeeID,EmployeeAddressType)上的複合主鍵來防止創建多個主地址。但是如果你使用的是ORM,當PK是一列時,它們中的許多隻會表現得很好。

+1

有點偏題,但你知道哪些ORM(s)與化合物PK有問題?我只使用Hibernate,而且我從來沒有遇到過問題。這似乎是ORM應該能夠處理的一件非常基本的事情。 – 2013-04-26 19:23:15

+0

從我所瞭解的情況來看,Hibernate是一些可以使用複合PK的ORM之一。我知道Massive,SubSonic,PetaPOCO,DJango都不支持它們。 – Aheho 2013-04-26 21:25:25

+0

好點,謝謝Aheho。 – splouie 2013-04-29 14:26:48