Mam dwie tabele w MySQL od bazy danych parent
, child
. Próbuję dodać odniesienia do klucza obcego do mojej tabeli podrzędnej na podstawie tabeli nadrzędnej. Czy jest jakaś znacząca różnica między ON UPDATE CASCADE
iON DELETE CASCADE
Stolik mojego rodzica
CREATE TABLE parent (
id INT NOT NULL,
PRIMARY KEY (id)
) ENGINE=INNODB;
Moje pytanie brzmi: jaka jest różnica między następującymi zapytaniami sql.
ON DELETE CASCADE
CREATE TABLE child ( id INT, parent_id INT, INDEX par_ind (parent_id), FOREIGN KEY (parent_id) REFERENCES parent(id) ON DELETE CASCADE ) ENGINE=INNODB;
ON UPDATE CASCADE
CREATE TABLE child ( id INT, parent_id INT, INDEX par_ind (parent_id), FOREIGN KEY (parent_id) REFERENCES parent(id) ON UPDATE CASCADE ) ENGINE=INNODB;
ON UPDATE CASCADE ON DELETE CASCADE
CREATE TABLE child ( id INT, parent_id INT, INDEX par_ind (parent_id), FOREIGN KEY (parent_id) REFERENCES parent(id) ON UPDATE CASCADE ON DELETE CASCADE ) ENGINE=INNODB;
Czy w zapytaniach są jakieś błędy? Co oznaczają te zapytania (1,2 i 3)? Czy są takie same ???
mysql
innodb
mysql-5.5
foreign-key
Samotny wilk
źródło
źródło
Odpowiedzi:
Bardzo dobry wątek na ten temat można znaleźć tutaj i tutaj . Ostatecznym przewodnikiem dla MySQL jest oczywiście dokumentacja, którą można znaleźć tutaj .
W standardzie SQL 2003 istnieje 5 różnych akcji referencyjnych:
Aby odpowiedzieć na pytanie:
KASKADA
ON DELETE CASCADE
oznacza, że jeśli rekord macierzysty zostanie usunięty, wszelkie rekordy potomne również zostaną usunięte. Moim zdaniem nie jest to dobry pomysł. Powinieneś śledzić wszystkie dane, które kiedykolwiek były w bazie danych, chociaż można to zrobić za pomocąTRIGGER
s. (Patrz jednak zastrzeżenie w komentarzach poniżej).ON UPDATE CASCADE
oznacza, że jeśli nadrzędny klucz podstawowy zostanie zmieniony, wartość podrzędna również ulegnie zmianie, aby to odzwierciedlić. Ponownie moim zdaniem nie jest to świetny pomysł. Jeśli zmieniaszPRIMARY KEY
s z dowolną regularnością (lub nawet w ogóle!), Coś jest nie tak z twoim projektem. Ponownie zobacz komentarze.ON UPDATE CASCADE ON DELETE CASCADE
oznacza, że jeśli TYUPDATE
LUBDELETE
rodzic, zmiana jest przekazywana kaskadowo do dziecka. Jest to równoważne zAND
wynikami pierwszych dwóch stwierdzeń.OGRANICZAĆ
RESTRICT
oznacza, że każda próba usunięcia i / lub aktualizacji rodzica nie powiedzie błędu. Jest to domyślne zachowanie w przypadku, gdy akcja referencyjna nie jest wyraźnie określona.BEZ AKCJI
NO ACTION
: Z instrukcji . Słowo kluczowe ze standardowego SQL. W MySQL, równoważne zRESTRICT
. Serwer MySQL odrzuca operację usuwania lub aktualizacji dla tabeli nadrzędnej, jeśli w odnośnej tabeli znajduje się powiązana wartość klucza obcego. Niektóre systemy baz danych mają odroczone kontrole iNO ACTION
są odroczone. W MySQL ograniczenia klucza obcego są sprawdzane natychmiast,NO ACTION
podobnie jakRESTRICT
.ZESTAW NULL
SET NULL
- ponownie z instrukcji. Usuń lub zaktualizuj wiersz z tabeli nadrzędnej i ustaw kolumnę lub kolumny klucza obcego w tabeli podrzędnej naNULL
. Nie jest to najlepszy pomysł IMHO, przede wszystkim dlatego, że nie ma możliwości „podróży w czasie” - tj. Spoglądania wstecz w tabele podrzędne i kojarzenia rekordówNULL
zs z odpowiednim rekordem nadrzędnym - alboCASCADE
użyciaTRIGGER
s do zapełniania tabel rejestrowania w celu śledzenia zmiany (ale zobacz komentarze).USTAW DOMYŚLNIE
SET DEFAULT
. Kolejna (potencjalnie bardzo przydatna) część standardu SQL, której MySQL nie zawracał sobie głowy wdrażaniem! Pozwala deweloperowi na określenie wartości, dla której należy ustawić kolumny klucza obcego w UPDATE lub DELETE. InnoDB i NDB odrzucą definicje tabel zSET DEFAULT
klauzulą.Jak wspomniano powyżej, powinieneś poświęcić trochę czasu na przeglądanie dokumentacji tutaj .
źródło
Te dwie czynności są odpowiednio wykonywane, gdy odnośny rekord w tabeli nadrzędnej zmieni swój identyfikator i zostanie usunięty.
Jeśli wykonasz:
I istnieje przynajmniej jeden rekord na
child
zparent_id = 1
, 1) nie powiedzie; w przypadkach 2) i 3) wszystkie rekordy o identyfikatorze nadrzędnym = 1 są aktualizowane do identyfikatora nadrzędnego = -1.Jeśli wykonasz:
I istnieje przynajmniej jeden rekord na
child
zparent_id = 1
, 2) nie powiedzie; w przypadkach 1) i 3) wszystkie zapisy zparent_id = 1
są usuwane.3) jest poprawny pod względem składniowym.
Pełna dokumentacja znajduje się w instrukcji .
źródło
Nie mam wystarczającej reputacji, aby komentować poprzednie odpowiedzi. Pomyślałem więc, że trochę rozwinę.
1) PRZY USUNIĘCIU KASKADA oznacza, że jeśli rekord nadrzędny zostanie usunięty, wówczas wszelkie odniesienia podrzędne zostaną również usunięte. ON UPDATE domyślnie ma wartość RESTRICT, co oznacza, że UPDATE w rekordzie nadrzędnym zakończy się niepowodzeniem.
2) Domyślnie akcja ON DELETE ma wartość RESTRICT, co oznacza, że DELETE w rekordzie nadrzędnym zakończy się niepowodzeniem. PRZY AKTUALIZACJI KASKADA zaktualizuje wszystkie referencyjne rekordy potomne, gdy rekord macierzysty zostanie zaktualizowany.
3) Zobacz działania CASCADE w 1) i 2) powyżej.
W przypadku używania identyfikatorów rekordów nadrzędnych jako kluczy obcych (w tabelach podrzędnych) - doświadczenie mówi a) jeśli identyfikatorami są automatycznie generowane numery sekwencyjne, NIE NALEŻY ich używać jako kluczy obcych. Zamiast tego użyj innego unikalnego klucza nadrzędnego. b) jeśli identyfikatorami są identyfikatory GUID, można używać ich jako kluczy obcych. W tej sugestii zobaczysz mądrość podczas eksportowania i importowania rekordów lub kopiowania rekordów do innej bazy danych. Zbyt kłopotliwe jest zajmowanie się automatycznie generowanymi numerami sekwencji podczas migracji danych, gdy są one określane jako klucze obce.
źródło