insert ignore into tabla

Posted on Fri 15 April 2011 in misc • 2 min read

Hoy vamos a hablar de bases de datos y de mysql

Hay veces que al hacer cargas masiva mediante scripts sql, la persona que te pasa los datos, no se preocupa de si en tu tabla ya existe el registro y os lo digo por experiencia o bien te piden hacer en el mejor de los casos un TRUNCATE de la tabla, otras DELETE FROM e incluso algunos hacen un DROP y la vuelven a crear. Esto con tablas con varios millones de registros.

Aunque el TRUNCATE es poco costoso para la mysql, luego volver a insertar los millones de registros si lo es, asi que vamos a mejorar el INSERT para que sea rápido y asi evitamos hacer el truncate de la tabla. Lo mas costoso seria cualquier tipo de DDL ( Data Definition Language) DROP TABLE – CREATE TABLE

Imaginemos una sencilla tabla con 2 campos, cliente y telefono. En este caso puede haber varios telefonos para un mismo cliente, pero no es posible que haya el mismo telefono para distintos clientes, por lo que la clave primaria va a ser telefono. Vamos a crear la tabla:

CREATE TABLE customer (   cid varchar(30) NULL,   tlf varchar(50) NOT NULL,   PRIMARY KEY  (tlf),   KEY cust_tlf (tlf));

En el campo cliente permito nulos ya que a veces me llegan telefonos sin cliente 😉

Supongamos que en nuestro spript hay un insert como este:

mysql> INSERT INTO customer (tlf,cid) values ("936686666","111111"); Query OK, 1 row affected (0.00 sec)

La primera vez que lo ejecutemos no habra ningun problema, ya que la clave primaria no se viola, pero si al dia siguiente, en el script viene otra vez el mismo insert y no se ha hecho un truncate de la tabla, el mismo comando dara un error:

mysql> INSERT INTO customer (tlf,cid) values ("936686666","111111"); ERROR 1062 (23000): Duplicate entry '936686666' for key 1

Como esto no esta bien y no vamos a ejecutar el script lleno de errores lo podemos hacer de una forma mas elegante y eficiente en terminos de recursos de BD:

mysql> DELETE FROM customer WHERE tlf = "936686666"; Query OK, 1 row affected (0.00 sec)

mysql> INSERT IGNORE INTO customer set tlf = "936686666", cid="111111"; Query OK, 1 row affected (0.00 sec)

mysql> INSERT IGNORE INTO customer set tlf = "936686666", cid="111111"; Query OK, 0 rows affected (0.00 sec)

Primero borramos el registro que hemos insertado y hacemos un INSERT IGNORE y vemos que hay 1 row afectado o sea que ha insertado un registro, pero la segunda vez, dice que no ha insertado nada, pero no da ningún error y así el script puede continuar correctamente sin problemas.