sql >> Base de Datos >  >> RDS >> Mysql

INSERTAR IGNORAR vs INSERTAR ... EN ACTUALIZACIÓN DE CLAVE DUPLICADA

Recomendaría usar INSERT...ON DUPLICATE KEY UPDATE .

Si usa INSERT IGNORE , la fila no se insertará realmente si da como resultado una clave duplicada. Pero la declaración no generará un error. En su lugar, genera una advertencia. Estos casos incluyen:

  • Insertar una clave duplicada en columnas con PRIMARY KEY o UNIQUE restricciones
  • Insertar un NULL en una columna con un NOT NULL restricción.
  • Insertar una fila en una tabla particionada, pero los valores que inserta no se asignan a una partición.

Si usa REPLACE , MySQL en realidad hace un DELETE seguido de INSERT internamente, lo que tiene algunos efectos secundarios inesperados:

  • Se asigna un nuevo ID de incremento automático.
  • Las filas dependientes con claves foráneas pueden eliminarse (si usa claves foráneas en cascada) o evitar el REPLACE .
  • Disparadores que se disparan en DELETE se ejecutan innecesariamente.
  • Los efectos secundarios también se propagan a las réplicas.

corrección: ambos REPLACE y INSERT...ON DUPLICATE KEY UPDATE son invenciones patentadas no estándar específicas de MySQL. ANSI SQL 2003 define un MERGE declaración que puede resolver la misma necesidad (y más), pero MySQL no es compatible con MERGE declaración.

Un usuario intentó editar esta publicación (los moderadores rechazaron la edición). La edición intentó agregar un reclamo que INSERT...ON DUPLICATE KEY UPDATE hace que se asigne una nueva identificación de incremento automático. Es cierto que la nueva identificación es generada , pero no se usa en la fila modificada.

Vea la demostración a continuación, probada con Percona Server 5.5.28. La variable de configuración innodb_autoinc_lock_mode=1 (el 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\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

Lo anterior demuestra que la instrucción IODKU detecta el duplicado e invoca la actualización para cambiar el valor de u . Tenga en cuenta el AUTO_INCREMENT=3 indica que se generó una identificación, pero no se usó en la fila.

Mientras que REPLACE elimina la fila original e inserta una nueva fila, generando y almacenar una nueva identificación de incremento automático:

mysql> select * from foo;
+----+------+
| id | u    |
+----+------+
|  1 |   20 |
+----+------+
mysql> replace into foo (u) values (20);
mysql> select * from foo;
+----+------+
| id | u    |
+----+------+
|  3 |   20 |
+----+------+