Powiązane tabele (np. "zamówienia" i "klienci") pojawiły się w relacyjnych bazach od samego początku, ale na wczesnych etapach kontrola integralności musiała być realizowana ręcznie przez logikę programową. Wraz z rozwojem SQL pojawiły się wbudowane ograniczenia (FOREIGN KEY) oraz automatyczne działania (CASCADE).
Historia pytania:
Początkowo bazy danych potrzebowały mechanizmów utrzymywania integralności, aby uniknąć "zawieszonych" rekordów (np. zamówienia bez istniejącego klienta). FOREIGN KEY stał się standardem, a opcje CASCADE zautomatyzowały synchronizację przy usuwaniu i zmianach.
Problem:
Bez działań kaskadowych usunięcie lub zaktualizowanie wiersza w głównej tabeli prowadzi do błędów lub "osieroconych" danych. Przekazanie tego zadania aplikacji często wiąże się z trudnościami w utrzymaniu i ryzykiem incydentów podczas masowych operacji. Niewłaściwe użycie działań kaskadowych może spowodować lawinowe usunięcie lub naruszenie logiki biznesowej.
Rozwiązanie:
Zastosowanie FOREIGN KEY z ON DELETE CASCADE i ON UPDATE CASCADE pozwala automatycznie utrzymywać integralność i poprawnie synchronizować powiązane tabele. W skomplikowanych scenariuszach (np. jeśli potrzebne jest nie tylko usuwanie, ale także logowanie działań) używa się wyzwalaczy.
Przykład kodu:
CREATE TABLE Customers ( CustomerID INT PRIMARY KEY, Name NVARCHAR(100) ); CREATE TABLE Orders ( OrderID INT PRIMARY KEY, CustomerID INT, Amount DECIMAL(10,2), FOREIGN KEY (CustomerID) REFERENCES Customers(CustomerID) ON DELETE CASCADE ON UPDATE CASCADE );
Kluczowe cechy:
Czy kaskadowe usuwanie zawsze jest najlepszą praktyką dla wszystkich relacji?
Nie: dla danych "historycznych" lub informacji archiwalnych kaskadowe usuwanie może prowadzić do utraty cennych danych. Ważne jest zrozumienie wartości biznesowej każdego typu relacji.
Czy ON UPDATE CASCADE działa, jeśli klucz obcy nie jest częścią PRIMARY KEY rodzicielskiej tabeli?
W większości systemów baz danych klucz obcy musi odnosić się do unikalnego lub PRIMARY KEY, aby wspierać kaskady. W przeciwnym razie polecenie nie zadziała.
Czy łańcuch kaskadowy może przekroczyć dozwolone limity poziomu zagnieżdżenia (rekursja) i co się stanie?
Tak: przy ogromnych kaskadach możliwy jest przekroczenie limitu głębokości (np. w SQL Server — 32). To spowoduje błąd i wycofanie operacji.
W systemie ewidencji dostawców i zamówień zastosowano ON DELETE CASCADE — klienci przypadkowo usuwali ważnego dostawcę, automatycznie usuwane były wszystkie zamówienia, historie dostaw znikły. Przywrócenie danych stało się niemożliwe.
Zalety:
Wady:
Zastosowano ON DELETE SET NULL, plus wyzwalacz do logowania — nawet po usunięciu wpisu klienta historia zamówień była zachowana (przypisano status nieaktualnych), przypadkowe masowe usunięcie nie miało miejsca.
Zalety:
Wady: