【问题标题】:Adjacency list tree - how to prevent circular references?邻接列表树 - 如何防止循环引用?
【发布时间】:2011-02-20 11:14:41
【问题描述】:

我在一个数据库中有一个邻接列表,它带有 ID 和 ParentID 来表示树结构:

-a
--b
---c
-d
--e

当然,在记录中,ParentID 绝不应该与 ID 相同,但我还必须防止循环引用以防止无限循环。这些循环引用理论上可能涉及超过 2 条记录。 (a->b、b->c、c->a 等)

对于每条记录,我将路径存储在一个字符串列中,如下所示:

a    a
b    a/b
c    a/b/c
d    d
e    d/e

我现在的问题是: 在插入/更新时,有没有办法检查是否会发生循环引用?

我应该补充一点,我对嵌套集合模型等都很了解。我选择了存储路径的邻接方法,因为我发现它更直观。我让它与触发器和一个单独的路径表一起工作,它就像一个魅力,除了可能的循环引用。

【问题讨论】:

  • 我现在解决了这个问题,方法是跟踪递归路径循环中使用的 ID。当它看到一个已经使用过的 ID 时,它会插入“NULL”而不是 ID。也许不是很优雅,但它似乎工作......

标签: sql mysql circular-reference adjacency-list


【解决方案1】:

如果您要这样存储路径,则可以检查该路径是否不包含 id。

【讨论】:

  • 这就是我意识到的,首先我将使用的 ID 存储在一个单独的数组中,但是在构建路径时,我可以使用路径字符串本身来检查 ID:)
【解决方案2】:

如果您使用的是 Oracle,您可以使用 CONNECT BY 语法来检查循环。节点数应等于根节点的后代数。

CHECK (
(SELECT COUNT(*) Nodes
 FROM Tree) =
(SELECT COUNT(*) Decendents
 FROM Tree
 START WITH parent_node IS NULL -- Root Node
 CONNECT BY parent_node = PRIOR child_node))

请注意,您仍然需要其他检查来强制执行该树。浏览器

具有空值的单个根节点。 节点只能有一个父节点。

您不能使用子查询创建检查约束,因此需要转到视图或触发器。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-03-12
    • 1970-01-01
    • 2014-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-18
    • 1970-01-01
    相关资源
    最近更新 更多