Recomendaría usar .
Se usa INSERT IGNORE
a continuación, a fila non se inserirá se resulta nunha tecla duplicada. Pero a declaración non xerará un erro. En vez diso, xera unha advertencia. Estes casos inclúen:
- Inserir unha tecla duplicada nas columnas con
PRIMARY KEY
ouUNIQUE
. - inserir un nulo nunha columna cunha restrición
NOT NULL
. - Inserir unha fila a unha táboa de partición, pero os valores que insertos non están asignados a unha partición.
Se usa REPLACE
MySQL realmente fai un DELETE
seguido por un INSERT
internamente, que ten algúns efectos secundarios inesperados:
- Unha nova identificación de auto-inclinación está asignada.
- o Pódense eliminar filas dependentes con teclas externas (se se usan as teclas externas en cascada) ou evita o
REPLACE
. - que disparar o lume sobre
DELETE
son executados innecesariamente. - Os efectos secundarios tamén están estendidos aos escravos de replicación ión.
Corrección: ambos REPLACE
e son invencións non estándar, propietarios, específicos MySQL. ANSI SQL 2003 define un MERGE
que pode resolver a mesma necesidade (e máis), pero MySQL non admite a declaración
.
Un usuario intentou editar esta publicación (a edición foi rexeitada polos moderadores). A edición intentou engadir unha afirmación de que INSERT...ON DUPLICATE KEY UPDATE
fai unha nova asignación de identificación de auto-inclinación. É certo que a nova ID é xerada pero non se usa na fila modificada.
Vexa a demostración a continuación, probada co servidor permanentemente 5.5.28. A variable de configuración innodb_autoinc_lock_mode=1
(o valor predeterminado):
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\GCREATE 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=latin1mysql> 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\GCREATE 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
O anterior mostra que a declaración iodku detecta o duplicado e invoca a actualización para cambiar o valor de u
. Teña en conta que o AUTO_INCREMENT=3
indica que se xerou unha identificación, pero non se usou na fila.
Mentres REPLACE
elimina a fila orixinal e inserir unha nova fila, xerar e almacenar unha nova identificación de auto-inclinación:
mysql> select * from foo;+----+------+| id | u |+----+------+| 1 | 20 |+----+------+mysql> replace into foo (u) values (20);mysql> select * from foo;+----+------+| id | u |+----+------+| 3 | 20 |+----+------+