Comment utiliser RESTRICT for Foreign Key dans mysql?

11

Dans la structure de la base de données de

  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;

Je m'attends à supprimer parent de Cityen laissant la valeur correspondante dans enfant intacte par ces trois commandes égales

  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)

Mais en utilisant NO ACTIONOR RESTRICTou en omettant ON DELETE. MySQL ne me permet pas de supprimer de la colonne parent avec cette erreur:

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

Où ai-je tort? N'est-ce pas la responsabilité des SQL de NO ACTIONsupprimer le parent et de laisser l'enfant orphelin?

Googlebot
la source

Réponses:

13

Selon la documentation MySQL sur DELETE RESTRICT

• RESTRICT: rejette l'opération de suppression ou de mise à jour de la table parent. La spécification de RESTRICT (ou NO ACTION) revient à omettre la clause ON DELETE ou ON UPDATE.

Quant à AUCUNE ACTION

• PAS D'ACTION: mot-clé de SQL standard. Dans MySQL, équivalent à RESTRICT. InnoDB rejette l'opération de suppression ou de mise à jour de la table parent s'il existe une valeur de clé étrangère associée dans la table référencée. Certains systèmes de base de données ont des vérifications différées, et NO ACTION est une vérification différée. Dans MySQL, les contraintes de clé étrangère sont vérifiées immédiatement, donc NO ACTION est identique à RESTRICT.

DELETE RESTRICT protège le parent de la suppression, pas les enfants.

RolandoMySQLDBA
la source
5

Si vous souhaitez supprimer le parent et laisser l'enfant, vous souhaitez probablement l' ON DELETE SET NULLoption:

SET NULL: supprimez ou mettez à jour la ligne de la table parent et définissez la ou les colonnes de clé étrangère de la table enfant sur NULL. Les clauses ON DELETE SET NULL et ON UPDATE SET NULL sont prises en charge.

Si vous spécifiez une action SET NULL, assurez-vous que vous n'avez pas déclaré les colonnes de la table enfant comme NOT NULL.

Il y a beaucoup de «non» dans cette dernière phrase, alors assurez-vous simplement que parent_id peut être NULL.

Voir aussi cette question connexe: quel est le but de SET NULL dans les contraintes de suppression / mise à jour de clés étrangères?

En définissant une clé étrangère, vous avez dit à la base de données de ne pas accepter les entrées de la table enfant qui n'ont pas de valeur correspondante dans le parent.

Derek Downey
la source