0

我正在尝试设计一个包含部分的表,每个部分包含任务,每个任务包含子任务等等。我想在一张桌子下做。请让我知道可扩展的最佳单表方法。我对数据库设计很陌生。另外请建议如果单表不是最好的方法,那么最好的方法是什么。我正在使用 db2。

4

4 回答 4

1

简而言之,我会说使用 1 个表来执行任务。

除了所有其他各种属性之外,每个任务都应该有一个主标识符,以及另一个可选地包含其父任务标识符的列。

如果您使用 DB2 for z/OS,那么您将使用带有公用表表达式的递归查询。否则,您可以在 DB2 for i或可能在 DB2 for LUW(Linux、Unix、Windows)中使用分层递归查询。

其他需要更多表的设计,每个表专门处理任务的某个部分:子任务关系,可能会不必要地引入问题或限制。

于 2013-10-04T06:14:49.600 回答
0

如果你打算把所有东西都放在一张桌子上,虽然从长远来看很方便,但效率很低。这意味着您将在数据库中存储不必要的重复数据组,这对处理器和内存完全不友好。它实际上会违反规范化规则,更具体地说,1st Normal Form它表示不应该在您的表中找到重复组。它实际上也违反了3rd Normal Form这意味着非主键对另一个非主键没有(过渡)依赖性。

为了给你一个例子,我会把你的设计放在一张桌子上。虽然我会猜测可能的领域,但请耐心等待,因为这是为了讨论。看下图:

在此处输入图像描述

如果您查看上面的图形(尽管这相当小,您可以下载图像并自己仔细查看),SectionName, Taskname, TaskInitiatorTaskStartDateTaskEndDate是不必要的重复,正如我之前提到的违反1st Normal Form.

其次,,Taskname和在功能上依赖于不是主键的 TaskID 而不是 SectionID ,在这种情况下应该是主键(如果在单独的表上)。这违反了第三范式,即不应该有过渡依赖或非主键应该依赖于另一个非主键。TaskInitiatorTaskStartDateTaskEndDate

虽然有些情况下你必须去规范化,但我相信这个应该被规范化。在我自己的估计中,您的设计中应该包含三个表,即 ,Sections并且TasksSubTasks下面的表类似。

在此处输入图像描述

Section与 相关Tasks,即一个部分可以有多个Tasks。与Task相关Sub-Tasks,即一个Task可以有很多个Sub-tasks

于 2013-10-03T06:08:52.863 回答
0

有几种方法可以做到这一点。

一种想法是使用两个表:Sections 和 Tasks

两者之间可能存在一对多的关系。任务表可以设计为具有 TaskId 和 ParentTaksId 的树,这意味着您可以拥有深入 n 级的任务(子任务的子任务 og 子任务等)。除了根任务之外的每个任务都有一个父任务。

我想你也可以通过使用一个表来解决这个问题,你只需在上面描述的任务表中添加一个部分列。

于 2013-10-03T04:11:29.210 回答
0

如果我理解正确,原始发帖人不知道,需要多少层次的层次结构(因此是“等等”)。他的问题是创造一种可以容纳任何深度结构的设计。

恕我直言,这是一个没有单一答案的复杂问题。在实施这样的设计时,您需要计算以下因素:

结构会相当稳定吗?(多少次写入?)这个结构多久会被读取一次?哪些操作需要成为可能?(获取给定对象的所有子对象?获取父对象?获取直接子对象?)

如果结构保持不变您可以使用嵌套集模型(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)。

于 2013-10-08T17:52:45.367 回答