将多个和一个多个表示为单个非规范化视图,作为多对多或其他方式?

时间:2011-02-15 19:24:56

标签: database-design schema database-schema

我有一个模型问题,后面是一个单独的SO帖子中的视图问题,我将在创建它时链接到该帖子。我正在发两个帖子,所以我可以做两个接受。

现在,让我们假设我有以下架构。这是我正在设计的真实模式的简化版本,省略了不相关的列。名字已经改变,以保护无辜和我的工作。

tree具有以下属性。

tree.id
tree.dob
tree.height    
tree.forestid

forestidforest表的外键,它只是聚合多个tree行的一种方法。它有一个id列和一些元数据列。

treeforest都有可能有多个treedata行。 treedata包含

treedata.value
treedata.treeid
treedata.forestid

treedata.treeid和treedata.forestid受约束,因此两者中的一个必须为空。

如果tree.forestid不为null,那么treedata和tree之间的关系是多对多的,而forest是链接器表。否则,树和树木之间的关系是一对多的。对于我的应用程序来说,用户能够通过UI动态地将树组合成森林,并为整个森林设置treedata.value,同时也能够处理单个树,这一点非常重要。现在,我可以想出几种方法来代表这一点。一个是说每棵树都有一个森林,并且是一个至少大小为1的森林。然后,这种关系总是很多很多。另一种是沿着

的线提供非规范化的视图
select tree.*, treedata.* 
from tree, treedata
where tree.id = treedata.treeid 
union 
select tree.*, treedata.*,
from tree, treedata
where tree.forestid = treedata.forestid.  

然而第三种方法是在forestid中添加tree列并完全删除forest表。沿着这条路走下去,我发现在tree.forestid的正确递增方面难以获得ACID保证。森林也有可能包含自己的元数据。我希望能够有更多的方法来表达这一点,并且想要了解更多经验丰富的数据库人员对于哪种方式更可取的意见,以及如果您通过引用自己的经验来解释为什么这么认为,那么最高分。 / p>

回应Martin Dom对TreeComposite表的建议:

感谢您的回复。在响应之前,我想在一天之内给出一个TreeComposite的建议。首先,你的方式确实模仿我正常表达的关系,所以是的,我认为你确实理解了这个问题。但是,我认为通过命名我的表树和森林来犯了一个愚蠢的错误:因为森林不需要递归地相互组合。它们不是计算机科学树。它们只是树皮和树枝。 parentid模型,虽然它仍然代表我需要的正常形式(这是我需要的概括),虽然它具有树木和森林现在是“相同的东西”的优势,表面上是一个复杂的胜利我担心在土壤中它会变得混乱。

问题在于,无论它们在我的模型中被称为相同的东西,它们对我的控制器或视图来说都不是一回事。 E.G.,具有子节点的TreeComposite可能至少具有每个节点将具有不同值的属性。在这种情况下,我需要在视图中使用不同的小部件来显示属性的多个值。换句话说,我需要能够将每个TreeComposite作为它自己的父显示为单行,并且该行的外观取决于TreeComposite是否有子项。

因此,在从模型中提取TreeComposite后,我要做的第一件事就是决定它是“真的”树还是森林。为什么这样,当我可以直接将它以正常形式存储为树和森林时,从而使我的视图和控制器更简单而不会伤害我的模型?父子关系也会使搜索TreeData变得复杂。我必须通过N个TreeComposites连接,直到找到根节点,然后搜索指向根节点的TreeData。这破坏了数据的位置。同时,如果我有一个带有ForestID的Tree,并且我想要Tree的数据,我根本不需要查看Forest表。我可以做一个直接的外键< - > foreignkey加入TreeData。 (where Tree.ForestID = TreeData.ForestID)。

1 个答案:

答案 0 :(得分:2)

复合结构怎么样?假设你有表TreeComposite,它有一个指向另一个TreeComposite的TreeComposite.ParentId外键。 TreeData只能引用单个TreeComposite,因此保留了仅引用林或单个树的约束。

我看到的唯一问题是你可能有多个级别的构图,这可能会也可能没有意义,这取决于你试图解决的问题。

如果我正确理解你的约束,那么TreeComposite和TreeData之间的关系可以通过中间表进行多对多。

使用此模型,您可以将树和森林视为同一类型的对象,并将元数据应用于此。