Necromante.
A resposta correta é: depende de qual mecanismo de banco de dados e de qual ferramenta de gerenciamento.
Vamos dar um exemplo:
temos uma tabela de relatórios,
e um relatório pode ter um pai (ponto de menu, como categoria),
e esse pai pode ter um pai (por exemplo, centro de lucro)
e assim por diante ad infinitum.
O exemplo mais simples de um relacionamento recursivo padrão, como em qualquer entidade / hierarquia auto-referente.
A tabela resultante do SQL-Server é:
IF EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N'dbo.FK_T_FMS_Reports_T_FMS_Reports') AND parent_object_id = OBJECT_ID(N'dbo.T_FMS_Reports'))
ALTER TABLE dbo.T_FMS_Reports DROP CONSTRAINT FK_T_FMS_Reports_T_FMS_Reports
GO
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'dbo.T_FMS_Reports') AND type in (N'U'))
DROP TABLE dbo.T_FMS_Reports
GO
CREATE TABLE dbo.T_FMS_Reports
(
RE_UID uniqueidentifier NOT NULL
,RE_RE_UID uniqueidentifier NULL
,RE_Text nvarchar(255) NULL
,RE_Link nvarchar(400) NULL
,RE_Sort int NOT NULL
,RE_Status int NOT NULL
,PRIMARY KEY CLUSTERED ( RE_UID )
);
GO
ALTER TABLE dbo.T_FMS_Reports WITH CHECK ADD CONSTRAINT FK_T_FMS_Reports_T_FMS_Reports FOREIGN KEY(RE_RE_UID)
REFERENCES dbo.T_FMS_Reports (RE_UID)
-- ON DELETE CASCADE -- here, MS-SQL has a problem
GO
ALTER TABLE dbo.T_FMS_Reports CHECK CONSTRAINT FK_T_FMS_Reports_T_FMS_Reports
GO
Mas você tem um problema:
quando você precisa excluir um ponto de menu com todos os seus submenus, NÃO PODE definir a cascata de exclusão, porque o Microsoft SQL-Server não suporta exclusões em cascata recursivas (por outro lado, o PostGreSQL sim [mas somente se o o gráfico não é cíclico], enquanto o MySQL não gosta desse tipo de estrutura de tabela, porque não suporta CTEs recursivos).
Então você meio que explode integridade / funcionalidade de exclusão, tornando obrigatório implementar essa funcionalidade em seu próprio código ou em um procedimento armazenado (se o seu RDBMS suportar procedimentos armazenados).
Isso sem dúvida explodirá qualquer tipo de importação / exportação de dados dinâmicos totalmente automática, porque você não pode simplesmente executar uma instrução de exclusão para todas as tabelas de acordo com relacionamentos de chave externa (sem referência própria), nem fazer uma seleção simples * e crie uma inserção para cada linha em uma ordem arbitrária.
Por exemplo, quando você cria um script INSERT usando SSMS, o SSMS não obtém a chave estrangeira e, de fato, cria instruções de inserção que inserem entradas com dependências, antes de inserir o pai da dependência, que falhará com um erro , porque a chave estrangeira está no lugar.
No entanto, em sistemas de gerenciamento de banco de dados adequados (como o PostgreSQL), com ferramentas adequadas, isso não deve ser um problema. Apenas entenda que, apenas porque você paga muito pelo seu RDBMS (estou olhando para você, Microsoft; Oracle =?) E / ou seu cinto de ferramentas, isso não significa que está programado corretamente. E o OpenSource (por exemplo, MySQL) também não o torna imune a essas minúcias maravilhosas.
O diabo está nos detalhes, como diz o velho ditado.
Agora, não que você não possa solucionar esses problemas, mas eu realmente não recomendaria se o seu sistema fosse complexo (por exemplo, mais de 200 tabelas).
Além disso, em um ambiente comercial habitual (como retratado por Dilbert), você simplesmente não terá esse tempo.
Uma abordagem muito melhor, embora mais difícil, seria uma tabela de fechamento.
Isso teria o bônus adicional de que ele também funciona no MySQL.
Depois de implementar a funcionalidade de fechamento uma vez, você a trabalhará em locais adicionais em quase nenhum momento.