如何设计SQL表以允许多个父表选项?

时间:2009-08-13 19:00:46

标签: sql database-design

考虑在报告层次结构中创建一系列表格,或多或少地绘制空白。

虽然此结构中的表只能有一个父项,但如何构造字段以使它们指向正确的父表?正如您在下面的示例中所看到的,行的父表可以有所不同。

                  ARRANGEMENT
                  /           \
           MATTERS            ISSUES 
              |                     |
            PHASES                MATTERS
          /       \                 |
     ISSUES      TASKS            PHASES
     /    \        |             /      \
 TITLES  TASKS   ISSUES       TASKS    TITLE  
           |        |           |
        TITLES   TITLES       TITLE 

基本上,最好让每个“分支”都有一个唯一的表(即使分支1中的任务与分支2或3具有相同的数据结构),或者最好让记录标识哪个表是他们的父?

Arrangement(ID)
Matters(ParentTable, ParentID, ID)
Phases(ParentTable, ParentID, ID)
Issues(ParentTable,ParentID, ID)
Titles(ParentTable,ParentID, ID)
Tasks(ParentTable,ParentID, ID)

以上对我来说似乎并不合适。帮助

4 个答案:

答案 0 :(得分:3)

我有两个意见。您必须清楚这些“多态”实体的含义。它们在语义上是不同的吗?即使它们看起来相同,如果它们用于不同的目的,您也可能不希望将它们放在同一个表中。


如果一个问题在安排和问题之间是真实的,语义上可互换的,那么我建议使用一种“映射”表:

Arrangement(ID)
Matters(ID)
Issues(ID)
ArragementMatters (FK_ArrangementID, FK_MatterID)
IssueMatters (FK_IssueID, FK_MatterID)

您可以在“多态”表中继续使用此模式。

如果需要,您可以在FK_MatterID列上添加唯一约束。

编写查询很容易:

Select * from Arrangement a 
inner join ArrangementMatters am on am.FK_arrangementID = a.ID
inner join Matters m on m.ID = am.FK_matterID

让您的所有事项与安排相关联。


另一方面,如果Matter under和Arrangement在语义上不可替代并且只有相同的模式,那么我建议创建完全独立的表:

Arrangement(ID)
ArrangementMatters(ID, FK_ArrangementID)
Issues(ID)
IssueMatters(ID, FK_IssueID)

这传达了与世界的区别。如果您可以分开您的顾虑,它会给您带来很多好处。 (也许你对IssueMatters和ArrangementMatters有很多大量使用 - 你可以独立地优化索引和表格布局。)

查询也更简单:

Select * from Arrangement a 
inner join Matters m on m.FK_arrangementID = a.ID

答案 1 :(得分:1)

你不能真的这样做 - 至少在我所知道的任何RDBMS中都没有,如果你使用参照完整性(外键关系),因为那些总是必须引用一个且只有一个父表 - 你不能拥有FK在一种情况下引用父表A而在另一种情况下引用父表B的关系。

在你的具体案例中,“标题”可能是“阶段”或“任务”的子项,解决这个问题的一种方法是为那些应该是直接的“标题”条目设置一个“虚拟”任务“阶段”表的孩子们。

从长远来看,任何其他事情都会成为黑客和噩梦。

马克

答案 2 :(得分:1)

我已经看到在关系数据库中以这种方式处理的各种类型(不仅仅是父关系)的多态关联。我会说继续使用`ParentTable,ParentID'方法。

缺点是您将无法在数据库级别强制执行参照完整性(即使用外键),除非您使用的是一个框架,否则获取关联将会更多一些工作。为你做腿部工作(例如,Rails)。但是,如果你真的需要多态关联,我不知道这些并发症有什么好办法。

答案 3 :(得分:0)

你可以拥有一张带有ID& PARENTID。
顶级行(Arrangement)将具有NULL ParentID。