Kiedy używać " na kaskadzie aktualizacji"

Używam" on DELETE CASCADE "regularnie, ale nigdy nie używam "ON UPDATE CASCADE", ponieważ nie jestem pewien, w jakiej sytuacji będzie to przydatne.

Dla dobra dyskusji zobaczmy jakiś kod.

CREATE TABLE parent (
    id INT NOT NULL AUTO_INCREMENT,
    PRIMARY KEY (id)
);

CREATE TABLE child (
    id INT NOT NULL AUTO_INCREMENT, parent_id INT,
    INDEX par_ind (parent_id),
    FOREIGN KEY (parent_id)
        REFERENCES parent(id)
        ON DELETE CASCADE
);

Dla "ON DELETE CASCADE", jeśli rodzic z id zostanie usunięty, rekord w potomku z parent_id = parent.id zostanie automatycznie usunięty. To nie powinno być problemem.

  1. Oznacza to, że "ON UPDATE CASCADE" zrobi to samo, gdy id rodzica jest aktualizacja?

  2. Jeśli (1) jest prawdziwe, oznacza to, że nie ma potrzeby używania "ON update CASCADE", Jeśli parent.id nie można zaktualizować (lub nigdy nie będzie aktualizowane), jak wtedy, gdy jest AUTO_INCREMENT lub zawsze ustawione na TIMESTAMP. Naprawdę?

  3. Jeśli (2) nie jest prawdą, w jakiej innej sytuacji powinniśmy użyć "ON update CASCADE"?

  4. Co jeśli (z jakiegoś powodu) zaktualizuję child.parent_id, aby było czymś nieistniejącym, czy zostanie ono automatycznie usunięte?

Cóż, Ja wiem, niektóre z powyższych pytań można przetestować programowo, aby zrozumieć, ale chcę również wiedzieć, czy którykolwiek z nich jest zależny od dostawcy bazy danych, czy nie.

Proszę rzucić trochę światła.

Author: Gray, 2009-09-26

6 answers

To prawda, że jeśli klucz podstawowy jest po prostu wartość tożsamości Auto incremented, nie będziesz miał rzeczywistego użytku w kaskadzie aktualizacji.

Załóżmy jednak, że Twoim kluczem głównym jest 10-cyfrowy Kod kreskowy UPC i ze względu na rozszerzenie, musisz zmienić go na 13-cyfrowy Kod kreskowy UPC. W takim przypadku, na aktualizacji kaskada pozwoli Ci zmienić wartość klucza podstawowego i wszelkie tabele, które mają odniesienia do klucza obcego do wartości zostaną odpowiednio zmienione.

W nawiązaniu do #4, Jeśli Zmień identyfikator dziecka na coś, co nie istnieje w tabeli rodzica (i masz referencjalną integralność), powinieneś uzyskać błąd klucza obcego.

 391
Author: C-Pound Guru,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-06 22:16:02
  1. Tak, oznacza to, że na przykład, jeśli wykonasz UPDATE parent SET id = 20 WHERE id = 10 wszystkie dzieci parent_id z 10 zostaną również zaktualizowane do 20

  2. Jeśli nie zaktualizujesz pola, do którego odnosi się klucz obcy, to ustawienie nie jest potrzebne

  3. Nie mogę wymyślić innego zastosowania.

  4. Nie możesz tego zrobić, ponieważ ograniczenie klucza obcego zawiedzie.

 71
Author: Zed,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-06 22:15:38

Myślę, że prawie trafiłeś w sedno!

Jeśli stosujesz najlepsze praktyki projektowania baz danych i twój klucz podstawowy nigdy nie jest aktualizowalny( co I tak powinno być zawsze), to nigdy tak naprawdę nie potrzebujesz klauzuli ON UPDATE CASCADE.

Zed dobrze zauważył, że jeśli użyjesz klucza natural (np. zwykłego pola z tabeli bazy danych) jako klucza podstawowego, to mogą wystąpić sytuacje, w których będziesz musiał zaktualizować klucze podstawowe. Kolejne Ostatnie przykładem może być ISBN (International Standard Book Numbers), który zmienił się z 10 do 13 cyfr+znaków nie tak dawno temu.

