3

I need some suggestions from the database design experts here.

  1. I have around six foreign keys into a single table (defect) which all point to primary key in user table. It is like:

    defect (.....,assigned_to,created_by,updated_by,closed_by...)
    

    If I want to get information about the defect I can make six joins. Do we have any better way to do it?

  2. Another one is I have a states table which can store one of the user-defined set of values. I have defect table and task table and I want both of these tables to share the common state table (New, In Progress etc.). So I created:

    • task (.....,state_id,imp_id,.....)
    • defect(.....,state_id,imp_id,...)
    • state(state_id,state_name,...)
    • importance(imp_id,imp_name,...)

There are many such common attributes along with state like importance(normal, urgent etc), priority etc. And for all of them I want to use same table. I am keeping one flag in each of the tables to differentiate task and defect. What is the best solution in such a case?

If somebody is using this application in health domain, they would like to assign different types, states, importances for their defect or tasks. Moreover when a user selects any project I want to display all the types,states etc under configuration parameters section.

4

2 回答 2

6

1 ...

这本身并没有什么错。如果可能的用户“角色”是严格确定的并且不太可能改变,那么这实际上是首选的方式。您正在有效地建模 C:M 关系,其中 C 是常数。

另一方面,如果角色可以改变(例如,您需要能够动态地向缺陷添加新的“生命周期阶段”),那么建模真正的 M:N 关系的链接(又名联结)表可能有道理。像这样的东西:

在此处输入图像描述

顺便说一句,虽然 JOIN 有其成本,但这本身并不意味着您负担不起。而且您甚至可能并不总是需要所有的 JOIN - 只需执行能够带来您当前需要的信息的 JOIN,而将其他信息排除在外。无论如何,我建议您测量实际数据量以确定是否存在实际性能问题。

2 ...

如果公共字段很多,可以使用继承1,尽量减少公共字段和外键的重复。例如:

在此处输入图像描述

在此模型中,每个“属性”表(例如stateimportance)仅与 连接一次base并通过它连接到每个“继承”表,例如defecttask。无论添加多少“继承”表,每个“属性”表仍然只有一个连接

defects这种模型基本上防止了“属性”FK 的扩散,代价是对和的管理更加繁琐tasks(因为它们现在分为“通用”和“特定”部分)。这是否比旧设计更好的平衡由您决定......


1阿卡。类别,子类,泛化层次结构等...

于 2012-06-29T09:58:13.403 回答
1

对于第一个问题,在我看来,您最好将缺陷表分解为一个“行”表,该表存储事务的历史记录,例如创建、更新、分配等。

这样做的好处是更灵活。一个缺陷可以更容易地跟踪被更新和分配给多个人、被重新打开等的历史,并清楚地表示出多次更新。

你的缺陷表仍然会存储缺陷的一些通用全局状态(可能是状态、优先级等,特别是如果你不需要跟踪这些状态的变化),你会有一系列的*defect_lines*,每个都有一个指向缺陷的外键,另一个指向用户的外键,以及一个类型字段,指示它是“创建”、“更新”等。

例如。

defect ( id, priority, status )
defect_line ( defect_id, timestamp, type, user, comment )

根据您所做的假设,defect_id、timestamp 和 user 可能是 defect_line 的主键。


对于第二个问题,至少根据您提供的信息,它们似乎共享所有相同的属性 - 所以基本上是相同的东西,具有不同的类型标志(“任务”或“缺陷”),所以为什么不只是有他们在同一张桌子上?

我可能会在假设所有缺陷都可以视为任务(“要修复的事情”)的情况下调用此任务,但所有任务都不是缺陷 - 但这现在都只是语义。

但是,如果存在不同的非共享属性,那么您可能会遇到这样的情况,即您可以在表中拥有任务/缺陷的共享属性,以及针对每个特定属性的表,尽管它们可能仍然能够共享相同的“线”细节结构。然后,这部分成为规范化和易用性之间的决定 - 拥有两个基本具有相同属性的表可能更容易,而不是将其分解为多个表。

于 2012-06-29T03:24:13.390 回答