2009-08-13 52 views
0

研究在報告層次結構中創建一系列表,並且或多或少地繪製空白。如何設計SQL表以允許多個父表選項?

雖然在這個結構表只能有一個家長,我怎麼結構中的字段,以便它們指向正確的父表?正如你在下面的例子中看到的那樣,行的父表可以不同。

    ARRANGEMENT 
       /   \ 
      MATTERS   ISSUES 
       |      | 
      PHASES    MATTERS 
     /  \     | 
    ISSUES  TASKS   PHASES 
    / \  |   / \ 
TITLES TASKS ISSUES  TASKS TITLE 
      |  |   | 
     TITLES TITLES  TITLE 

從本質上講,是它最好有每個「分支」有一個唯一的表(即使在分支1任務具有相同的數據結構分支2或3),或者是它最好有記錄識別哪張桌子是他們的父母?

Arrangement(ID) 
Matters(ParentTable, ParentID, ID) 
Phases(ParentTable, ParentID, ID) 
Issues(ParentTable,ParentID, ID) 
Titles(ParentTable,ParentID, ID) 
Tasks(ParentTable,ParentID, ID) 

上述對我來說看起來並不正確。幫幫我?

回答

0

你可以有ID & PARENTID 1臺。
頂級行(排列)將具有NULL ParentID。

+0

這並不真正幫助我知道哪個表是parentid所指的。 – tsarstruck 2009-08-13 19:09:39

+0

我在說你不應該有單獨的表格。全部都有一張桌子。我很抱歉,如果我沒有得到全面的照片。 – shahkalpesh 2009-08-13 19:15:59

+0

感謝您的答覆,無論如何。這將解決層次問題,但不會指出應鏈接哪些表。 – tsarstruck 2009-08-13 19:59:41

1

你不能真正做到這一點 - 至少在我所知道的任何RDBMS,如果您使用參照完整性(外鍵關係),因爲那些總要引用一個和一個父表 - 你不能有在一種情況下引用父表A和在另一種情況下引用父表B的FK關係。

在您的具體情況下,如果「標題」可能是「階段」或「任務」的子項,則解決此問題的一種方法是爲那些「標題」條目設置一個「虛擬」任務「階段」表的直接子女。

任何東西都不會是一個黑客和一個噩夢,從長遠來看,以保持。

馬克

1

我所看到的各種排序(不只是父母的關係)的多態關聯處理關係數據庫的方式。我會說繼續並使用`ParentTable,ParentID'方法。

缺點是您無法在數據庫級別強制引用完整性(即使用外鍵),並且除非您使用的是一個框架會爲你做一些運動(比如Rails)。但是,如果你真的需要多態關聯,我不知道解決這些問題的好方法。

+0

嗯,它確實是一個純粹的SQL框架,所以所有的工作都是我的。真正的缺點(除了參照完整性問題),我認爲這種方法將是你需要構建來訪問數據的SQL語句。 – tsarstruck 2009-08-13 19:26:01

3

我有兩個看法。你必須清楚這些「多態」實體的含義。它們在語義上是不同的並且是分開的?即使它們看起來一樣,但如果它們用於不同的目的,您可能不希望將它們放在同一張表中。


如果事情是真的,安排與問題之間的語義可替代的,那麼我建議使用的「映射」表格形式:

Arrangement(ID) 
Matters(ID) 
Issues(ID) 
ArragementMatters (FK_ArrangementID, FK_MatterID) 
IssueMatters (FK_IssueID, FK_MatterID) 

您可以繼續在「多態的這種模式「表格。

如果需要,可以在FK_MatterID列添加一個唯一約束。

可以很容易地編寫查詢:

Select * from Arrangement a 
inner join ArrangementMatters am on am.FK_arrangementID = a.ID 
inner join Matters m on m.ID = am.FK_matterID 

獲得與安排有關的所有事項的。


在另一方面,如果在和安排的問題不能互換的語義,只有具有相同的架構,那麼我建議建立完全獨立的表:

Arrangement(ID) 
ArrangementMatters(ID, FK_ArrangementID) 
Issues(ID) 
IssueMatters(ID, FK_IssueID) 

這傳達的區別致全世界。如果你能分開你的顧慮,它會給你很多好處。 (即也許你有很多IssueMatters與ArrangementMatters的大量使用的 - 你可以獨立優化索引和表的佈局。)

查詢也更簡單:

Select * from Arrangement a 
inner join Matters m on m.FK_arrangementID = a.ID 
+0

傑夫, 首先,謝謝你的迴應。在想了一下之後,我不認爲它們在語義上是可替換的。 ultiamte應用程序是預算編制。例如,如果某個任務是「問題」的祖父母,則該任務需要每個任務的美元預算金額。然而,如果任務是一個階段的孩子,那麼_issue_將需要預算金額,而任務不會(因爲它的工作將是將任務指向正確的問題管理結構)。 – tsarstruck 2009-08-13 19:54:06

相關問題