3 Stimmen

Gibt es einen Nachteil bei der blinden Verwendung von INSERT in MySQL?

Oft möchte ich einen Wert zu einer Tabelle hinzufügen oder den Wert aktualisieren, wenn der Schlüssel bereits existiert. Dazu gibt es mehrere Möglichkeiten, vorausgesetzt, in den Spalten "user_id" und "pref_key" im Beispiel ist ein Primärschlüssel oder eindeutiger Schlüssel festgelegt:

1. Blindes Einfügen, Aktualisieren, wenn ein Fehler mit doppelten Schlüsseln auftritt:

// Try to insert as a new value
INSERT INTO my_prefs 
(user_id, pref_key, pref_value)
VALUES (1234, 'show_help', 'true');

// If a duplicate-key error occurs run an update query
UPDATE my_prefs 
SET pref_value = 'true'
WHERE user_id=1234 AND pref_key='show_help';

2. Prüfen Sie, ob es vorhanden ist, und wählen Sie dann oder aktualisieren Sie:

// Check for existence
SELECT COUNT(*) 
FROM my_prefs
WHERE user_id=1234 AND pref_key='show_help';

// If count is zero, insert
INSERT INTO my_prefs 
(user_id, pref_key, pref_value) 
VALUES (1234, 'show_help', 'true');

// If count is one, update
UPDATE my_prefs 
SET pref_value = 'true' 
WHERE user_id=1234 AND pref_key='show_help';

Die erste Methode scheint vorzuziehen zu sein, da sie nur eine Abfrage für neue Einfügungen und zwei für eine Aktualisierung erfordert, während die zweite Methode immer zwei Abfragen erfordert. Gibt es irgendetwas, das ich übersehe, das es zu einer schlechten Idee machen würde, blind einzufügen?

12voto

Ken Punkte 73996

Sehen Sie sich die ON DUPLICATE KEY-Syntax in http://dev.mysql.com/doc/refman/5.0/en/insert-select.html

INSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE]
[INTO] tbl_name [(col_name,...)]
SELECT ...
[ ON DUPLICATE KEY UPDATE col_name=expr, ... ]

0 Stimmen

Das ist verdammt genial! Ich werde jetzt etwa 2 Seiten Code kürzen gehen.

0 Stimmen

Das wusste ich nicht; wir verwenden immer noch MySQL 4 (weil ein Upgrade nicht trivial ist), das diese Funktion nicht bietet. Es gibt REPLACE, und wir verwenden es, das eine ähnliche Funktion hat, aber weniger flexibel ist.

7voto

Vinko Vrsalovic Punkte 252104

Es gibt noch eine dritte Möglichkeit für MySQL, die in diesem RDBMS die bevorzugte ist

INSERT INTO my_prefs 
(user_id, pref_key, pref_value) 
VALUES (1234, 'show_help', 'true')
ON DUPLICATE KEY 
UPDATE pref_value = 'true'

0 Stimmen

Wow! Ich wusste nicht, dass das existiert!

4voto

Dave Verwer Punkte 6129

Ich persönlich bin nie ein Fan von ausnahmebasierter Programmierung (das Erwarten einer Ausnahme im normalen Betrieb einer Anwendung), und für mich ist das zweite Beispiel viel lesbarer/wartbarer.

Es gibt Situationen, in denen dies einen Unterschied machen würde (z. B. sehr enge Schleifen), aber ich denke, es sollte einen guten Grund geben, einen solchen Code zu schreiben, anstatt ihn als Standard zu verwenden.

0 Stimmen

In Ruby vielleicht, aber in einer Datenbank ist das nicht der Fall. Der Overhead der Prüfung in einer Tabelle ist nicht vergleichbar mit dem Overhead der Prüfung eines Objekts im Speicher. Sie wenden die Standards für Ihre Sprache falsch auf eine Datenbank an. Datenbanken haben nicht umsonst den gegenteiligen Standard, der viel besser funktioniert.

0 Stimmen

Das ist nicht ungewöhnlich. Je mehr ich über SQL Server lerne, desto mehr wird mir klar, dass mein Standard für meinen Oracle-Code eine schreckliche Idee für SQL Server-Code wäre. Nur weil er an einer Stelle gilt, heißt das nicht, dass er überall eine gute Idee ist.

3voto

Georgi Punkte 4362

Wenn Sie "die Ausnahme" vermeiden wollen, indem Sie vielleicht eine Doublette einfügen, und Sie wollen Standard-SQL verwenden (und Ihre Programmiersprache/Datenbank gibt die Anzahl der aktualisierten Zeilen zurück), dann verwenden Sie die folgenden "SQL"-Befehle (Pseudocode):

int i = SQL("UPDATE my_prefs ...");
if(i==0) {
    SQL("INSERT INTO my_prefs ...");
}

Dabei wird auch berücksichtigt, dass in den meisten Anwendungsfällen Aktualisierungen häufiger vorkommen als Einfügungen.

0 Stimmen

Warum werden Aktualisierungen häufiger durchgeführt als Einfügungen? Ich wette, dass die Leute auf SO viel häufiger neue Antworten einfügen als sie sie bearbeiten.

2voto

Paul Kroll Punkte 572

Möglicherweise können Sie stattdessen REPLACE verwenden, oder wenn Sie ein aktuelleres MySQL verwenden, haben Sie die Möglichkeit, " EINFÜGEN ... BEI DOPPELTEM SCHLÜSSEL AKTUALISIEREN "

Die Tatsache, dass mehrere Leute dieses Problem kurz nacheinander angesprochen haben, zeigt, dass man bei Problemen immer in den MySQL-Dokumenten nachsehen sollte, da sie gut sind und in vielen Fällen direkt zur Lösung führen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X