Nécromancie.
La réponse correcte est: cela dépend de quel moteur de base de données et de quel outil de gestion.
Prenons un exemple:
nous avons une table de rapport,
et un rapport peut avoir un parent (menupoint, comme une catégorie),
et ce parent peut lui-même avoir un parent (par exemple, Centre de profit),
et ainsi de suite à l'infini.
L'exemple le plus simple d'une relation récursive standard, comme avec toute entité / hiérarchie à référence automatique.
La table SQL-Server résultante est:
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
Mais vous rencontrez un problème:
lorsque vous devez supprimer un point de menu avec tous ses sous-points, vous NE POUVEZ PAS définir delete-cascade, car Microsoft SQL-Server ne prend pas en charge les suppressions en cascade récursives (par contre, PostGreSQL ne [ graph n'est pas cyclique], alors que MySQL n'aime pas du tout ce type de structure de tableau, car il ne supporte pas les CTE récursifs).
Vous détruisez donc un peu l’intégrité / fonctionnalité de suppression, ce qui rend obligatoire l’implémentation de cette fonctionnalité dans votre propre code ou dans une procédure stockée (si votre SGBDR prend en charge les procédures stockées).
Cela entraînera sans aucun doute toute sorte d'importation / exportation de données dynamiques entièrement automatique, car vous ne pouvez pas simplement exécuter une instruction delete pour toutes les tables en fonction de relations de clé étrangère (sans auto-référencement), ni effectuer une simple sélection. * et créez un insert pour chaque ligne dans un ordre arbitraire.
Par exemple, lorsque vous créez un script INSERT à l'aide de SSMS, SSMS ne récupère pas la clé étrangère et crée donc bien des instructions d'insertion qui insèrent des entrées avec des dépendances, avant d'insérer le parent de la dépendance, ce qui échouera avec une erreur. , car la clé étrangère est en place.
Cependant, sur des systèmes de gestion de base de données appropriés (tels que PostgreSQL), avec un outillage approprié, cela ne devrait pas poser de problème. Comprenez simplement que le fait que vous payiez beaucoup pour votre SGBDR (je vous regarde, Microsoft; Oracle =?) Et / ou sa ceinture d’outils ne signifie pas qu’il est programmé correctement. Et OpenSource (par exemple, MySQL) ne vous rend pas non plus immunisé contre de telles minuties.
Le diable est dans les détails, comme le dit le vieil adage.
Maintenant, non pas que vous ne puissiez pas contourner de tels problèmes, mais je ne le recommanderais vraiment pas, si votre système devait être complexe (par exemple, plus de 200 tables).
De plus, dans un contexte commercial habituel (tel que décrit par Dilbert), on ne vous donnera tout simplement pas ce temps.
Une approche bien meilleure, bien que plus difficile, consisterait en une table de fermeture.
Cela aurait l'avantage supplémentaire que cela fonctionne également sur MySQL.
Une fois que vous avez implémenté la fonctionnalité de fermeture une fois, vous la travaillerez à des emplacements supplémentaires en un rien de temps.