18. Oktober 2007
Zu Beginn: Ab dem neuesten MySQL ist die im Titel angegebene Syntax nicht möglich. Es gibt jedoch mehrere sehr einfache Möglichkeiten, mit den vorhandenen Funktionen das zu erreichen, was erwartet wird.
Es gibt drei mögliche Lösungen: Verwenden von 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, wir haben eine automatische Pipeline, die Transkript-Metadaten aus Ensembl importiert, und dass die Pipeline aus verschiedenen Gründen bei jedem Ausführungsschritt unterbrochen werden kann. Daher müssen wir zwei Dinge sicherstellen:
Wiederholte Ausführungen der Pipeline zerstören unsere Datenbank nicht
Wiederholte Ausführungen sterben nicht aufgrund von Fehlern beim Duplizieren des Primärschlüssels.
Methode 1: Verwenden von REPLACE
Es ist sehr einfach:
REPLACE INTO `transcripts`
SET `ensembl_transcript_id` = 'ENSORGT00000000001',
`transcript_chrom_start` = 12345,
`transcript_chrom_end` = 12678;
Wenn der Datensatz vorhanden ist, wird er überschrieben. Wenn es noch nicht existiert, wird es erstellt. Die Verwendung dieser Methode ist in unserem Fall jedoch nicht effizient: Wir müssen vorhandene Datensätze nicht überschreiben, es ist in Ordnung, sie nur zu überspringen.
Methode 2: INSERT IGNORE verwenden Auch 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 Datenbank vorhanden ist, wird sie hier stillschweigend übersprungen (ignoriert). (Genauer gesagt, hier ein Zitat aus dem MySQL-Referenzhandbuch: „Wenn Sie das Schlüsselwort IGNORE verwenden, werden Fehler, die beim Ausführen der INSERT-Anweisung auftreten, stattdessen als Warnungen behandelt. Ohne IGNORE beispielsweise eine Zeile, die einen vorhandenen UNIQUE-Index dupliziert oder PRIMARY KEY-Wert in der Tabelle verursacht einen Duplikatschlüsselfehler und die Anweisung wird abgebrochen. ”.) Wenn der Datensatz noch nicht vorhanden ist, wird er erstellt.
Diese zweite Methode weist mehrere potenzielle Schwachstellen auf, einschließlich des Nichtabbruchs der Abfrage, falls ein anderes Problem auftritt (siehe Handbuch). Daher sollte es verwendet werden, wenn es zuvor ohne das Schlüsselwort IGNORE getestet wurde.
Methode 3: Verwenden von INSERT… ON DUPLICATE KEY UPDATE:
Die dritte Option ist zu verwenden INSERT … ON DUPLICATE KEY UPDATE
Syntax und im UPDATE-Teil nichts zu tun, um eine bedeutungslose (leere) Operation durchzuführen, wie z. B. die Berechnung von 0 + 0 (Geoffray schlägt vor, die Zuweisung id = id für die MySQL-Optimierungs-Engine vorzunehmen, um diese Operation zu ignorieren). Der Vorteil dieser Methode besteht darin, dass nur doppelte Schlüsselereignisse ignoriert werden und andere Fehler weiterhin abgebrochen werden.
Als letzter Hinweis: Dieser Beitrag wurde von Xaprb inspiriert. Ich würde auch empfehlen, seinen anderen Beitrag zum Schreiben flexibler SQL-Abfragen zu konsultieren.