SQL bietet verschiedene Möglichkeiten, Daten in einer Tabelle zu aktualisieren oder einzufügen:
Wann und was verwenden:
INSERT.UPDATE mit Bedingungen.MERGE oder UPSERT zu verwenden – dies spart Komplexität und verringert die Anzahl der SQL-Anfragen.Beispiel (PostgreSQL):
INSERT INTO employees(id, name, salary) VALUES (1, 'Ivan', 100000) ON CONFLICT (id) DO UPDATE SET salary = EXCLUDED.salary;
Einfluss auf Leistung und Integrität:
Was passiert, wenn Sie versuchen, ein UPSERT auf ein eindeutiges Feld auszuführen, aber gleichzeitig in derselben Transaktion dieselbe Zeile einfügen und aktualisieren?
Richtige Antwort: Es kann zu einem Sperr-/Konfliktfehler kommen, da die Transaktion versucht, dieselbe Zeile zweimal zu ändern. Die Operation wird entweder nicht abgeschlossen oder schlägt mit einem deadlock-Fehler je nach DBMS fehl.
Beispiel:
BEGIN; INSERT INTO users(id, name) VALUES (1, 'Oleg') ON CONFLICT (id) DO UPDATE SET name = EXCLUDED.name; UPDATE users SET name = 'Petr' WHERE id = 1; COMMIT;
Bei falscher Reihenfolge und Isolationsstufe kann es zu Konflikten bei den Änderungen kommen.
Geschichte Nr. 1
In einer Logik zur Datenmigration wurde eine Kombination aus SELECT und dann INSERT oder UPDATE verwendet, was manchmal dazu führte, dass eine andere Transaktion die Daten früher festlegte und ein Fehler „duplicate key“ auftrat. Dies führte zu häufigen Ausfällen beim nächtlichen Datenexport, sodass die Logik auf UPSERT umgestellt werden musste.
Geschichte Nr. 2
In einem Projekt mit MySQL wurde ON DUPLICATE KEY UPDATE fehlerhaft angewendet, was zusammengesetzte eindeutige Schlüssel nicht korrekt berücksichtigte. Infolgedessen wurden einige Daten nicht aktualisiert, und es traten Duplikate auf. Das Problem konnte nur in der Produktionsumgebung identifiziert werden.
Geschichte Nr. 3
In einem Projekt wurde UPDATE anstelle von UPSERT zur Synchronisation von Benutzerdaten verwendet. Bei Verbindungsfehlern ging ein Teil der Daten verloren, da Aktualisierungen für neue Benutzer übersprungen wurden. Nach der Analyse wurde MERGE/UPSERT vollständig implementiert.