it-swarm.com.de

Unterschied zwischen On Delete Cascade und On Update Cascade in MySQL

Ich habe zwei Tabellen in der MySQL-Datenbank - parent, child. Ich versuche, meiner untergeordneten Tabelle basierend auf der übergeordneten Tabelle Fremdschlüsselreferenzen hinzuzufügen. Gibt es einen signifikanten Unterschied zwischen ON UPDATE CASCADE und ON DELETE CASCADE

Mein Elterntisch

CREATE TABLE parent (
    id INT NOT NULL,
    PRIMARY KEY (id)
) ENGINE=INNODB;

Meine Frage ist: Was ist der Unterschied zwischen den folgenden SQL-Abfragen.

  1. ON DELETE CASCADE

    CREATE TABLE child (
        id INT, 
        parent_id INT,
        INDEX par_ind (parent_id),
        FOREIGN KEY (parent_id) 
            REFERENCES parent(id)
            ON DELETE CASCADE
    ) ENGINE=INNODB;
    
  2. ON UPDATE CASCADE

    CREATE TABLE child (
        id INT, 
        parent_id INT,
        INDEX par_ind (parent_id),
        FOREIGN KEY (parent_id) 
            REFERENCES parent(id)
            ON UPDATE CASCADE
    ) ENGINE=INNODB;
    
  3. ON UPDATE CASCADE ON DELETE CASCADE

    CREATE TABLE child (
            id INT, 
            parent_id INT,
            INDEX par_ind (parent_id),
            FOREIGN KEY (parent_id) 
                REFERENCES parent(id)
                ON UPDATE CASCADE ON DELETE CASCADE
        ) ENGINE=INNODB;
    

Gibt es Fehler in den Abfragen? Was bedeuten diese Abfragen (1,2 & 3)? Sind sie gleich ???

53
Lonewolf

Ein sehr guter Thread zu diesem Thema ist zu finden hier und auch hier . Die endgültige Anleitung für MySQL ist natürlich die Dokumentation hier .

Im SQL 2003-Standard gibt es 5 verschiedene referenzielle Aktionen:

  1. KASKADE
  2. BESCHRÄNKEN
  3. KEINE AKTION
  4. SET NULL
  5. STANDARD EINSTELLEN

