因此,您想要的是实现可传递闭包。也就是说,给定此应用程序表…
ID | PARENT_ID
------+----------
1 |
2 | 1
3 | 2
4 | 2
5 | 4
…图形表如下所示:
PARENT_ID | CHILD_ID
-----------+----------
1 | 2
1 | 3
1 | 4
1 | 5
2 | 3
2 | 4
2 | 5
4 | 5
在Oracle中可以维护一个这样的表,尽管您需要为其滚动自己的框架。问题是这是否值得开销。如果源表是易失性的,则保持图形数据新鲜可能花费的周期比您将在查询中节省的周期更多。只有您知道数据的个人资料。
我认为您无法使用CONNECT BY查询和级联外键来维护这样的图形表。间接活动过多,难以正确解决。物化视图也已退出,因为我们无法编写SQL查询,1->5
当删除的源记录时,该查询将破坏记录ID=4
。
因此,我建议您阅读由Dong,Libkin,Su和Wong撰写的名为“维护SQL中的图的传递闭包”的论文。它包含许多理论和一些粗糙的(Oracle)sql,但是它将为您构建维护图表所需的PL / sql提供基础。
“您能否扩展一下用CONNECT BY /级联FK维护起来太困难的部分?如果我控制对表的访问,并且所有插入/更新/删除都是通过存储过程进行的,那么在哪种情况下会发生这种情况?分解?”
考虑1->5
是短路的记录1->2->4->5
。现在,如果像我之前说的那样,我们删除的源记录,该ID=4
怎么办?级联外键可以删除该条目2->4
和4->5
。但是,尽管它们不再代表 图形中 的有效边,但仍保留 在图形表中1->5
(并且确实如此2->5
)。 __
可能有效的方法(我想,我还没有做到)是在源表中使用附加的合成键,如下所示。
ID | PARENT_ID | NEW_KEY
------+-----------+---------
1 | | AAA
2 | 1 | BBB
3 | 2 | CCC
4 | 2 | DDD
5 | 4 | EEE
现在,图形表将如下所示:
PARENT_ID | CHILD_ID | NEW_KEY
-----------+----------+---------
1 | 2 | BBB
1 | 3 | CCC
1 | 4 | DDD
1 | 5 | DDD
2 | 3 | CCC
2 | 4 | DDD
2 | 5 | DDD
4 | 5 | DDD
因此,图形表具有一个外键,该外键引用生成它的源表中的关系,而不是链接到ID。然后删除的记录,ID=4
将会级联删除图形表中的所有记录,其中NEW_KEY=DDD
。
如果任何给定的ID只能有零个或一个父ID,这将起作用。但是,如果允许发生这种情况,它将无法正常工作:
ID | PARENT_ID
------+----------
5 | 2
5 | 4
换句话说,边缘1->5
代表1->2->4->5
和1->2->5
。因此,可能有效的方法取决于数据的复杂性。