18 октября 2007
Для начала: с последней версии MySQL синтаксис, представленный в заголовке, не
возможный. Но есть несколько очень простых способов сделать то, что
ожидается использование существующего функционала.
Существует 3 возможных решения: использование INSERT IGNORE, REPLACE или
ВСТАВИТЬ… НА ДУБЛИКАТ. КЛЮЧЕВОЕ ОБНОВЛЕНИЕ.
Представьте, что у нас есть таблица:
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) повторные казни конвейера не разрушат наши
базы данных, и 2) повторные казни не умрут из-за ‘дубликата
ошибки первичного ключа.
Способ 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.
Есть еще один вариант: использовать INSERT … ON DUPLICATE KEY UPDATE
синтаксис, а в части ОБНОВЛЕНИЕ просто ничего не делать, делать некоторые бессмысленные
(пустая) операция, такая как вычисление 0 + 0 (Джеффри предлагает сделать
id = идентификатор для механизма оптимизации MySQL, чтобы игнорировать это
операция). Преимущество этого метода в том, что он игнорирует только дубликаты
ключевые события и по-прежнему прерывается при других ошибках.
В качестве последнего уведомления: этот пост был вдохновлен Xaprb. Я бы также посоветовал
обратитесь к его другому посту по написанию гибких SQL-запросов.