【问题标题】:modeling many to many unary relationship and 1:M unary relationship建模多对多一元关系和 1:M 一元关系
【发布时间】:2012-07-20 18:04:35
【问题描述】:

我重新回到数据库设计领域,我意识到我的知识存在巨大差距。

我有一个包含类别的表格。每个类别可以有多个子类别,每个子类别又可以属于多个超类别。

我想创建一个包含所有子类别文件夹的类别名称的文件夹。 (像 windows 文件夹这样的视觉对象) 所以我需要对子类别进行快速搜索。

我想知道在这种情况下使用 1:M 或 M:N 关系有什么好处? 以及如何实现每个设计?

我创建了一个 1:M 一元关系的 ERD 模型。 (该图还包含一个费用表,其中存储了所有费用值,但在这种情况下不相关)

这个设计正确吗?

多对多一元关系是否允许更快地搜索超类别?默认情况下是最佳设计吗?

我更喜欢包含 ERD 的答案

【问题讨论】:

  • 出于好奇,什么是“1:M 一元关系”?我使用术语“一元”来表示“1:1”关系(或者,在某些情况下,可能是“0-1:0-1”)。
  • In Database Systems - Design, Implementation, and Management (9th Edition) 一元 M:N 关系通过给出课程示例来解释: M:N 递归关系在学校可能更熟悉环境。例如,请注意图 4.17 所示的 M:N “COURSE requires COURSE”关系如何在图 4.21 中实现。在此示例中,MATH-243 是 QM-261 和 QM-362 的先决条件,而 MATH-243 和 QM-261 都是 QM-362 的先决条件

标签: mysql database database-design erd


【解决方案1】:

如果我理解正确,一个子类别最多可以有一个(直接)超类别,在这种情况下,您不需要单独的表。这样的事情就足够了:

显然,您需要一个递归查询来获取所有级别的子类别,但如果您在 PARENT_ID 上放置一个索引,它应该是相当有效的。

反方向(并获取所有祖先)也需要递归查询。由于这需要在 PK 上进行搜索(自动编入索引),因此这也应该是相当有效的。

有关更多想法和不同的性能权衡,请查看this slide-show

【讨论】:

  • 好棒,所以没有必要恐慌。我在看书,看到了各种各样的图表,我根本不记得它们,所以我草草下结论。感谢您的回答和链接:)
【解决方案2】:

在某些情况下,在关系数据库中维护多级层次结构的最简单方法是 Nested Set Model,有时也称为“修改的前序树遍历”(MPTT)。

基本上树节点不仅存储父id,还存储最左边和最右边叶子的id:

spending_category
-----------------
parent_id    int
left_id      int
right_id     int
name        char

这样做的主要好处是,现在您可以通过单个查询获得节点的整个子树:子树节点的 id 介于 left_id 和 right_id 之间。有很多变化;除了父节点 id 之外,其他人存储节点的深度。

一个缺点是在插入或删除节点时必须更新 left_id 和 right_id,这意味着这种方法仅适用于中等大小的树。

Branko 提到的wikipedia articleslideshow 比我更好地解释了这项技术。如果您想了解更多关于在关系数据库中存储分层数据的不同方法,还可以查看this list of resources

【讨论】:

  • 非常有趣。当您插入新值时,我会阅读它,这似乎需要维护很多工作。
猜你喜欢
  • 1970-01-01
  • 2018-09-27
  • 1970-01-01
  • 1970-01-01
  • 2015-07-10
  • 2014-02-02
  • 2019-08-04
  • 2018-06-15
  • 2015-02-05
相关资源
最近更新 更多