Mysql 插入时,为什么闭包表指向自身

Mysql 插入时,为什么闭包表指向自身,mysql,sql,closures,Mysql,Sql,Closures,在下面的闭包表教程中,我一直不明白为什么节点需要指向自身。例如: 创建表 create table closure ( ancestor int not null, descendant int not null, primary key (ancestor, descendant), foreign key (ancestor) references nodes(node), foreign key (descendant) references nod

在下面的闭包表教程中,我一直不明白为什么节点需要指向自身。例如:

创建表

create table closure (
    ancestor int not null,
    descendant int not null,
    primary key (ancestor, descendant),
    foreign key (ancestor) references nodes(node),
    foreign key (descendant) references nodes(node)
);
假设这些ID存在,则插入

insert into closure (ancestor, descendant) values
    (1,1), (1,2), (1,3), (1,4), (1,5), (1,6), (1,7),
    (2,2),
    (3,3), (3,4), (3,5),
    (4,4), (4,5),
    (5,5),
    (6,6), (6,7),
    (7,7); // <-- junction to itself?
我不能真正理解的部分是为什么1,1或2,2或3,3等等。。。用于。我试着用谷歌搜索答案,但我似乎永远也找不到合适的关键词


感谢

树中的每个节点都需要至少对应于闭包中的一行,其id是祖先。如果节点是叶,则它没有任何真正的子体,这种退化情况通过将子体指向自身来表示

我相信他为非叶节点创建了一个自引用行,这样就可以安全地删除具有该祖先的其他行-当删除所有子节点时,该节点将继续存在。

1正如Barmar所述,如果删除了叶节点的所有祖先节点,则自引用节点允许叶节点在闭包表中继续“存在”

2类似地,如果要移动子树,当子树与其原始祖先“断开”时,始终存在根节点。如果没有这一点,我认为移动子树的过程可能会有点混乱

3同样,自引用节点允许闭包表中不存在子代的根节点

4看过Bill Karwin的一些例子后,我认为这可能会帮助您编写更简单、更高效的SQL查询,但我在SQL方面的专家还不足以证明这一点

综上所述,在user1318677提供的示例中,自引用记录占表的41%,我觉得这是一个相当大的数量。如果您的项目不会导致1或2个频繁出现,例如基本论坛/评论系统,那么我认为自引用节点在很大程度上是冗余数据,您不一定需要它们

如果有人能证明不是这样,我很想听听


作为旁注,在评论部分回答用户1318677的问题:是的,可以有任意多的根节点,例如,论坛的每个原始帖子都有一个根节点

。我认为这只是部分答案,因为我怀疑所有节点都需要自引用,而不仅仅是leaf。否定自引用行是否会中断SELECT或DELETE查询?此外,从我找到的所有示例来看,闭包表只有一个主根节点。是否可能有多个根节点?请尝试删除7,7行,看看当您运行他的查询并打印所有路径时会发生什么。