Então o que você quer é materializar os fechamentos transitivos. Ou seja, dada essa tabela de aplicação...
ID | PARENT_ID
------+----------
1 |
2 | 1
3 | 2
4 | 2
5 | 4
... a tabela do gráfico ficaria assim:
PARENT_ID | CHILD_ID
-----------+----------
1 | 2
1 | 3
1 | 4
1 | 5
2 | 3
2 | 4
2 | 5
4 | 5
É possível manter uma tabela como esta no Oracle, embora você precise rolar seu próprio framework para ela. A questão é se vale a pena a sobrecarga. Se a tabela de origem for volátil, manter os dados do gráfico atualizados pode custar mais ciclos do que você economizará nas consultas. Só você conhece o perfil dos seus dados.
Eu não acho que você possa manter uma tabela de gráficos com consultas CONNECT BY e chaves estrangeiras em cascata. Muita atividade indireta, muito difícil de acertar. Além disso, uma visão materializada está fora, porque não podemos escrever uma consulta SQL que zapeie o
1->5
registro quando excluímos o registro de origem para ID=4
. Então, sugiro que você leia um artigo chamado Mantendo Fechamento Transitivo de Gráficos em SQL por Dong, Libkin, Su e Wong. Isso contém muita teoria e um pouco de SQL (Oracle), mas lhe dará a base para construir o PL/SQL que você precisa para manter uma tabela de gráficos.
"você pode expandir a parte sobre isso ser muito difícil de manter com CONNECT BY/FKs em cascata? Se eu controlar o acesso à tabela e todas as inserções/atualizações/exclusões ocorrerem procedimentos armazenados em vias, que tipos de cenários existem em que isso quebraria?"
Considere o registro
1->5
que é um curto-circuito de 1->2->4->5
. Agora, o que acontece se, como eu disse antes, excluirmos o registro de origem de ID=4
? Chaves estrangeiras em cascata podem excluir as entradas para 2->4
e 4->5
. Mas isso deixa 1->5
(e de fato 2->5
) na tabela do gráfico, embora não representem mais uma aresta válida no gráfico . O que pode funcionar (acho que não fiz isso) seria usar uma chave sintética adicional na tabela de origem, assim.
ID | PARENT_ID | NEW_KEY
------+-----------+---------
1 | | AAA
2 | 1 | BBB
3 | 2 | CCC
4 | 2 | DDD
5 | 4 | EEE
Agora a tabela do gráfico ficaria assim:
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
Portanto, a tabela de gráficos tem uma chave estrangeira que faz referência ao relacionamento na tabela de origem que a gerou, em vez de vincular ao ID. Em seguida, excluindo o registro para
ID=4
iria em cascata exclusões de todos os registros na tabela de gráfico onde NEW_KEY=DDD
. Isso funcionaria se um determinado ID pudesse ter apenas zero ou um ID pai. Mas não funcionará se for permitido que isso aconteça:
ID | PARENT_ID
------+----------
5 | 2
5 | 4
Em outras palavras, a borda
1->5
representa tanto 1->2->4->5
e 1->2->5
. Portanto, o que pode funcionar depende da complexidade dos seus dados.