考虑在报告层次结构中创建一系列表格,或多或少地绘制空白。
虽然此结构中的表只能有一个父项,但如何构造字段以使它们指向正确的父表?正如您在下面的示例中所看到的,行的父表可以有所不同。
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)
以上对我来说似乎并不合适。帮助
答案 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。