Supponiamo di avere una tabella che ha un vincolo di chiave esterna su se stessa, come tale:
CREATE TABLE Foo
(FooId BIGINT PRIMARY KEY,
ParentFooId BIGINT,
FOREIGN KEY([ParentFooId]) REFERENCES Foo ([FooId]) )
INSERT INTO Foo (FooId, ParentFooId)
VALUES (1, NULL), (2, 1), (3, 2)
UPDATE Foo SET ParentFooId = 3 WHERE FooId = 1
Questa tabella avrà i seguenti record:
FooId ParentFooId
----- -----------
1 3
2 1
3 2
Ci sono casi in cui questo tipo di design potrebbe avere senso (ad esempio la tipica relazione "impiegato-e-capo-impiegato"), e in ogni caso: mi trovo in una situazione in cui ho questo nel mio schema.
Questo tipo di design purtroppo consente la circolarità nei set di dati, come mostrato nell'esempio sopra.
La mia domanda quindi è:
- È possibile scrivere un vincolo che controlla questo? e
- È possibile scrivere un vincolo che controlli questo? (se necessario solo per una certa profondità)
Per la parte (2) di questa domanda può essere rilevante menzionare che mi aspetto solo centinaia o forse in alcuni casi migliaia di record nella mia tabella, normalmente non nidificati più in profondità di circa 5-10 livelli.
PS. MS SQL Server 2008
Aggiornamento 14 marzo 2012
Ci sono state diverse buone risposte. Ora ho accettato quello che mi ha aiutato a capire la possibilità / fattibilità menzionata. Ci sono molte altre grandi risposte, alcune anche con suggerimenti di implementazione, quindi se sei arrivato qui con la stessa domanda dai un'occhiata a tutte le risposte;)