Chcę używać kluczy obcych, aby zachować integralność i uniknąć sierot (używam już innoDB).
Jak zrobić instrukcję SQL, która USUWA W KASKADIE?
Jeśli usunę kategorię, w jaki sposób mogę się upewnić, że nie usunie ona produktów, które są również powiązane z innymi kategoriami.
Tabela przestawna „category_products” tworzy relację wiele-do-wielu między dwiema pozostałymi tabelami.
categories
- id (INT)
- name (VARCHAR 255)
products
- id
- name
- price
categories_products
- categories_id
- products_id
mysql
foreign-keys
innodb
Cudos
źródło
źródło
Odpowiedzi:
Jeśli kaskadowanie usuwa produkt nuklearny, ponieważ należał on do kategorii, która została zabita, oznacza to, że nieprawidłowo skonfigurowałeś klucze obce. Biorąc pod uwagę przykładowe tabele, powinieneś mieć następującą konfigurację tabeli:
W ten sposób możesz usunąć produkt LUB kategorię, a tylko powiązane rekordy w category_products umrą obok. Kaskada nie przesunie się dalej w górę drzewa i nie usunie nadrzędnej tabeli produktów / kategorii.
na przykład
Jeśli usuniesz kategorię „czerwone”, umiera tylko wpis „czerwony” w tabeli kategorii, a także dwa wpisy prod / cats: „czerwone buty” i „czerwone płaszcze”.
Usunięcie nie nastąpi dalej i nie spowoduje usunięcia kategorii „buty” i „płaszcze”.
uzupełnienie komentarza:
nadal nie rozumiesz, jak działa usuwanie kaskadowe. Mają one wpływ tylko na tabele, w których zdefiniowano „kaskadę usuwania”. W tym przypadku kaskada jest ustawiana w tabeli „Categories_products”. Jeśli usuniesz kategorię „czerwona”, jedynymi rekordami, które będą usuwane kaskadowo w kategoriach category_products, są te, w których
category_id = red
. Nie dotknie żadnych rekordów, w których „category_id = blue” i nie przejdzie dalej do tabeli „products”, ponieważ nie ma zdefiniowanego klucza obcego w tej tabeli.Oto bardziej konkretny przykład:
Załóżmy, że usuwasz kategorię nr 2 (niebieski):
DBMS przejrzy wszystkie tabele, które mają klucz obcy wskazujący na tabelę „kategorie” i usunie rekordy, w których pasujący identyfikator wynosi 2. Ponieważ zdefiniowaliśmy tylko relację klucza obcego w programie
products_categories
, otrzymujesz tę tabelę, gdy usuwanie kończy się:W
products
tabeli nie zdefiniowano żadnego klucza obcego , więc kaskada nie będzie tam działać, więc nadal masz wymienione buty i rękawice. Po prostu nie ma już „niebieskich butów” i „niebieskich rękawiczek”.źródło
CASCADE
działać. W przeciwnym razie zostanie użyty domyślny MySQL, MyISAM, a MyISAM nie obsługujeCASCADE
operacji. Aby to zrobić, po prostu dodajENGINE InnoDB
przed ostatnim;
.Zmyliła mnie odpowiedź na to pytanie, więc stworzyłem przypadek testowy w MySQL, mam nadzieję, że to pomoże
źródło
Myślę (nie jestem pewien), że ograniczenia klucza obcego nie będą działać dokładnie tak, jak chcesz, biorąc pod uwagę projekt tabeli. Być może najlepszą rzeczą do zrobienia jest zdefiniowanie procedury składowanej, która usunie kategorię tak, jak chcesz, a następnie wywołanie tej procedury za każdym razem, gdy chcesz usunąć kategorię.
Musisz również dodać następujące ograniczenia klucza obcego do tabeli łączącej:
Klauzula CONSTRAINT może oczywiście pojawić się również w instrukcji CREATE TABLE.
Po utworzeniu tych obiektów schematu możesz usunąć kategorię i uzyskać żądane zachowanie, wydając
CALL DeleteCategory(category_ID)
(gdzie category_ID jest kategorią do usunięcia), a ona będzie zachowywać się tak, jak chcesz. Ale nie wysyłaj normalnegoDELETE FROM
zapytania, chyba że chcesz bardziej standardowego zachowania (tj. Usuń tylko z tabeli łączącej i pozostawproducts
tabelę w spokoju).źródło
KEY pkey (product_id),
w trzecimCREATE TABLE
zapytaniu w zaakceptowanej odpowiedzi?