Um die Frage zu beantworten:

  1. [~ # ~] Kaskade [~ # ~]

    • ON DELETE CASCADE Bedeutet, dass beim Löschen des übergeordneten Datensatzes auch alle untergeordneten Datensätze gelöscht werden. Dies ist meiner Meinung nach keine gute Idee. Sie sollten alle Daten verfolgen, die jemals in einer Datenbank vorhanden waren. Dies kann jedoch mit TRIGGERs erfolgen. (Siehe jedoch Einschränkung in den Kommentaren unten).

    • ON UPDATE CASCADE Bedeutet, dass sich der untergeordnete Primärwert ändert, wenn der übergeordnete Primärschlüssel geändert wird, um dies widerzuspiegeln. Wieder meiner Meinung nach keine gute Idee. Wenn Sie PRIMARY KEY Regelmäßig (oder überhaupt!) Ändern, stimmt etwas mit Ihrem Design nicht. Siehe auch Kommentare.

    • ON UPDATE CASCADE ON DELETE CASCADE Bedeutet, dass wenn Sie UPDATE [~ # ~] oder [~ # ~] DELETE Beim Elternteil wird die Änderung auf das Kind übertragen. Dies ist das Äquivalent von AND für die Ergebnisse der ersten beiden Anweisungen.

  2. [~ # ~] einschränken [~ # ~]

    • RESTRICT bedeutet, dass jeder Versuch, das übergeordnete Element zu löschen und/oder zu aktualisieren, fehlschlägt und einen Fehler auslöst. Dies ist das Standardverhalten für den Fall, dass eine referenzielle Aktion nicht explizit angegeben wird.

      Für einen ON DELETE Oder ON UPDATE, Der nicht angegeben ist, lautet die Standardaktion immer RESTRICT`.

  3. KEINE AKTION

    • NO ACTION: Aus dem Handbuch . Ein Schlüsselwort aus Standard-SQL. In MySQL entspricht RESTRICT. Der MySQL Server 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 aufgeschobene Prüfungen, und NO ACTION Ist eine aufgeschobene Prüfung. In MySQL werden Fremdschlüsseleinschränkungen sofort überprüft, sodass NO ACTION Mit RESTRICT identisch ist.
  4. SET NULL

    • SET NULL - wieder aus dem Handbuch. 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. Dies ist meiner Meinung nach nicht die beste Idee, vor allem, weil es keine Möglichkeit gibt, "Zeitreisen" zu unternehmen - dh in die untergeordneten Tabellen zurückzublicken und Datensätze mit NULLs mit dem entsprechenden übergeordneten Datensatz zu verknüpfen - entweder CASCADE oder verwenden Sie TRIGGERs, um Protokollierungstabellen zu füllen und Änderungen zu verfolgen (siehe jedoch Kommentare).
  5. SET DEFAULT

    • SET DEFAULT. Ein weiterer (möglicherweise sehr nützlicher) Teil des SQL-Standards, den MySQL nicht implementiert hat! Ermöglicht dem Entwickler, einen Wert anzugeben, auf den die Fremdschlüsselspalte (n) in einem UPDATE oder einem DELETE festgelegt werden sollen. InnoDB und NDB lehnen Tabellendefinitionen mit einer SET DEFAULT - Klausel ab.

Wie oben erwähnt, sollten Sie sich einige Zeit mit der Dokumentation befassen, hier .

76
Vérace

Diese beiden Aktionen müssen jeweils ausgeführt werden, wenn der referenzierte Datensatz in der übergeordneten Tabelle seine ID ändert und wenn er gelöscht wird.

Wenn Sie ausführen:

UPDATE parent SET id = -1 WHERE id = 1;

Und es gibt mindestens einen Datensatz auf child mit parent_id = 1, 1) wird fehlschlagen; In den Fällen 2) und 3) werden alle Datensätze mit parent_id = 1 auf parent_id = -1 aktualisiert.

Wenn Sie ausführen:

DELETE FROM parent WHERE id = 1;

Und es gibt mindestens einen Datensatz auf child mit parent_id = 1, 2) wird fehlschlagen; in den Fällen 1) und 3) alle Datensätze mit parent_id = 1 werden gelöscht.

3) ist syntaktisch korrekt.

Vollständige Dokumentation finden Sie im Handbuch .

9
jynus

Ich habe nicht genug Ruf, um die vorherigen Antworten zu kommentieren. Also dachte ich, ich würde etwas näher darauf eingehen.

1) ON DELETE CASCADE bedeutet, dass beim Löschen des übergeordneten Datensatzes auch alle referenzierenden untergeordneten Datensätze gelöscht werden. ON UPDATE ist standardmäßig RESTRICT, was bedeutet, dass das UPDATE im übergeordneten Datensatz fehlschlägt.

2) Die Aktion ON DELETE ist standardmäßig RESTRICT, was bedeutet, dass DELETE im übergeordneten Datensatz fehlschlägt. ON UPDATE CASCADE aktualisiert alle referenzierenden untergeordneten Datensätze, wenn der übergeordnete Datensatz aktualisiert wird.

3) Siehe die CASCADE-Aktionen in 1) und 2) oben.

Bei Verwendung von übergeordneten Datensatz-IDs als Fremdschlüssel (in untergeordneten Tabellen) - Erfahrung sagt a) Wenn die IDs automatisch generierte Sequenznummern sind, verwenden Sie sie NICHT als Fremdschlüssel. Verwenden Sie stattdessen einen anderen eindeutigen übergeordneten Schlüssel. b) Wenn die IDs GUIDs sind, ist es in Ordnung, sie als Fremdschlüssel zu verwenden. Sie werden die Weisheit in diesem Vorschlag sehen, wenn Sie die Datensätze exportieren und importieren oder Datensätze in eine andere Datenbank kopieren. Es ist zu umständlich, während der Datenmigration automatisch generierte Sequenznummern zu verarbeiten, wenn diese als Fremdschlüssel bezeichnet werden.

6
g r