18. Oktober 2007
Zu Beginn: In der neuesten Version von MySQL ist die im Titel genannte Syntax nicht möglich. Aber es gibt mehrere sehr einfache Möglichkeiten, das zu erreichen, was erwartet wird zu erreichen, indem man die vorhandene Funktionalität nutzt.
Es gibt 3 mögliche Lösungen: INSERT IGNORE, REPLACE, oder INSERT ON DUPLICATE KEY UPDATE.
Stellen Sie sich vor, wir haben einen Tisch:
CREATE TABLE `transcripts` (
`ensembl_transcript_id` varchar(20) NOT NULL,
`transcript_chrom_start` int(10) unsigned NOT NULL,
`transcript_chrom_end` int(10) unsigned NOT NULL,
PRIMARY KEY (`ensembl_transcript_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Stellen Sie sich nun vor, dass wir eine automatische Pipeline haben, die Transkripte importiert Metadaten aus Ensembl importiert, und dass die Pipeline aus verschiedenen Gründen aus verschiedenen Gründen bei einem beliebigen Ausführungsschritt unterbrochen werden könnte. Daher müssen wir zwei Dinge sicherstellen Dinge sicherstellen:
-
die wiederholte Ausführung der Pipeline unsere Datenbank nicht zerstört > Datenbank
-
Wiederholte Hinrichtungen werden nicht aufgrund von "doppelten > Primärschlüssel' Fehler.
Methode 1: Verwendung von REPLACE
Es ist ganz einfach:
REPLACE INTO `transcripts`
SET `ensembl_transcript_id` = 'ENSORGT00000000001',
`transcript_chrom_start` = 12345,
`transcript_chrom_end` = 12678;
Ist der Datensatz vorhanden, wird er überschrieben; ist er noch nicht vorhanden, wird er existiert, wird er neu erstellt. Diese Methode ist jedoch nicht effizient für unseren Fall nicht effizient: Wir müssen keine bestehenden Datensätze überschreiben, es reicht aus sie einfach zu überspringen.
Methode 2: mit INSERT IGNORE Ebenfalls sehr einfach:
INSERT IGNORE INTO `transcripts`
SET `ensembl_transcript_id` = 'ENSORGT00000000001',
`transcript_chrom_start` = 12345,
`transcript_chrom_end` = 12678;
Wenn die "ensembl_transcript_id" bereits in der Datei Datenbank vorhanden ist, wird sie stillschweigend übersprungen (ignoriert). (Um genauer zu sein, hier ist ein Zitat aus dem MySQL-Referenzhandbuch: "Wenn Sie das IGNORE Schlüsselwort benutzen, werden Fehler, die während der Ausführung der INSERT-Anweisung auftreten stattdessen als Warnungen behandelt. Ohne IGNORE würde zum Beispiel eine Zeile, die einen vorhandenen UNIQUE-Index oder PRIMARY KEY-Wert in der Tabelle dupliziert einen Duplikat-Schlüssel-Fehler und die Anweisung wird abgebrochen."). Wenn der Datensatz noch nicht existiert, wird er erstellt.
Diese zweite Methode hat mehrere potenzielle Schwachstellen, darunter kein Abbruch der Abfrage, wenn ein anderes Problem auftritt (siehe das Handbuch). Daher sollte sie verwendet werden, wenn sie zuvor ohne das IGNORE-Schlüsselwort.
Methode 3: mit INSERT ON DUPLICATE KEY UPDATE:
Die dritte Möglichkeit ist die Verwendung von INSERT … ON DUPLICATE KEY UPDATE
Syntax, und im UPDATE-Teil einfach nichts tun einige sinnlose (leere) Operation, wie die Berechnung von 0+0 (Geoffray schlägt vor, die id=id-Zuweisung, damit die MySQL-Optimierungsmaschine diese Operation ignoriert Operation zu ignorieren). Der Vorteil dieser Methode ist, dass sie nur doppelte Schlüsselereignisse ignoriert Schlüsselereignisse ignoriert und bei anderen Fehlern immer noch abbricht.
Zum Schluss noch ein Hinweis: Dieser Beitrag wurde von Xaprb inspiriert. Ich würde auch raten seinen anderen Beitrag über das Schreiben flexibler SQL-Abfragen zu lesen.