在数据库中表示无根树/图表/层次结构

时间:2013-01-25 09:08:20

标签: sql ms-access database-design relational-database

似乎有几个很好的选择来表示数据库中的分层数据,最流行的显然是树遍历算法。

在我的情况下可能起作用的另一个选择是递归地执行它。这可能涉及保存父ID并从那里开始 - 尽管这也需要某种方向。

现在我有一个问题,我有一组项目,可以通过连接图表来表征,但没有根,不一定是起点。例如,可能会发生项目循环自身,因此排序只是每个元素的元素而不是完整的。无论顺序是“父母”还是“孩子”,取决于你开始的方向,可以这么说 此外,每个连接应该由几个属性表征,因此连接需要以某种方式识别 这是一个例子,虽然注意它只是一个小例子,但你已经可以看到一个简单的遍历算法可能从254开始,然后从203到162然后254实际上是162的孩子 - 这可能是一个问题(我我远没有成为cs专业所以我老实说不知道) example

另一件事是我只限于Access,这意味着我几乎只限于你的标准SQL命令而没有SQL中的递归或函数。
例如,SQL中转换为左/右遍历树的许多算法都不能与Access SQL一起使用 我对解决这个问题很感兴趣,而且不太依赖VBA。

就性能而言,尽管有关元素属性及其连接的查询可能有数十个元素,但我预计会少于5000个项目。一开始,不到10个用户会同时使用该数据库,但如果它们运行良好,这些东西往往会迅速扩展。

那么,你将如何实现这个构造?

1 个答案:

答案 0 :(得分:1)

我使用过Joe Celko的嵌套方法。它在适当的情况下非常有效。这不是其中之一。

更灵活的方法和我建议您使用的方法是Bill Karwin所说的 closure table

基本思路是您有每个可能路径的一条记录。比尔建议两个字段,ancestor_id和descendant_id。从你的图表中不清楚祖先/后代范式是否真的适用于你的情况。

我还发现为节点之间的跳数添加至少一个字段是有用的。我会通过创建一个包含三个字段的表来调整Bill的方法:

  1. NodeA上
  2. 节点B
  3. 啤酒花
  4. 以下是图表的一些示例数据:

    NodeA   NodeB  Hops
    ------  ------ ----
    tog171  tog171  0
    tog171  abb521  1
    abb521  tog171  1
    tog171  tog226  2
    tog226  tog171  2
    tog171  tog218  3
    tog218  tog171  3
    

    如果对不同的彩色线条和实线与虚线有一些语义含义,那么捕获该语义含义的附加字段也可以添加到您的表格中。

    你的表中最终会有很多条目,但灵活性几乎是无限的。在查看图表时,灵活性似乎是您最大的需求。

    编辑:我的样本数据第0行有0跳,实际上是我从PJ Eby在他的博客文章The simplest(?) way to do tree-based queries in SQL中学到的一种技巧。这些节点的目的是使节点的插入和删除更简单。我强烈建议该页面详细介绍实现闭包表。

    我认为PJ Eby的页面实际上是写入到闭包表的更好资源,而Bill Karwin的答案有一些很好的例子,从表中读取