2013-10-03 69 views
0

我想設計一個表,其中包含部分,每個部分包含任務,每個任務包含子任務等。我想在一張桌子下面做。請讓我知道可擴展的最佳單表方法。我對數據庫設計相當陌生。另外請建議,如果單桌不是最好的辦法,那麼最好的辦法是什麼可以做到這一點。我正在使用db2。分層數據的表設計

+0

您應該花時間回答以下三(3)個答案中的任何一個,我相信這些答案可以解決您的問題。如果不這樣做,就會在未來從SO社區獲得體面的迴應而讓您失去吸引力。如果答案接近您的解決方案,您的願望或接近理想,請告訴海報。如果不是的話,那麼你至少可以指出回答你的問題的那個人應該關注哪個區域(並改善)。 – Edper

回答

0

有幾種方法可以做到這一點。

一個想法是使用兩個表:節和任務

可能有一到兩個之間的多對多關係。任務表可以設計爲具有TaskId和ParentTaksId的樹,這意味着您可以具有深度爲n級的任務(子任務或子任務的子任務等)。除根任務以外的每個任務都將有一個父項。

我想你也可以通過使用一個表格來解決這個問題,在這個表格中你只需要在上面描述的任務表中添加一個section列。

+0

您的最後一句話是相當不錯的,只是您沒有分欄而只有一個object_type列。部分,任務,子任務將是不同的對象ID。如果你願意,你也可以在以後添加更多的對象類,比如Story或Subsection。通過將所有內容放在同一張表中,您可以在存儲多少層級時獲得靈活性。但是,你無法使用外鍵來強制執行不同層級之間的關係,例如,任務永遠不會有子任務作爲父項。 –

0

如果您打算將所有內容放在一張表中,儘管從長遠來看,方便的方式效率不高。這意味着你將在你的數據庫中存儲不必要的重複數據組,這不會是處理器和內存友好的。它實際上違反了Normalization rules,並且更具體地說是1st Normal Form,它表示應該沒有可以在你的表中找到的重複組。它實際上也會違反3rd Normal Form這意味着不會有(非過渡)非主鍵與另一個非主鍵的依賴關係。

給你一個插圖,我會把你的設計放在一張桌子上。雖然我會猜測可能的領域,但只是忍受它,因爲這是爲了討論。看看下面的圖形:

enter image description here

如果你看看上面的圖形(雖然這是相當小的,你可以下載的圖片,看看它更接近自己),在SectionNameTasknameTaskInitiato R,TaskStartDateTaskEndDate是不必要的重複,正如我前面提到的違反1st Normal Form

其次,TasknameTaskInitiatorTaskStartDateTaskEndDate在功能上依賴於的TaskID這不是一個主鍵代替SectionID在這種情況下應該是主密鑰(如果在一個單獨的表)。這違反了第三範式,該第三範式說明不應該存在過渡依賴關係或非主關鍵字應當取決於另一個非主關鍵字。

雖然有些情況下您必須進行非歸一化處理,但我認爲這應該歸一化。根據我自己的估計,您的設計中應該包含三個表格,即Sections,TasksSubTasks,它們將會在下面顯示。

enter image description here

Section有關Tasks,就是一款可以有很多Tasks。 And TaskSub-Tasks有關,即,Task可能有許多Sub-tasks

1

說得很簡單,我會說使用1表的任務。

除了所有其他各種屬性之外,每個任務都應具有主標識符,而另一列可以包含其父任務的標識符。

如果您正在使用DB2 for z/OS,那麼您將使用recursive query with a common table expression。否則,您可以使用hierarchical recursive query in DB2 for i,或可能使用in DB2 for LUW(Linux,Unix,Windows)。

其他需要更多表格的設計,每個表格都專注於任務的某個部分:子任務關係,可能會不必要地引入問題或限制。

0

如果我理解正確的原始海報不知道,將需要多少層次的層次結構(因此「等等」)。他的問題是創建一個可以保持任何深度結構的設計。

Imho這是一個複雜的問題,沒有一個單一的答案。在實施這樣的設計時,您需要考慮以下因素:

結構是否相當穩定? (多少次寫入?) 該結構多久讀一次? 需要進行哪些操作? (獲取所有的孩子給定對象的對象?獲取父對象?得到直接孩子?)

如果結構將保持不變,您可以使用嵌套集模型(http://en.wikipedia.org/wiki/Nested_set_model

這樣的表有一個'左'和'右'欄。父對象的左右列包含其任何子對象的值。

這樣,你就可以使用這樣的查詢列表中的對象的所有孩子:

SELECT child.id 
FROM table AS parent 
JOIN table AS child 
    ON child.left BETWEEN parent.left AND parent.right 
    AND child.right BETWEEN parent.left AND parent.right 
WHERE 
    parent.id = @searchId 

這樣的設計可以非常快閱讀,但也極其昂貴當結構的變化(例如向任何對象添加子項時必須使用比所插入對象更高的「正確」值來更新任何對象)。

如果您需要能夠實時更改結構,您應該使用帶有兩個表格的設計 - 一個保存對象,第二個結構(像parentId,childId,differenceInHierarchyLevels)。