2017-09-10 55 views
0

例如。在我的系統中,我有一個對象被其他幾種類型的對象以1對1的關係使用。讓我們調用使用Address的對象,以及使用它的兩個對象Company和Person。每個公司和個人都有一個地址,每個地址在系統中都是唯一的,因此每個地址都由個人或公司引用。1對1與超過2個表的關係

我有兩個問題。

問題1)這個關係叫什麼?我在網上找到的1對1關係的所有例子都只在兩個表之間,而這是三對一的關係。

問題2)什麼樣的表結構最好地捕獲了這種關係?我發現至少有兩種看起來有缺陷的潛在設計。

設計a)使用兩個可爲空的外鍵,約束條件是至少有一個不爲空。就像一個複合外鍵。

- Company - 
pkCompanyId 
... 

- Person - 
pkPersonId 
... 

- Address - 
pkAddressId 
fkPersonId <nullable> 
fkCompanyId <nullable> 
... 

設計b)每個公司和個人識別它使用的地址。

- Company - 
pkCompanyId 
fkAddressId 
... 

- Person - 
pkPersonId 
fkAddressId 
... 

- Address - 
pkAddressId 
... 

設計一)似乎是一個更傳統的使用外鍵我在正在使用的對象標識引用它的對象,但我還沒有看到任何的例子是與做多這樣的外鍵。

設計b)看起來像是正常建模1對1關係的反過程。

在我看來,在常規的1對1關係(下面)中,fkPersonId是一個不可爲空的唯一外鍵有助於在實際表結構中強制執行1對1關係(它保證每個地址被一個沒有引用其他地址的Person引用)。我的設計都沒有達到這個目標。在設計中a)必須確保fkCompanyId或fkPersonId中的一個且僅有一個爲空以確保一致性。在設計b)中,必須確保公司或人員中的任何fkAddressId都不在任何表中重複。這使我懷疑我在這裏犯了一個錯誤。

- Person - 
pkPersonId 
... 

- Address - 
pkAddressId 
fkPersonId 
... 

沒有太多的精力,我可以看到其他的設計,例如使用guid作爲pkCompanyId和pkPersonId以及Address中的單個外鍵,但我再次在我所研究的任何在線資源中看不到任何此策略的示例。

我已經明顯超出了我對數據庫設計的有限知識,可以使用一些指導。處理這個問題的最好方法是什麼?

更新響應沃爾特米蒂的回答

我認爲單個表繼承不適合我的情況。儘管我在這裏使用了公司和人員的例子,但在我的真實應用程序中,這些都是大型複雜表格,除了它們都擁有地址之外,沒有任何共同之處。他們的數據不僅非常不同,而且代表完全不同的概念。

我的每個具有相同類型實例的實際實體都是Organization,Project和ProjectElement。組織代表許可使用系統的公司。項目表示由特定組織的用戶創建的項目,ProjectElement表示一段項目數據。

他們都有一個實例的東西是一個設置對象。默認設置在組織級別提供。創建項目時,會獲取組織設置的副本。項目中的組件獲得項目設置的副本。

此體系結構支持多種用例,包括何時修改組織的設置時,這些更改僅影響新項目,而不影響已創建的項目。 ProjectElement繼承了Project的設置,但可以選擇覆蓋特定的Project設置。

更進一步的複雜性包括組織,項目和ProjectElement不僅僅具有一個共享類型的實例,而是幾個。有幾種不同類型的設置對象,每個都有自己的表格。如果不能使用共享類型的實例的ID作爲引用對象的主鍵,則這使得它變得尷尬。我也在使用目前不支持視圖的實體框架核心ORM。

你的答案非常有用,給了我很多思考,但到目前爲止,似乎我的設計2最好的實現了我的要求。設計2有什麼內在不合理的地方讓它不適合?

+0

當然。我的建議是基於你最初提出的簡單案例。 –

回答

1

你的問題看起來像一個類型和子類型(或類和子類)的情況。在我嘗試處理你的兩個問題之前,我將嘗試重新構建它,然而,作爲兩個關係。

首先,我要發明一個新的實體,我將其稱爲「聯繫人」。系統中的每個地址都由聯繫人引用,每個聯繫人都有一個或多個地址。

每個聯繫人都是一個人或一個公司,但不是兩個。

現在,至少在概念上,我們首先將地址與聯繫人連接,然後將該聯繫人與個人或公司聯繫起來。在邏輯和物理層面上,這可能是矯枉過正的。也就是說,它可能會增加複雜性而不增加價值。我無法強調這一點。

但概念清晰度對其本身是有價值的。

現在對你的問題1.

聯繫人和地址之間的關係僅僅是一個典型的「有-A」式的關係,就像很多你以前見過。

但是,聯繫人與個人或公司之間的關係是一種不同的關係,您可能以前從未見過。它被稱爲各種名稱,這是我對您的問題的答案1.

它有時被稱爲正是「IS-A關係」。在ER建模中,它通常被稱爲「專業化/泛化」關係。在對象建模中,雖然常常使用流行語「派生類」或「擴展類」,但它通常被稱爲「類/子類關係」。它也與繼承的對象概念有關。

然而,關於對象建模的警告一句話。如果您打算在同一個項目中進行對象建模和數據建模,那麼最好對它們有更深入的瞭解,以及它們是如何爲您的項目增加價值的。否則,你很可能陷入這樣的陷阱:認爲一個模型或另一個模型簡直是無法理解或無用。比我更聰明的人多次陷入這個陷阱。

現在是第二個問題。有兩種方法可以爲這種情況設計表格。一個稱爲「單表繼承」,另一個稱爲「類表繼承」。我把連字符放進去的原因是這兩個主題在這個區域有標籤,並且查看這兩個標籤下的問題和信息可能會對您有所幫助。

單表繼承。

我們將有兩個表格,一個用於地址,另一個用於聯繫人。

地址:

AddressID (PK) 
ContactID (FK references Contact) 
Street Address 
City, 
State, 
Zipcode, 
etc. 

聯繫人:

ContactID (PK) 
ContactType (Person or Company, coded) 
First Name 
Last Name, 
Company Name, 
etc. 

公司名稱將是人的情況下,NULL,姓氏,名字將在公司的情況下,NULL)。

類表繼承

我們將有四個表,地址,聯繫方式,個人和公司

地址:

AddressID (PK) 
ContactID (FK references Contact) 
Street Address 
City, 
State, 
Zipcode, 
etc. 

聯繫人:

ContactID (PK) 

人:

ContactID (PK, and FK references Contact) 
First Namme, 
Last Name, 
etc. 

公司:

ContactID (PK and FK references Contact) 
Company Name 
etc. 

對於你的情況,我建議單表繼承。但是對於非常複雜的IS-A關係來說,類表繼承可以更好地工作。

+0

已在我的操作系統更新中回覆。 – Neutrino