2015-04-27 158 views
0

在設計關係型數據庫時,如果我設計的設計變得更加簡單,那麼我的腦海中就有了這樣的問題。 該設計包括4個表:(簡化的)關係數據庫設計問題

  • 位置
  • 辦公室
  • 學校
  • 組的學校

ERD PK =主鍵, FK =外鍵

比方說我們想要得到有關位置的詳細信息。如果該地點是一所學校,我們希望看到其名稱,學生數量和學校組的名稱。如果是辦公室,我們只想看看辦公室的名稱。 隨着目前的設計,這是不可能做在1查詢(我的知識)。

問題: 有沒有更好的方法來設計這個數據庫,這樣我就可以在1個查詢中獲得所需的位置細節。

雖然可能有辦法在1個查詢中獲取這些詳細信息,但我更感興趣的是增強數據庫設計。

由於提前, Knarfi

答:我終於發現,我描述的問題術語:多態關聯。特別是this question給了我一個很好的答案。

回答

1

你可以嘗試這樣的事情

SELECT location.*,school.*,office.* 
FROM location 
LEFT JOIN school ON school.locationID=location.locationID 
LEFT JOIN office ON office.locationID=location.locationID 

在結果你會爲學校的字段NULL值是否會有辦公室,反之亦然。但是你必須在你的應用程序中檢查這個,並在那裏做出決定 - 數據庫向你發送所有數據。

+0

雖然這是有用的,我真的希望不會在應用程序中做出這些決定。所以我真的希望增強數據庫,因爲我真的認爲這個當前的設置有點笨拙。 – Frank

1

您可以合併學校和辦公室,以一個實體,比如:組織具有以下屬性:

  • 的organization_ID(PM)
  • 類型(1 =學校,2 =辦公室)
  • LOCATION_ID( FK)
  • GROUP_ID(FK)(它可以有值僅適用於學校,除非你想添加組信息辦公室太例如:在表組會計,銷售等)
  • 名稱
  • NumOfMembers (它可以適用於學校和辦事處)

關於你的最後一個問題:「雖然有可能是一種方式來獲得在1個查詢這些細節,我更感興趣的是加強數據庫設計。「我必須說,這不是一個設計問題,而是一個實現問題。請記住,根據您的實施需求更改設計是一種非常糟糕的做法。

在任何情況下,您都可以在兩種情況下使用ONE查詢(您的和我的)查看其他人的答案。 tIp:嘗試使用視圖...在這種情況下它們是有用的。

+0

我想到了很多合併表的方法,但問題是組織實體不適合設計。該數據庫是針對一組學校的,因此一個organistatoin實體並不適合數據庫。 而你說得對,事實上它只是一個實現的問題:) – Frank

1

數據庫設計不會限制location同時與schooloffice相關。 (可能是多所學校和/或多個辦公室。)

有幾種可能的方法檢索與location相關的信息。

這裏有一個辦法:

SELECT 'school' AS source 
    , s.name 
    , s.students 
    , g.name AS school_group_name 
    FROM location sl 
    JOIN school s 
    ON s.location_id = sl.id 
    LEFT 
    JOIN group_of_schools g 
    ON g.id = s.group_id 
UNION ALL 
SELECT 'office' AS source 
    , o.name 
    , NULL 
    , NULL 
    FROM location ol 
    JOIN office o 
    ON o.location_id = ol.id 

如果您需要限制到一組特定的位置,你需要在每個SELECT添加WHERE條款。

如果您希望以特定順序返回行,請添加ORDER BY

+0

我喜歡這種方法,但我更關心你指出的第一個事實,現在一個位置可以是學校和辦公室......你知道解決這個問題的方法嗎?我認爲這是我期待的改善! – Frank

+1

有幾種將繼承層次結構映射到關係表的方法;每種方法都是優點和缺點,最好的選擇取決於你的用例。根據您提問中的信息,將地點,學校和辦公室合併到一張表格中可能是一種合適的方法。添加一個鑑別器列(用於指示某個位置是「school」子類的實例,「office」子類的實例還是僅僅是「location」超類的實例,併爲每個子類特定的屬性添加列。 .. – spencer7593

+1

我建議Scott Ambler的文章回顧O/R映射方法,以處理OO類層次結構和關係數據庫表之間的「阻抗不匹配」:[** http://www.agiledata.org/essays/mappingObjects .html **](http://www.agiledata.org/essays/mappingObjects.html)(例如,在你現在的模型中,你可以在'school'和'office'中使'location_id'唯一,但是在數據庫中沒有聲明性約束來防止位置既是學校也是辦公室) – spencer7593