2009-09-26 32 views
311

Ich verwende "ON DELETE CASCADE" regelmäßig, aber ich verwende nie "ON UPDATE CASCADE", da ich nicht sicher bin, in welcher Situation es nützlich sein wird.Wann "ON UPDATE CASCADE" zu verwenden ist

Für die Diskussion lassen Sie einige Code sehen.

CREATE TABLE parent (
    id INT NOT NULL AUTO_INCREMENT, 
    PRIMARY KEY (id) 
); 

CREATE TABLE child (
    id INT NOT NULL AUTO_INCREMENT, parent_id INT, 
    INDEX par_ind (parent_id), 
    FOREIGN KEY (parent_id) 
     REFERENCES parent(id) 
     ON DELETE CASCADE 
); 

Für „ON DELETE CASCADE“, wenn ein Elternteil mit einem id gelöscht wird, wird ein Datensatz in Kind mit parent_id = parent.id automatisch gelöscht. Dies sollte kein Problem sein.

  1. Das bedeutet, dass „ON UPDATE CASCADE“ wird das gleiche tun, wenn id des Mutter aktualisiert wird?

  2. Wenn (1) wahr ist, bedeutet dies, dass es keine Notwendigkeit „ON UPDATE CASCADE“ zu verwenden ist, wenn parent.id nicht aktualisierbar ist (oder wird nie aktualisiert werden), wie wenn es AUTO_INCREMENT ist oder immer TIMESTAMP gesetzt werden. Ist das richtig?

  3. Wenn (2) nicht wahr ist, in welcher anderen Situation sollten wir "ON UPDATE CASCADE" verwenden?

  4. Was passiert, wenn ich (aus irgendeinem Grund) die child.parent_id aktualisieren, um etwas nicht vorhanden zu sein, wird es dann automatisch gelöscht werden?

Nun, ich weiß, über einen Teil der Frage kann programmically sein Test zu verstehen, aber ich möchte auch wissen, ob jede dieser Datenbank-Anbieter abhängig ist oder nicht.

Bitte werfen Sie etwas Licht.

+1

Siehe auch: http://stackoverflow.com/questions/6894162/postgresql-how-to-compact-renumber-id-for-all-tables-and-reset-sequences-to-max –

Antwort

352

Es stimmt, dass wenn Ihr Primärschlüssel nur ein Identitätswert ist, der automatisch inkrementiert wird, Sie für ON UPDATE CASCADE keine wirkliche Verwendung hätten.

Lassen Sie uns jedoch sagen, dass Ihr Primärschlüssel ein 10-stelliger UPC-Barcode ist und Sie ihn wegen der Erweiterung in einen 13-stelligen UPC-Barcode ändern müssen. In diesem Fall können Sie mit ON UPDATE CASCADE den Wert des Primärschlüssels ändern, und alle Tabellen mit Fremdschlüsselreferenzen auf den Wert werden entsprechend geändert.

In Bezug auf # 4, wenn Sie die Kind-ID in etwas ändern, die nicht in der übergeordneten Tabelle vorhanden ist (und Sie haben referentielle Integrität), sollten Sie einen Fremdschlüsselfehler erhalten.

+4

musste nur verwenden 'ON UPDATE CASCADE' selbst, um Primärschlüssel in einer alten Tabelle zu aktualisieren, die keinen automatisch inkrementierten Schlüssel verwendet –

63
  1. Ja, bedeutet dies, dass zum Beispiel, wenn Sie UPDATE parent SET id = 20 WHERE id = 10 alle Kinder parent_id die von 10 tun wird auch

  2. Wenn Sie das Feld bezieht sich der Fremdschlüssel für diese Einstellung nicht aktualisiert, bis 20 aktualisiert werden, wird nicht benötigt

  3. Kann mir keine andere Verwendung vorstellen.

  4. Dies ist nicht möglich, da die Fremdschlüsseleinschränkung fehlschlagen würde.

20

Ich denke, Sie haben die Punkte ziemlich genagelt!

Wenn Sie die Best Practices für das Datenbankdesign befolgen und Ihr Primärschlüssel nie aktualisierbar ist (was meiner Meinung nach immer der Fall sein sollte), dann brauchen Sie nie wirklich die ON UPDATE CASCADE Klausel.

Zed einen guten Punkt gemacht, dass, wenn Sie ein natürlichen Schlüssel (zB ein regelmäßiges Feld aus Ihrer Datenbank-Tabelle) als Primärschlüssel verwenden, dann könnte es bestimmte Situationen, in denen Sie Ihre Primärschlüssel aktualisieren müssen . Ein anderes aktuelles Beispiel wäre die ISBN (International Standard Book Numbers), die vor nicht allzu langer Zeit von 10 auf 13 Ziffern und Zeichen geändert wurde. Diese

ist nicht der Fall, wenn Sie sich dazu entscheiden Surrogat verwenden (beispielsweise artifiziell System generierte) Schlüssel als Primärschlüssel (die meine bevorzugte Wahl in allen sein würde, aber die meisten seltenen Fällen).

Also am Ende: Wenn Ihr Primärschlüssel nie ändert, dann brauchen Sie nie die ON UPDATE CASCADE Klausel.

Marc

+0

Was sind" künstlich systemgenerierte "Schlüssel? UUIDs? – HPWD

+0

