2012-08-29 7 views
24

Mi sto interrogando su questa domanda di prova. Ho preparato l'esempio da solo e l'ho provato, ma continuo a non essere sicuro della risposta.MySQL su delete cascade. Esempio di prova

Con la seguente:

CREATE TABLE foo (
    id INT PRIMARY KEY AUTO_INCREMENT, 
    name INT 
) 

CREATE TABLE foo2 (
    id INT PRIMARY KEY AUTO_INCREMENT, 
    foo_id INT REFERENCES foo(id) ON DELETE CASCADE 
) 

Per quanto posso vedere la risposta è:

a. Due tabelle vengono create

Anche se ci sono anche:

b. Se una riga nella tabella foo2, con un foo_id di 2 è soppresso, poi la riga con id = 2 nella foo tabella viene cancellato automaticamente

d.If una riga con id = 2 nella tabella è soppressa foo, tutte le righe con foo_id = 2 nella tabella foo2 vengono eliminate

Nel mio esempio avrei usato la sintassi di eliminazione:

DELETE FROM foo WHERE id = 2; 
DELETE FROM foo2 WHERE foo_id = 2; 

per qualche motivo non sono riuscito a trovare alcuna relazione tra le tabelle anche se sembra come dovrebbe essercene uno Forse c'è qualche impostazione MySQL o forse è ON DELETE CASCADE non usato correttamente nelle query di creazione della tabella? Mi chiedo ...

risposta

37

Risposta d. è corretto, se e solo se il motore di archiviazione effettivamente supporta e impone vincoli di chiave esterna.

Se le tabelle vengono create con Engine=MyISAM, quindi né b. o d. è corretta.

Se le tabelle vengono create con Engine=InnoDB, quindi d. è corretto.

NOTA:

Questo è vero per InnoDB se e solo se FOREIGN_KEY_CHECKS = 1; se FOREIGN_KEY_CHECKS = 0, quindi un DELETE dalla tabella padre (pippo) sarà non rimuovere le righe dalla tabella figlio (foo2) che fanno riferimento a una riga rimossa dalla tabella padre.

verificare questo con l'uscita dal SHOW VARIABLES LIKE 'foreign_key_checks' (1 = ON, 0 = OFF) (Il predefinito è normale per questo essere ON.)

L'output SHOW CREATE TABLE foo indicherà quale motore utilizza la tabella.

L'uscita da SHOW VARIABLES LIKE 'storage_engine' mostrerà il motore predefinito utilizzato quando viene creata una tabella e il motore non viene specificato.

+0

notevole differenza tra 'MyISAM' e' InnoDB' per la correttezza di ** b ** – JalalJaberi

+0

Hai ragione. Era ** d **. perdonami per quello. – JalalJaberi

14

Si ha una relazione tra due tabelle, è nel comando di creazione di foo2: ... foo_id int references foo(id) on delete cascade.

Secondo il MySQL Foreign Key Constraints reference:

CASCADE: Eliminare o aggiornare la riga dalla tabella padre, e automaticamente eliminare o aggiornare le righe corrispondenti nella tabella figlio. Sono supportati sia ON DELETE CASCADE che ON UPDATE CASCADE.

Inoltre, secondo l'MySQL Foreign Keys reference:

Per i motori di archiviazione diversi InnoDB, è possibile quando si definisce una colonna di utilizzare un nome_tabella (nome_col) clausola, che non ha alcun effetto reale, RIFERIMENTI e funge solo da promemoria o commento per te che la colonna che stai attualmente definendo intende fare riferimento a una colonna in un'altra tabella.

Quindi dal momento che la chiave esterna è dalla tabella figlio alla tabella padre, fa foo una tabella padre e foo2 una tabella figlio, così l'eliminazione di una riga da foo sarà cascata eliminazioni a foo2, fornendo si utilizza InnoDB o qualche altro motore di archiviazione che lo supporta.

+1

Sarebbe d. (non b.) che sarebbe corretto. La chiave esterna è dalla tabella figlio alla tabella padre. L'eliminazione di una riga dalla tabella figlio non avrà alcun effetto (tramite la chiave esterna) nella tabella padre. È quando una riga viene eliminata dalla tabella padre in cui la chiave esterna entra in gioco. – spencer7593

+1

@ spencer7593 - Hai ragione, lo modificherò, grazie – Vic