Бих препоръчал да използвате INSERT...ON DUPLICATE KEY UPDATE .
Ако използвате INSERT IGNORE , тогава редът всъщност няма да бъде вмъкнат, ако доведе до дублиран ключ. Но изявлението няма да генерира грешка. Вместо това генерира предупреждение. Тези случаи включват:
- Вмъкване на дублиран ключ в колони с
PRIMARY KEYилиUNIQUEограничения. - Вмъкване на NULL в колона с
NOT NULLограничение. - Вмъкване на ред в разделена таблица, но стойностите, които вмъквате, не се съпоставят с дял.
Ако използвате REPLACE , MySQL всъщност извършва DELETE последвано от INSERT вътрешно, което има някои неочаквани странични ефекти:
- Разпределя се нов идентификатор за автоматично увеличение.
- Зависимите редове с външни ключове може да бъдат изтрити (ако използвате каскадни външни ключове) или да предотвратите
REPLACE. - Задействания, които се задействат при
DELETEсе изпълняват ненужно. - Страничните ефекти се разпространяват и в копия.
корекция: и двете REPLACE и INSERT...ON DUPLICATE KEY UPDATE са нестандартни, патентовани изобретения, специфични за MySQL. ANSI SQL 2003 дефинира MERGE изявление, което може да реши същата нужда (и повече), но MySQL не поддържа MERGE изявление.
Потребител се опита да редактира тази публикация (редактирането беше отхвърлено от модераторите). Редактирането се опита да добави твърдение, което INSERT...ON DUPLICATE KEY UPDATE причинява разпределяне на нов идентификатор за автоматично увеличение. Вярно е, че новият идентификатор е генериран , но не се използва в променения ред.
Вижте демонстрация по-долу, тествана с Percona Server 5.5.28. Конфигурационната променлива innodb_autoinc_lock_mode=1 (по подразбиране):
mysql> create table foo (id serial primary key, u int, unique key (u));
mysql> insert into foo (u) values (10);
mysql> select * from foo;
+----+------+
| id | u |
+----+------+
| 1 | 10 |
+----+------+
mysql> show create table foo\G
CREATE TABLE `foo` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`u` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `u` (`u`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1
mysql> insert into foo (u) values (10) on duplicate key update u = 20;
mysql> select * from foo;
+----+------+
| id | u |
+----+------+
| 1 | 20 |
+----+------+
mysql> show create table foo\G
CREATE TABLE `foo` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`u` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `u` (`u`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1
Горното показва, че операторът IODKU открива дубликата и извиква актуализацията, за да промени стойността на u . Обърнете внимание на AUTO_INCREMENT=3 показва, че идентификаторът е генериран, но не е използван в реда.
Докато REPLACE изтрива оригиналния ред и вмъква нов ред, генерирайки и съхраняване на нов идентификатор за автоматично увеличение:
mysql> select * from foo;
+----+------+
| id | u |
+----+------+
| 1 | 20 |
+----+------+
mysql> replace into foo (u) values (20);
mysql> select * from foo;
+----+------+
| id | u |
+----+------+
| 3 | 20 |
+----+------+