Nekromanzierung.
Die richtige Antwort lautet: Es kommt darauf an, welche Datenbank-Engine und welches Management-Tool verwendet wird.
Lassen Sie uns ein Beispiel machen:
Wir haben eine Berichtstabelle,
und ein Bericht kann ein übergeordnetes Element haben (Menüpunkt, wie Kategorie),
und dieses übergeordnete Element kann selbst ein übergeordnetes Element haben (z. B. Profit Center)
und so weiter.
Das einfachste Beispiel für eine standardmäßige rekursive Beziehung, wie bei jeder selbstreferenzierenden Entität / Hierarchie.
Die resultierende SQL-Server-Tabelle lautet:
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
Aber Sie bekommen ein Problem:
Wenn Sie einen Menupunkt mit all seinen Unterpunkten löschen müssen, können Sie delete-cascade NICHT setzen, weil Microsoft SQL-Server rekursive kaskadierte Löschvorgänge nicht unterstützt (PostGreSQL hingegen [, aber nur wenn graph is not cyclic], während MySQL diese Art von Tabellenstruktur überhaupt nicht mag, weil es keine rekursiven CTEs unterstützt).
Sie können damit also die Löschintegrität / -funktionalität in die Luft jagen, sodass die Implementierung dieser Funktionalität in Ihrem eigenen Code oder in einer gespeicherten Prozedur (sofern Ihr RDBMS gespeicherte Prozeduren unterstützt) obligatorisch ist.
Dies wird zweifellos jede Art von vollautomatischem dynamischem Datenimport / -export in die Luft jagen, da Sie weder einfach eine Löschanweisung für alle Tabellen gemäß (nicht selbstreferenzierenden) Fremdschlüsselbeziehungen ausführen noch eine einfache Auswahl vornehmen können * und erstellen Sie eine Einfügung für jede Zeile in einer beliebigen Reihenfolge.
Wenn Sie beispielsweise ein INSERT-Skript mit SSMS erstellen, erhält SSMS den Fremdschlüssel nicht und erstellt daher tatsächlich Insert-Anweisungen, mit denen Einträge mit Abhängigkeiten eingefügt werden, bevor das übergeordnete Element der Abhängigkeit eingefügt wird, was mit einem Fehler fehlschlägt , weil der Fremdschlüssel vorhanden ist.
Auf ordnungsgemäßen Datenbankverwaltungssystemen (wie PostgreSQL) sollte dies jedoch mit geeigneten Tools kein Problem darstellen. Nur verstehen, dass nur, weil Sie viel für Ihr RDBMS (ich sehe Sie, Microsoft; Oracle =?) Und / oder dessen Tool-Belt bezahlen, es nicht bedeutet, dass es richtig programmiert ist. Und OpenSource (zB MySQL) macht Sie auch nicht immun gegen solch wunderbare Kleinigkeiten.
Der Teufel steckt im Detail, wie das alte Sprichwort sagt.
Nun, nicht, dass Sie solche Probleme nicht umgehen könnten, aber ich würde es wirklich nicht empfehlen, wenn Ihr System komplex sein wird (z. B. mehr als 200 Tabellen).
Außerdem wird Ihnen in einem üblichen kommerziellen Umfeld (wie von Dilbert dargestellt) diese Zeit nicht gewährt.
Ein viel besserer, wenn auch schwierigerer Ansatz wäre ein Abschlusstisch.
Das hätte den zusätzlichen Bonus, dass es auch auf MySQL funktioniert.
Sobald Sie die Closure-Funktionalität einmal implementiert haben, können Sie sie in kürzester Zeit an weiteren Stellen einsetzen.