Tak nie jest, jeśli zdecydujesz się użyć zastępczych (np. sztucznie generowanych systemowo) kluczy jako klucza podstawowego(co byłoby moim preferowanym wyborem we wszystkich, ale najbardziej rzadkich przypadkach).

Więc na koniec: jeśli twój klucz podstawowy nigdy się nie zmienia, to nigdy nie potrzebujesz klauzuli ON UPDATE CASCADE.

Marc

 25
Author: marc_s,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-09 09:28:36

Kilka dni temu miałem problem z wyzwalaczami i odkryłem, że ON UPDATE CASCADE mogą być przydatne. Spójrz na ten przykład (PostgreSQL):

CREATE TABLE club
(
    key SERIAL PRIMARY KEY,
    name TEXT UNIQUE
);

CREATE TABLE band
(
    key SERIAL PRIMARY KEY,
    name TEXT UNIQUE
);

CREATE TABLE concert
(
    key SERIAL PRIMARY KEY,
    club_name TEXT REFERENCES club(name) ON UPDATE CASCADE,
    band_name TEXT REFERENCES band(name) ON UPDATE CASCADE,
    concert_date DATE
);

W moim numerze musiałem zdefiniować kilka dodatkowych operacji (trigger) do aktualizacji tabeli koncertowej. Te operacje musiały zmodyfikować nazwę klubu i nazwę zespołu. Nie byłem w stanie tego zrobić, z powodu referencji. Nie mogłem zmodyfikować koncertu, a potem zająć się klubowymi i zespołowymi stolikami. Nie mogłem też zrobić tego w drugą stronę. ON UPDATE CASCADE był kluczem do rozwiązania problemu.

 14
Author: Ariel Grabijas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-09 15:13:17

Mój komentarz jest głównie w odniesieniu do punktu # 3: w jakich okolicznościach ma zastosowanie kaskada aktualizacji, jeśli Zakładamy, że klucz rodzica nie jest aktualizowalny? Oto jedna sprawa.

Mam do czynienia ze scenariuszem replikacji, w którym wiele satelitarnych baz danych musi być połączonych z master. Każdy Satelita generuje dane na tych samych tabelach, więc łączenie tabel z master prowadzi do naruszenia ograniczenia unikalności. Próbuję użyć na UPDATE CASCADE jako część rozwiązanie, w którym ponownie zwiększam klucze podczas każdego scalania. Kaskada aktualizacji powinna uprościć ten proces, automatyzując część procesu.

 4
Author: ted.strauss,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-09-20 18:15:52

To doskonałe pytanie, miałem to samo pytanie wczoraj. Myślałem o tym problemie, specjalnie szukał, czy istnieje coś takiego jak "na kaskadzie aktualizacji" i na szczęście projektanci SQL również myślał o tym. Zgadzam się z Tedem.Straussa, a także skomentowałem sprawę Norana.

Kiedy go użyłem? Jak zauważył Ted, kiedy traktujesz kilka baz danych naraz, a modyfikacja w jednej z nich, w jednej tabeli, ma jakikolwiek rodzaj reprodukcji w tym, co nazywa Ted "satellite database", nie może być przechowywana z bardzo oryginalnym identyfikatorem i z jakiegokolwiek powodu musisz utworzyć nowy, w przypadku, gdy nie możesz zaktualizować danych na starym (na przykład ze względu na uprawnienia, lub w przypadku, gdy szukasz trwałości W przypadku, który jest tak efemeryczny, że nie zasługuje na absolutny i całkowity szacunek dla całkowitych zasad normalizacji, po prostu dlatego, że będzie bardzo krótkotrwałe Narzędzie)

Więc zgadzam się w dwóch punktach:

(A.) Tak, w wielu przypadkach lepszy projekt można tego uniknąć; ale

(B.) W przypadku migracji, replikacji baz danych lub rozwiązywania sytuacji awaryjnych, jest to świetne narzędzie, które na szczęście było tam, kiedy poszedłem szukać, czy istnieje.

 3
Author: David L,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-27 18:36:39