【问题标题】:Representing a many-many and a one-many as a single denormalized view, as a many-to-many, or another way?将多对多和一对多表示为单个非规范化视图、多对多或其他方式?
【发布时间】:2011-06-27 20:50:14
【问题描述】:

我有一个模型问题,然后是一个单独的 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 是链接器表。否则,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


    【解决方案1】:

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

    我看到的唯一问题是您可能有多个级别的组合,这可能有意义也可能没有意义,具体取决于您要解决的问题。

    如果我正确理解您的约束条件,您的 TreeComposite 和 TreeData 之间的关系将是通过中间表进行多对多的关系。

    使用此模型,您可以将树和森林视为同一种对象,并牢记这一点来应用元数据。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-20
      • 1970-01-01
      • 2019-03-20
      • 2018-03-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多