Fremdschlüsseleinschränkungen mit ON Update, On Delete (Restrict, No Action, Cascade, Null)
Zögern Sie nicht, der Datenbank Einschränkungen aufzuerlegen. Sie können sicher sein, dass Sie über eine konsistente Datenbank verfügen, und das ist einer der guten Gründe, eine Datenbank zu verwenden. Vor allem, wenn Sie mehrere Anwendungen haben, die dies anfordern (oder nur eine Anwendung, aber mit einem direkten Modus und einem Batch-Modus mit unterschiedlichen Quellen).
Mit MySQL haben Sie keine erweiterten Einschränkungen wie in PostgreSQL, aber zumindest sind die Fremdschlüsselbeschränkungen ziemlich fortgeschritten.
Nehmen wir ein Beispiel, eine Firmentabelle mit einer Benutzertabelle, die Personen aus diesem Unternehmen enthält
CREATE TABLE COMPANY (
company_id INT NOT NULL,
company_name VARCHAR(50),
PRIMARY KEY (company_id)
) ENGINE=INNODB;
CREATE TABLE USER (
user_id INT,
user_name VARCHAR(50),
company_id INT,
INDEX company_id_idx (company_id),
FOREIGN KEY (company_id) REFERENCES COMPANY (company_id) ON...
) ENGINE=INNODB;
Schauen wir uns die ON UPDATE-Klausel an:
- ON UPDATE RESTRICT : die Vorgabe : Wenn Sie versuchen, eine company_id in der Tabelle COMPANY zu aktualisieren, lehnt die Engine die Operation ab, wenn mindestens ein USER auf diese Firma verlinkt.
- ON UPDATE NO ACTION : wie RESTRICT.
- ON UPDATE CASCADE : normalerweise das Beste: Wenn Sie eine company_id in einer Zeile der Tabelle COMPANY aktualisieren, aktualisiert die Engine sie entsprechend für alle USER-Zeilen, die auf diese COMPANY verweisen (aber keine aktivierten Trigger in der USER-Tabelle, Warnung). Die Engine verfolgt die Änderungen für Sie, das ist gut.
- ON UPDATE SET NULL : Wenn Sie eine company_id in einer Zeile der Tabelle COMPANY aktualisieren, setzt die Engine die zugehörigen USERs company_id auf NULL (sollte im Feld USER company_id verfügbar sein). Ich kann bei einem Update nichts Interessantes sehen, was damit zu tun hat, aber ich kann mich irren.
Und jetzt auf der ON DELETE-Seite:
- ON DELETE RESTRICT : die Standardeinstellung: Wenn Sie versuchen, eine company_id-ID in der Tabelle COMPANY zu löschen, lehnt die Engine die Operation ab, wenn mindestens ein BENUTZER auf diese Firma verlinkt, kann Ihr Leben retten.
- ON DELETE NO ACTION : wie RESTRICT
- ON DELETE CASCADE : gefährlich : Wenn Sie eine Firmenzeile in der Tabelle COMPANY löschen, löscht die Engine auch die zugehörigen USERs. Dies ist gefährlich, kann aber verwendet werden, um automatische Bereinigungen für sekundäre Tabellen vorzunehmen (es kann also etwas sein, das Sie wollen, aber ganz sicher nicht für ein COMPANY<->USER-Beispiel)
- ON DELETE SET NULL : handful : Wenn Sie eine COMPANY-Zeile löschen, haben die zugehörigen USERs automatisch die Beziehung zu NULL. Wenn Null Ihr Wert für Benutzer ohne Unternehmen ist, kann dies ein gutes Verhalten sein, z. B. müssen Sie die Benutzer möglicherweise als Autoren einiger Inhalte in Ihrer Anwendung behalten, aber das Entfernen des Unternehmens ist für Sie kein Problem.
Normalerweise ist meine Standardeinstellung: ON DELETE RESTRICT ON UPDATE CASCADE. mit einigen ON DELETE ON DELETE CASCADE für Track-Tabellen (Protokolle – nicht alle Protokolle–, solche Dinge) und ON DELETE SET NULL, wenn die Master-Tabelle ein „einfaches Attribut“ für die Tabelle ist, die den Fremdschlüssel enthält, wie eine JOB-Tabelle für die USER-Tabelle.