建模多对多的一元关系和1:M一元关系

时间:2012-07-20 18:04:36

标签: mysql database database-design erd

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

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

我想创建一个包含所有子类别文件夹的类别名称的文件夹。 (视觉对象,如Windows文件夹) 所以我需要预先快速搜索子类别。

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

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

1:M unary relationship

这个设计是否正确?

多对多的一元关系可以更快地搜索超类别,默认情况下是最好的设计吗?

我更喜欢包含ERD的答案

2 个答案:

答案 0 :(得分:2)

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

enter image description here

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

向相反的方向(并获得所有祖先)也需要递归查询。由于这需要搜索PK(自动索引),这也应该是合理有效的。

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

答案 1 :(得分:1)

在某些情况下,在关系数据库中维护多级层次结构的最简单方法是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之外或代替父节点id,其他人存储节点的深度。

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

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