Wie verwende ich RESTRICT für Fremdschlüssel in MySQL?

11

In der Datenbankstruktur von

  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;

Ich erwarte, Eltern zu löschen, Cityindem der entsprechende Wert in Kind durch diese drei gleichen Befehle intakt bleibt

  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)

Aber wenn Sie NO ACTIONOR verwenden RESTRICToder weglassen ON DELETE. Mit MySQL kann ich mit diesem Fehler nicht aus der übergeordneten Spalte löschen:

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

Wo irre ich mich Ist es nicht die Verantwortung der SQLs NO ACTION, das Elternteil zu löschen und das Kind verwaist zu lassen?

Googlebot
quelle

Antworten:

13

Gemäß der MySQL-Dokumentation zu DELETE RESTRICT

• RESTRICT: Lehnt den Lösch- oder Aktualisierungsvorgang für die übergeordnete Tabelle ab. Das Angeben von RESTRICT (oder NO ACTION) entspricht dem Weglassen der Klausel ON DELETE oder ON UPDATE.

Wie für keine Aktion

• KEINE AKTION: Ein Schlüsselwort aus Standard-SQL. In MySQL entspricht RESTRICT. InnoDB lehnt den Lösch- oder Aktualisierungsvorgang für die übergeordnete Tabelle ab, wenn die referenzierte Tabelle einen zugehörigen Fremdschlüsselwert enthält. Einige Datenbanksysteme haben verzögerte Prüfungen, und NO ACTION ist eine zurückgestellte Prüfung. In MySQL werden Fremdschlüsseleinschränkungen sofort überprüft, sodass NO ACTION mit RESTRICT identisch ist.

DELETE RESTRICT schützt die Eltern vor dem Löschen, nicht die Kinder.

RolandoMySQLDBA
quelle
5

Wenn Sie den Elternteil löschen und das Kind verlassen möchten, möchten Sie wahrscheinlich die ON DELETE SET NULLOption:

SET NULL: Löschen oder aktualisieren Sie die Zeile aus der übergeordneten Tabelle und setzen Sie die Fremdschlüsselspalte oder -spalten in der untergeordneten Tabelle auf NULL. Es werden sowohl die Klauseln ON DELETE SET NULL als auch ON UPDATE SET NULL unterstützt.

Wenn Sie eine SET NULL-Aktion angeben, stellen Sie sicher, dass Sie die Spalten in der untergeordneten Tabelle nicht als NOT NULL deklariert haben.

Es gibt eine Menge von ‚nicht‘ in diesem letzten Satz, so nur sicherstellen , dass die parent_id kann NULL sein.

Siehe auch diese verwandte Frage: Was ist der Zweck von SET NULL in den Einschränkungen zum Löschen / Aktualisieren von Fremdschlüsseln ?

Durch das Definieren eines Fremdschlüssels haben Sie die Datenbank angewiesen, keine Einträge in der untergeordneten Tabelle zu akzeptieren, die im übergeordneten Element keinen entsprechenden Wert haben.

Derek Downey
quelle