单个表的多个外键和指向多个表的单个键

时间:2012-06-28 02:43:01

标签: database-design join foreign-keys self-join

我需要数据库设计专家的一些建议。

  1. 我有大约六个外键进入一个表(缺陷),它都指向用户表中的主键。它就像:

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

    如果我想获得有关缺陷的信息,我可以进行六次连接。我们有更好的方法吗?

  2. 另一个是我有一个states表,可以存储一个用户定义的值。我有缺陷表和任务表,我希望这两个表共享公共状态表(New,In Progress等)。所以我创建了:

    • task (.....,state_id,imp_id,.....)
    • defect(.....,state_id,imp_id,...)
    • state(state_id,state_name,...)
    • importance(imp_id,imp_name,...)
  3. 有许多这样的共同属性以及状态如重要性(正常,紧急等),优先级等。对于所有这些,我想使用相同的表。我在每个表中保留一个标志以区分任务和缺陷。在这种情况下,最佳解决方案是什么?

    如果有人在健康域中使用此应用程序,他们希望为其缺陷或任务分配不同的类型,状态,重要性。此外,当用户选择任何项目时,我想在配置参数部分下显示所有类型,状态等。

2 个答案:

答案 0 :(得分:6)

  

1 ...

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

另一方面,如果角色可以更改(例如,您需要能够动态地向缺陷添加新的“生命周期阶段”),然后是链接(也称为联结)表建模真正的M:N关系可能是合理的。像这样:

enter image description here

顺便说一下,虽然JOIN有他们的成本,但这本身并不意味着你买不起。并且可能甚至不需要所有的JOIN - 只需执行带有您当前所需信息的JOIN,并将其他人留下。无论如何,我建议您对实际数据量进行度量,以确定是否存在实际性能问题。

  

2 ...

如果有许多常用字段,则可以使用继承 1 来最小化公共字段和外键的重复。例如:

enter image description here

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

这个模型基本上可以防止“属性”FK的扩散,因为taskdefects的管理稍微麻烦一些(因为它们现在被拆分为“共同”和“特定”部分)。这是否比旧设计更好的平衡是你决定...


1 Aka。类别,子类,泛化层次等......

答案 1 :(得分:1)

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

这具有更灵活的好处。缺陷可以更容易地跟踪更新的历史记录并分配给多个人,重新打开等,并通过时间清晰地表示多个更新。

您仍然有缺陷表存储缺陷的一般常规状态(可能是状态,优先级等,特别是如果您不需要跟踪这些状态的变化),你将有一系列* defect_lines *,每个都有一个指向缺陷的外键,另一个外键指向用户,还有一个< em> type 字段,指示它是“创建”,“更新”等。

例如

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

根据你做得很好的假设,defect_id,timestamp和user可能是defect_line的主键。


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

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

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