我正在尝试设计一个包含部分的表,每个部分包含任务,每个任务包含子任务等等。我想在一张桌子下做。请让我知道可扩展的最佳单表方法。我对数据库设计很陌生。另外请建议如果单表不是最好的方法,那么最好的方法是什么。我正在使用 db2。
4 回答
简而言之,我会说使用 1 个表来执行任务。
除了所有其他各种属性之外,每个任务都应该有一个主标识符,以及另一个可选地包含其父任务标识符的列。
如果您使用 DB2 for z/OS,那么您将使用带有公用表表达式的递归查询。否则,您可以在 DB2 for i或可能在 DB2 for LUW(Linux、Unix、Windows)中使用分层递归查询。
其他需要更多表的设计,每个表专门处理任务的某个部分:子任务关系,可能会不必要地引入问题或限制。
如果你打算把所有东西都放在一张桌子上,虽然从长远来看很方便,但效率很低。这意味着您将在数据库中存储不必要的重复数据组,这对处理器和内存完全不友好。它实际上会违反规范化规则,更具体地说,1st Normal Form
它表示不应该在您的表中找到重复组。它实际上也违反了3rd Normal Form
这意味着非主键对另一个非主键没有(过渡)依赖性。
为了给你一个例子,我会把你的设计放在一张桌子上。虽然我会猜测可能的领域,但请耐心等待,因为这是为了讨论。看下图:
如果您查看上面的图形(尽管这相当小,您可以下载图像并自己仔细查看),SectionName
, Taskname
, TaskInitiato
rTaskStartDate
和TaskEndDate
是不必要的重复,正如我之前提到的违反1st Normal Form
.
其次,,Taskname
和在功能上依赖于不是主键的 TaskID 而不是 SectionID ,在这种情况下应该是主键(如果在单独的表上)。这违反了第三范式,即不应该有过渡依赖或非主键应该依赖于另一个非主键。TaskInitiator
TaskStartDate
TaskEndDate
虽然有些情况下你必须去规范化,但我相信这个应该被规范化。在我自己的估计中,您的设计中应该包含三个表,即 ,Sections
并且Tasks
与SubTasks
下面的表类似。
Section
与 相关Tasks
,即一个部分可以有多个Tasks
。与Task
相关Sub-Tasks
,即一个Task
可以有很多个Sub-tasks
。
有几种方法可以做到这一点。
一种想法是使用两个表:Sections 和 Tasks
两者之间可能存在一对多的关系。任务表可以设计为具有 TaskId 和 ParentTaksId 的树,这意味着您可以拥有深入 n 级的任务(子任务的子任务 og 子任务等)。除了根任务之外的每个任务都有一个父任务。
我想你也可以通过使用一个表来解决这个问题,你只需在上面描述的任务表中添加一个部分列。
如果我理解正确,原始发帖人不知道,需要多少层次的层次结构(因此是“等等”)。他的问题是创造一种可以容纳任何深度结构的设计。
恕我直言,这是一个没有单一答案的复杂问题。在实施这样的设计时,您需要计算以下因素:
结构会相当稳定吗?(多少次写入?)这个结构多久会被读取一次?哪些操作需要成为可能?(获取给定对象的所有子对象?获取父对象?获取直接子对象?)
如果结构保持不变您可以使用嵌套集模型(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)。