Nie projektuję schematów codziennie, ale kiedy to robię, próbuję poprawnie skonfigurować aktualizacje kaskadowe / usunąć, aby ułatwić administrację. Rozumiem, jak działają kaskady, ale nigdy nie pamiętam, który stół jest który.
Na przykład, jeśli mam dwie tabele - Parent
i Child
- z kluczem obcym do Child
tych referencji Parent
i ma ON DELETE CASCADE
, które rekordy wyzwalają kaskadę, a które rekordy są kasowane? Moim pierwszym przypuszczeniem byłoby, że Child
rekordy zostaną usunięte po Parent
ich usunięciu, ponieważ Child
rekordy zależą od Parent
akt, ale ON DELETE
jest to niejednoznaczne; może to oznaczać usunięcie Parent
rekordu po jego Child
usunięciu lub może oznaczać usunięcie Child
rekordu po jego Parent
usunięciu. Więc co to jest?
Chciałbym, aby składnia była ON PARENT DELETE, CASCADE
, ON FOREIGN DELETE, CASCADE
lub coś podobnego, aby usunąć dwuznaczność. Czy ktoś ma jakieś mnemoniki, żeby o tym pamiętać?
źródło
Order(custID, itemID, orderID)
gdziecustID
odnosi się do klucza podstawowego wCustomers
tabeli iitemID
odnosi się do klucza podstawowego wItems
tabeli. Nie będzieszOrder
miał dwojga rodziców?ON DELETE CASCADE jest klauzulą opcjonalną w deklaracji klucza obcego. To idzie w parze z deklaracją klucza obcego. (Czyli w tabeli „podrzędnej”).
Jednym ze sposobów interpretacji deklaracji klucza obcego jest: „Wszystkie prawidłowe wartości dla tej kolumny pochodzą z„ that_column ”w„ that_table ”.” Kiedy usuwasz wiersz w tabeli „potomnej”, nikogo to nie obchodzi. Nie wpływa to na integralność danych.
Kiedy usuwasz wiersz z tabeli „nadrzędnej” - z „tej_tabeli” - usuwasz prawidłową wartość z możliwych wartości dla tabeli „podrzędnej”. Aby zachować integralność danych, musisz coś zrobić w tabeli „podrzędnej”. Kaskadowe usuwanie jest jedną rzeczą, którą możesz zrobić.
źródło
SQL: 2011 Spec
Istnieje pięć opcji
ON DELETE
,ON UPDATE
które mogą mieć zastosowanie doFOREIGN KEY
. Są one wywoływane<referential actions>
bezpośrednio ze specyfikacji SQL: 2011Klucz obcy ustanawia zależność.
<referential action>
Określa, co się dzieje, gdy związek jest rozpuszczony.Przykład / metafora / objaśnienie
W tym przykładzie zaakceptujemy wspólny model społeczeństwa i gospodarki: gdzie każda
business
jest firmą, która utrzymuje relacje zbourgeoisie
przedsiębiorstwemfatcat_owner
.Jeśli wszystkie
business
es są bezpośrednio dotkniętebourgeoisie
przez sposób ichfatcat_owner
to co robisz po rewolucji robotniczej, kiedy to Usunieszfatcat_owner
S i mieć bezklasowe społeczeństwo?Masz tutaj kilka opcji,
RESTRICT
. Niektórzy uważają, że jest to mniejsze zło, ale zwykle się mylą.Pozwól, aby trwało. Jeśli tak, to kiedy nastąpi rewolucja, SQL daje cztery opcje,
SET NULL
-- zostaw puste. Kto wie, może kapitalizm zostaje przywróconybourgeoisie
, a oligarchowie wypełniają listęfatcat_owners
. Ważna uwaga, kolumna musi byćNULLABLE
(nieNOT NULL
), inaczej to się nigdy nie stanie.SET DEFAULT
- może już sobie zDEFAULT
tym poradziłeś? ADEFAULT
może wywołać funkcję. Być może twój schemat jest już gotowy na rewolucję.CASCADE
- nie ma kontroli uszkodzeń. Jeślibourgeoisie
pójdzie, to teżbusiness
. Jeśli firma musi miećfatcat_pig
, to czasem sensowniej jest stracić dane, niż mieć inną firmę wbusiness
tabeli.NO ACTION
- jest to w zasadzie metoda opóźniania kontroli, w MySQL nie różni się toRESTRICT
, ale w PostgreSQL można to zrobićW takim systemie ograniczenie jest sprawdzane tylko przed zatwierdzeniem transakcji. Może to spowodować zatrzymanie rewolucji, ale możesz odzyskać w transakcji - w pewnym stopniu „odzyskać”.
źródło
referenced
tabela oznacza tabelę nadrzędną, areferencing
tabela oznacza tabelę podrzędną?Byłby prosty mnemonik
PRZY USUNIĘCIU rodzica KASKADA [przez usunięcie] tutaj
To mówi ci, które usunięcia (usunięcia rodzica) są kaskadowane, gdzie idzie instrukcja ON DELETE CASCADE (na potomku), a co zostaje usunięte (potomek).
źródło
cóż, być może możemy zracjonalizować składnię. Weźmy przykład w języku Python:
to, co mówi ta linia, to on_delete od rodzica (o czym przypadkowo wspomniano w oświadczeniu), proszę kaskadowo usunąć dziecko. Dlatego instrukcja CASCADE jest zdefiniowana na poziomie potomnym, oznacza te dzieci, które należy usunąć
Na przykład, jeśli miałeś inną klasę
ta struktura wyraźnie pokazuje, które z dzieci należy usunąć (Dziecko), a które mają pozostać (GrownUpChild), choć osierocone
[Edycja: Biorąc pod uwagę kontekst dyskusji, szczególnie w przypadku on_delete = models.CASCADE itp.], W rzeczywistości często pożądanym zachowaniem jest pozostawienie dzieci usuniętego rodzica ze względów kontrolnych i sprawozdawczych, a także odzyskania przypadkowego skreślenia. [oczywiście oprogramowanie na poziomie przedsiębiorstwa zostanie zbudowane wokół takiego zachowania i będzie oznaczać usunięte rekordy jako usunięte = 1 zamiast faktycznie je usuwać, a także nie będzie uwzględniać ich w żadnych zapytaniach dotyczących interfejsu użytkownika, pomijając niektóre specjalnie zaprojektowane raporty. Ponadto będzie miał funkcję usuwania usuniętych == 1 rekordów z bazy danych, co zwykle będzie wykonywane przez administratora interfejsu użytkownika, często unikając jakiegokolwiek zaangażowania ze strony administratora bazy danych.]
źródło