Come utilizzare RESTRICT per chiave esterna in mysql?


11

Nella struttura del database di

  CREATE TABLE Country (
  name varchar(40) NOT NULL,
  PRIMARY KEY  (name)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;

CREATE TABLE City (
  name varchar(40) NOT NULL,
  PRIMARY KEY  (name)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;

CREATE TABLE Map (
  country varchar(40) NOT NULL,
  city varchar(100) NOT NULL,
  PRIMARY KEY  (country,city),
  FOREIGN KEY (country) REFERENCES Country (name) ON DELETE CASCADE,
  FOREIGN KEY (city) REFERENCES City (name) ON DELETE RESTRICT
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Mi aspetto di eliminare il genitore Citylasciando intatto il valore corrispondente in figlio con questi tre comandi uguali

  FOREIGN KEY (city) REFERENCES City (name) ON DELETE NO ACTION
  FOREIGN KEY (city) REFERENCES City (name) ON DELETE RESTRICT
  FOREIGN KEY (city) REFERENCES City (name)

Ma quando si utilizza NO ACTIONOR RESTRICTo si omette ON DELETE. MySQL non mi consente di eliminare dalla colonna padre con questo errore:

ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails 
('test'.'Map', CONSTRAINT 'Map_ibfk_2' FOREIGN KEY ('city') REFERENCES 'City'('name')
 ON DELETE RESTRICT

Dove sbaglio? Non è responsabilità dell'SQL NO ACTIONeliminare il genitore e lasciare il bambino orfano?

Risposte:


13

Secondo la documentazione MySQL su DELETE RESTRICT

• RESTRICT: rifiuta l'operazione di eliminazione o aggiornamento per la tabella padre. Specificare RESTRICT (o NO ACTION) equivale a omettere la clausola ON DELETE o ON UPDATE.

Per quanto riguarda NO AZIONE

• NO AZIONE: una parola chiave da SQL standard. In MySQL, equivalente a RESTRICT. InnoDB rifiuta l'operazione di eliminazione o aggiornamento per la tabella padre se esiste un valore di chiave esterna correlato nella tabella di riferimento. Alcuni sistemi di database hanno controlli differiti e NESSUNA AZIONE è un controllo differito. In MySQL, i vincoli di chiave esterna vengono controllati immediatamente, quindi NESSUNA AZIONE è uguale a RESTRICT.

DELETE RESTRICT protegge il genitore dalla cancellazione, non i figli.


5

Se si desidera eliminare il genitore e lasciare il figlio, probabilmente si desidera l' ON DELETE SET NULLopzione:

SET NULL: elimina o aggiorna la riga dalla tabella padre e imposta la colonna o le colonne della chiave esterna nella tabella figlio su NULL. Sono supportate le clausole ON DELETE SET NULL e ON UPDATE SET NULL.

Se si specifica un'azione SET NULL, assicurarsi di non aver dichiarato le colonne nella tabella figlio come NOT NULL.

C'è un sacco di "non" in quest'ultima frase, quindi assicurati solo che parent_id possa essere NULL.

Vedi anche questa domanda correlata: Qual è lo scopo di SET NULL nei vincoli Elimina / Aggiorna chiavi esterne?

Definendo una chiave esterna, hai detto al database di non accettare voci nella tabella figlio che non hanno un valore corrispondente nel padre.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.