【发布时间】:2011-06-27 20:50:14
【问题描述】:
我有一个模型问题,然后是一个单独的 SO 帖子中的视图问题,我将在创建它时链接到该问题。我正在发两个帖子,所以我可以做两个接受。
现在,让我们先假设我有以下架构。这是我正在设计的真实模式的简化版本,省略了不相关的列。已更改名称以保护无辜者和我的工作。
tree 具有以下属性。
tree.id
tree.dob
tree.height
tree.forestid
forestid 是forest 表的外键,它只是聚合多个tree 行的一种方式。它有一个id 列和一些元数据列。
tree 和 forest 都可能有很多 treedata 行。 treedata 包含
treedata.value
treedata.treeid
treedata.forestid
treedata.treeid 和 treedata.forestid 受到约束,因此两者之一必须为空。
如果tree.forestid 不为null,则treedata 与tree 的关系是多对多的,而forest 是链接器表。否则,tree和treedata之间的关系是一对多的。对我的应用程序来说,用户能够通过 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.
第三种方法是在tree 中有一个forestid 列并完全删除forest 表。在这条路上,我发现在正确增加tree.forestid 方面很难获得 ACID 保证。森林也有可能包含自己的元数据。我很想听听更多的方式来表示这一点,也想听听更多经验丰富的数据库人员对哪种方式更可取的意见,如果你通过引用自己的经验来解释你为什么这么认为的话,我会得到最高分。
对 Martin Dom 关于 TreeComposite 表的建议的回应:
感谢您的回复。我想在回应之前给 TreeComposite 的建议一天炖。首先,您的方式确实模拟了我以正常形式表达的关系,所以是的,我认为您确实理解了这个问题。但是,我认为我将表命名为 Tree 和 Forest 犯了一个愚蠢的错误:因为 Forest 不需要递归地组合成彼此。它们不是计算机科学树。它们只是树皮和树枝。 parentid 模型,虽然它仍然以正常形式代表我需要的东西(它是我需要的概括),虽然它的优点是 Trees 和 Forests 现在是“相同的东西”,这在表面上是复杂性的胜利,我怕在泥土里会乱成一团。
问题在于,无论它们在我的模型中是否被称为相同的东西,它们对我的控制器或视图来说都不是相同的东西。例如,具有子节点的 TreeComposite 可能至少具有每个节点将具有不同值的属性。在这种情况下,我需要在视图中使用不同的小部件来显示属性的多个值。换句话说,我需要能够将作为其自身父级的每个 TreeComposite 显示为一行,而该行的外观取决于 TreeComposite 是否有子级。
因此,从模型中提取 TreeComposite 后,我要做的第一件事就是确定它是“真的”是树还是森林。为什么要这样做,当我可以直接将它以正常形式存储为树和森林时,从而使我的视图和控制器更简单而不会损害我的模型?搜索 TreeData 也因父子关系而变得复杂。我必须通过N个TreeComposites进行连接,直到找到根节点,然后搜索指向根节点的TreeData。这粉碎了数据局部性。同时,如果我有一个带有 ForestID 的树,并且我想要该树的数据,我根本不需要查看 Forest 表。我可以直接将外键 外键加入到 TreeData。 (where Tree.ForestID = TreeData.ForestID)。
【问题讨论】:
标签: database-design schema database-schema