18 октября 2007 г.
Для начала: с последней версии MySQL синтаксис, представленный в заголовке, невозможен. Но есть несколько очень простых способов выполнить то, что ожидается, используя существующие функциональные возможности.
Существует 3 возможных решения: использование INSERT IGNORE, REPLACE или INSERT… ON DUPLICATE KEY UPDATE.
Представьте, что у нас есть стол:
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;
Теперь представьте, что у нас есть автоматический конвейер, импортирующий метаданные транскриптов из Ensembl, и что по разным причинам конвейер может быть прерван на любом этапе выполнения. Таким образом, нам необходимо обеспечить две вещи:
повторные выполнения конвейера не уничтожат нашу базу данных
повторные выполнения не прекратятся из-за ошибок «дублирования первичного ключа».
Способ 1: использование REPLACE
Это очень просто:
REPLACE INTO `transcripts`
SET `ensembl_transcript_id` = 'ENSORGT00000000001',
`transcript_chrom_start` = 12345,
`transcript_chrom_end` = 12678;
Если запись существует, она будет перезаписана; если он еще не существует, он будет создан. Однако использование этого метода неэффективно для нашего случая: нам не нужно перезаписывать существующие записи, просто пропустить их.
Способ 2: использование INSERT IGNORE Также очень просто:
INSERT IGNORE INTO `transcripts`
SET `ensembl_transcript_id` = 'ENSORGT00000000001',
`transcript_chrom_start` = 12345,
`transcript_chrom_end` = 12678;
Здесь, если 'ensembl_transcript_id' уже присутствует в базе данных, он будет пропущен (игнорируется). (Точнее, вот цитата из справочного руководства MySQL: «Если вы используете ключевое слово IGNORE, ошибки, возникающие при выполнении оператора INSERT, обрабатываются вместо этого как предупреждения. Например, без IGNORE - строка, которая дублирует существующий индекс UNIQUE или значение PRIMARY KEY в таблице вызывает ошибку дубликата ключа, и оператор отменяется. ».) Если запись еще не существует, она будет создана.
Этот второй метод имеет несколько потенциальных недостатков, в том числе не прерывание запроса в случае возникновения любой другой проблемы (см. Руководство). Таким образом, его следует использовать, если он был предварительно протестирован без ключевого слова IGNORE.
Способ 3: использование INSERT… ON DUPLICATE KEY UPDATE:
Третий вариант - использовать INSERT … ON DUPLICATE KEY UPDATE
синтаксис, а в части UPDATE ничего не делать, делать какую-то бессмысленную (пустую) операцию, например, вычисление 0 + 0 (Джеффрей предлагает выполнить присвоение id = id для механизма оптимизации MySQL, чтобы игнорировать эту операцию). Преимущество этого метода заключается в том, что он игнорирует только повторяющиеся ключевые события и по-прежнему прерывается при других ошибках.
В качестве последнего уведомления: этот пост был вдохновлен Xaprb. Я бы также посоветовал обратиться к его другому посту по написанию гибких SQL-запросов.