@HPWD: nur ein "künstlicher" Schlüssel (ein Wert, der nicht auf Ihren tatsächlichen Daten basiert oder von diesen abgeleitet ist), der vom System erzeugt wird - es kann * eine GUID, oder ein INT oder ein BIGINT - oder irgendetwas sein wirklich - ist egal. Punkt ist: Dieser Wert steht in keiner Beziehung zu Ihren eigenen, tatsächlichen Daten - und das System generiert diesen Wert automatisch für Sie. –

+0

@ marc-s danke, dass du dir die Zeit genommen hast, das zu schreiben. Deine Antwort ergab vollkommenen Sinn. – HPWD

4

Mein Kommentar ist in erster Linie in Bezug auf 3 # Punkt: unter welchen Umständen ON UPDATE CASCADE anwendbar ist, wenn wir gehen davon aus, dass der übergeordnete Schlüssel nicht aktualisierbar ist? Hier ist ein Fall.

Ich habe es mit einem Replikationsszenario zu tun, in dem mehrere Satelliten-Datenbanken mit einem Master zusammengeführt werden müssen. Jeder Satellit erzeugt Daten in denselben Tabellen, so dass das Zusammenführen der Tabellen mit dem Master zu Verletzungen der Eindeutigkeitsbeschränkung führt. Ich versuche, ON UPDATE CASCADE als Teil einer Lösung zu verwenden, in der ich die Schlüssel bei jeder Zusammenführung erneut inkrementiere. ON UPDATE CASCADE sollte diesen Prozess vereinfachen, indem ein Teil des Prozesses automatisiert wird.

11

Vor ein paar Tagen hatte ich ein Problem mit Triggern, und ich habe herausgefunden, dass ON UPDATE CASCADE kann nützlich sein. Werfen Sie einen Blick auf dieses Beispiel (PostgreSQL):

CREATE TABLE club 
(
    key SERIAL PRIMARY KEY, 
    name TEXT UNIQUE 
); 

CREATE TABLE band 
(
    key SERIAL PRIMARY KEY, 
    name TEXT UNIQUE 
); 

CREATE TABLE concert 
(
    key SERIAL PRIMARY KEY, 
    club_name TEXT REFERENCES club(name) ON UPDATE CASCADE, 
    band_name TEXT REFERENCES band(name) ON UPDATE CASCADE, 
    concert_date DATE 
); 

In meiner Ausgabe hatte ich einige zusätzliche Operationen (Trigger) zu definieren, für Konzert der Tabelle zu aktualisieren. Diese Operationen mussten club_name und band_name ändern. Ich konnte es nicht tun, wegen der Referenz. Ich konnte das Konzert nicht ändern und dann mit den Club- und Bandtischen umgehen. Ich könnte es auch nicht anders machen. ON UPDATE CASCADE war der Schlüssel zur Lösung des Problems.

+2

Guter Kommentar. Ich finde auf Update-Kaskade auch nützlich, auf jeden Fall musst du deine ID ändern. Ich stimme auch mit anderen überein, dass diese Änderung nicht so typisch sein sollte. Wenn Sie z. B. zitieren, denke ich, dass in großen Datenmengen möglicherweise die Verwendung von Fremdschlüsseln mithilfe von Textfeldern nicht zu der schnellsten Leistung des Datenbankmoduls führt. Beachten Sie, dass, wenn die Fremdbeziehung in der Konzertetabelle club.SERIAL und die Band.SERIAL verwendet, die Änderungen im Namen die Beziehung zwischen den Tabellen nicht beeinflussen würden. Allerdings finde ich ON UPDATE CASCADE ist ein großartiges Werkzeug zur Lösung von Notfällen. Grüße –

+3

Dies ist ein fragwürdiger Entwurf, der jedoch für ein ziemlich konstruiertes Beispiel sorgt. Was ist der Zweck, zwei 'SERIAL'-Spalten in' club' und 'band' als Primärschlüssel zu behalten, wenn Sie' name' anstelle des Primärschlüssels jeder Tabelle referenzieren? –

3

Es ist eine ausgezeichnete Frage, ich hatte die gleiche Frage gestern. Ich habe über dieses Problem nachgedacht, speziell SUCHTE, wenn es so etwas wie "ON UPDATE CASCADE" gab und zum Glück hatten die Designer von SQL auch darüber nachgedacht. Ich stimme Ted.strauss zu, und ich habe auch Norans Fall kommentiert.

Wann habe ich es benutzt? Wie Ted sagte, wenn man mehrere Datenbanken gleichzeitig behandelt, und die Änderung in einem von ihnen, in einer Tabelle, irgendeine Art von Reproduktion in dem, was Ted "Satellitendatenbank" nennt, kann man nicht mit dem sehr originellen halten ID, und aus irgendeinem Grund müssen Sie eine neue erstellen, falls Sie die Daten auf der alten nicht aktualisieren können (zum Beispiel aufgrund von Berechtigungen, oder wenn Sie in einem Fall, der so kurzlebig ist, nach Echtheit suchen verdient es nicht die absolute und völlige Achtung der Gesamt Regeln der Normalisierung, einfach weil wird ein sehr kurzlebig Nutzen sein)

Also, ich stimme in zwei Punkten:

(A.) Ja, oft kann ein besseres Design es vermeiden; ABER

(B.) Im Falle von Migrationen, Datenbanken replizieren oder Notfälle lösen, ist es ein GROSSES WERKZEUG, das glücklicherweise vorhanden war, als ich suchte, wenn es existierte.