1. ¿Qué es UPSERT?
Resumen
“UPSERT” se refiere a una función en bases de datos que combina “INSERT” y “UPDATE”. Es decir, si no existe un dato nuevo, se inserta; y si el mismo dato ya existe, se actualiza. Con esta función, es posible mantener la consistencia de los datos y realizar operaciones de manera eficiente.
En MySQL, la sintaxis INSERT ... ON DUPLICATE KEY UPDATE
corresponde a esta operación. Gracias a esta función, incluso en situaciones donde se producen duplicados, se puede evitar el error de clave duplicada y actualizar los datos existentes.
Casos de uso
- Sistema de gestión de clientes: insertar un nuevo cliente si no existe y actualizar la información si ya está registrado.
- Gestión de inventario: añadir productos nuevos y actualizar las existencias de los productos existentes.
Ventajas de UPSERT en MySQL
- Evita errores de clave duplicada
- Simplifica las consultas SQL
- Mantiene la integridad de los datos
2. Uso básico de UPSERT en MySQL
En MySQL, la operación UPSERT se realiza mediante la sintaxis INSERT ... ON DUPLICATE KEY UPDATE
. Con esta sintaxis, si se genera una clave duplicada, en lugar de insertar un nuevo dato, se actualiza parcial o totalmente el existente.
Sintaxis básica
INSERT INTO nombre_tabla (columna1, columna2)
VALUES (valor1, valor2)
ON DUPLICATE KEY UPDATE
columna1 = valor1, columna2 = valor2;
Explicación:
INSERT INTO
inserta los datos en la tabla.- Si los datos ya existen en la tabla, se ejecuta la parte
ON DUPLICATE KEY UPDATE
, actualizando los valores correspondientes.
Ejemplo:
INSERT INTO users (user_id, name)
VALUES (1, 'Taro Tanaka')
ON DUPLICATE KEY UPDATE
name = 'Taro Tanaka';
En este ejemplo, si ya existe un usuario con user_id
igual a 1, se actualiza el campo name
a ‘Taro Tanaka’. Si no existe, se inserta un nuevo registro.

3. Detalles de la sintaxis SQL de UPSERT y ejemplos
Actualizar múltiples columnas
Al usar UPSERT, a veces solo se actualizan columnas específicas. En ese caso, se pueden indicar únicamente esas columnas en la cláusula ON DUPLICATE KEY UPDATE
.
INSERT INTO products (product_id, name, price)
VALUES (100, 'Portátil', 50000)
ON DUPLICATE KEY UPDATE
price = VALUES(price);
En este ejemplo, si ya existe un producto con product_id
igual a 100, solo se actualiza el price
, mientras que otras columnas (como name
) permanecen sin cambios.
4. Diferencias con otras bases de datos
En otras bases de datos distintas a MySQL también existen formas de realizar operaciones similares. Por ejemplo, en PostgreSQL o SQLite se utiliza la sintaxis INSERT ... ON CONFLICT
o MERGE
, que equivalen a UPSERT.
Ejemplo en PostgreSQL
INSERT INTO users (user_id, name)
VALUES (1, 'Taro Tanaka')
ON CONFLICT (user_id) DO UPDATE SET
name = 'Taro Tanaka';
En PostgreSQL y SQLite, la cláusula ON CONFLICT
controla el comportamiento cuando ocurre un error por clave duplicada. En cambio, MySQL utiliza ON DUPLICATE KEY UPDATE
.
Particularidades de MySQL
- En MySQL se usa
INSERT ... ON DUPLICATE KEY UPDATE
, cuya sintaxis difiere de otras bases de datos. Esto requiere atención especial al migrar aplicaciones entre motores.
5. Uso avanzado de UPSERT
Bulk UPSERT (procesamiento masivo de múltiples registros)
UPSERT no solo puede aplicarse a un único registro, sino también a múltiples registros de manera masiva. Esto mejora considerablemente la eficiencia de las operaciones en la base de datos.
INSERT INTO products (product_id, name, price)
VALUES
(100, 'Portátil', 50000),
(101, 'Smartphone', 30000)
ON DUPLICATE KEY UPDATE
price = VALUES(price);
En este ejemplo, se insertan varios productos a la vez y, si hay claves duplicadas, solo se actualiza el precio correspondiente.
UPSERT mediante procedimientos almacenados
Para optimizar el procesamiento de UPSERT, también se pueden usar procedimientos almacenados. Esto permite crear código reutilizable dentro de la base de datos, mejorando la legibilidad y el mantenimiento.

6. Trampas y precauciones de UPSERT
Transacciones y bloqueos (deadlocks)
Al usar UPSERT, especialmente con grandes volúmenes de datos, pueden ocurrir bloqueos (deadlocks). Si el nivel de aislamiento de transacciones en MySQL está configurado en REPEATABLE READ
, es más probable que se produzcan bloqueos por “gap lock”.
Estrategias para evitar gap locks
- Cambiar el nivel de aislamiento de la transacción a
READ COMMITTED
para reducir la probabilidad de deadlocks. - Si es necesario, dividir la operación de UPSERT en múltiples consultas más pequeñas y ejecutarlas de forma separada.
7. Conclusión
La función UPSERT en MySQL es muy útil para insertar y actualizar datos de manera eficiente, evitando errores de clave duplicada. Sin embargo, su implementación requiere prestar atención a riesgos como deadlocks y configuraciones de transacciones. Usado correctamente, UPSERT simplifica y optimiza las operaciones en bases de datos.