Empecé buscando en Google y encontré este artículo que habla sobre tablas mutex.
Tengo una mesa con ~ 14 millones de registros. Si deseo agregar más datos en el mismo formato, ¿hay alguna manera de asegurar que el registro que deseo insertar no exista sin usar un par de consultas (es decir, una consulta para verificar y otra para insertar es el conjunto de resultados) vacío)?
¿Una unique
restricción en un campo garantiza insert
que fallará si ya está allí?
Parece que con solo una restricción, cuando publico el inserto a través de php, el script se rompe.
mysql
sql
primary-key
sql-insert
madriguera
fuente
fuente
Respuestas:
utilizar
INSERT IGNORE INTO table
ver http://bogdan.org.ua/2007/10/18/mysql-insert-if-not-exists-syntax.html
también hay
INSERT … ON DUPLICATE KEY UPDATE
sintaxis, puede encontrar explicaciones en dev.mysql.comPublicación de bogdan.org.ua según el caché web de Google :
fuente
INSERT … ON DUPLICATE KEY UPDATE
es mejor ya que no elimina la fila, conservando lasauto_increment
columnas y otros datos.INSERT … ON DUPLICATE KEY UPDATE
método incrementa cualquier columna AUTO_INCREMENT con una inserción fallida. Probablemente porque no ha fallado realmente, pero ACTUALIZADO.Solución:
Explicación:
La consulta más interna
utilizado como la
WHERE NOT EXISTS
condición detecta si ya existe una fila con los datos que se insertarán. Después de encontrar una fila de este tipo, la consulta puede detenerse, por lo tanto, elLIMIT 1
, se puede omitir la (microoptimización).La consulta intermedia
representa los valores a insertar.
DUAL
se refiere a una tabla especial de una fila y una columna presente de forma predeterminada en todas las bases de datos Oracle (consulte https://en.wikipedia.org/wiki/DUAL_table ). En un servidor MySQL versión 5.7.26 recibí una consulta válida al omitirFROM DUAL
, pero las versiones anteriores (como 5.5.60) parecen requerir laFROM
información. Mediante el usoWHERE NOT EXISTS
la consulta intermedia, se devuelve un conjunto de resultados vacío si la consulta más interna encontró datos coincidentes.La consulta externa
inserta los datos, si alguno es devuelto por la consulta intermedia.
fuente
INSERT IGNORE
yINSERT ON DUPLICATE KEY
requiere restricciones de clave únicas)stuff for value1
ystuff for value2
son idénticos? Esto arrojaría unDuplicate column name
SELECT 1
lugar deSELECT *
en las subconsultas. Es mucho más probable que esto pueda satisfacerse con un índice.en la actualización de claves duplicadas , o insertar ignorar pueden ser soluciones viables con MySQL.
Ejemplo de actualización de actualización de clave duplicada basada en mysql.com
Ejemplo de ignorar inserción basado en mysql.com
O:
O:
fuente
Cualquier restricción simple debería hacer el trabajo, si una excepción es aceptable. Ejemplos:
Lo siento, esto parece engañosamente simple. Sé que se ve mal confrontado con el enlace que compartes con nosotros. ;-(
Pero nunca le doy esta respuesta, porque parece satisfacer su necesidad. (De lo contrario, puede activar la actualización de sus requisitos, lo que también sería "algo bueno").
Editado : si una inserción rompe la restricción única de la base de datos, se lanza una excepción a nivel de la base de datos, transmitida por el controlador. Ciertamente detendrá su script, con una falla. Debe ser posible en PHP abordar ese caso ...
fuente
INSERT IGNORE
básicamente cambia todos los errores en advertencias para que su secuencia de comandos no se interrumpa. Luego puede ver cualquier advertencia con el comandoSHOW WARNINGS
. Y otra nota importante : las restricciones ÚNICAS no funcionan con valores NULL, es decir. row1 (1, NULL) y row2 (1, NULL) se insertarán (a menos que se rompa otra restricción, como una clave primaria). Desgraciado.Aquí hay una función PHP que insertará una fila solo si todos los valores de las columnas especificadas no existen en la tabla.
Si una de las columnas difiere, se agregará la fila.
Si la tabla está vacía, se agregará la fila.
Si existe una fila donde todas las columnas especificadas tienen los valores especificados, la fila no se agregará.
Ejemplo de uso:
fuente
mysql_*
extensión está en desuso a partir de PHP 5.5.0 y se ha eliminado a partir de PHP 7.0.0. En su lugar, se debe usar la extensión mysqli o PDO_MySQL . Consulte también la Descripción general de la API MySQL para obtener más ayuda al elegir una API MySQL.Si el registro existe, se sobrescribirá; si aún no existe, se creará.
fuente
REPLACE
puede eliminar la fila y luego insertar en lugar de actualizar. El efecto secundario es que las restricciones pueden eliminar otros objetos y se activan los desencadenantes de eliminación.Intenta lo siguiente:
fuente
Hay varias respuestas que cubren cómo resolver esto si tiene un
UNIQUE
índice que puede verificar conON DUPLICATE KEY
oINSERT IGNORE
. Ese no es siempre el caso, y comoUNIQUE
tiene una restricción de longitud (1000 bytes), es posible que no pueda cambiar eso. Por ejemplo, tuve que trabajar con metadatos en WordPress (wp_postmeta
).Finalmente lo resolví con dos consultas:
La consulta 1 es una
UPDATE
consulta normal sin efecto cuando el conjunto de datos en cuestión no está allí. La consulta 2 es unaINSERT
que depende de aNOT EXISTS
, es decir,INSERT
solo se ejecuta cuando el conjunto de datos no existe.fuente
Algo que vale la pena señalar es que INSERT IGNORE seguirá incrementando la clave principal si la declaración fue un éxito o no, como lo haría un INSERT normal.
Esto provocará lagunas en sus claves principales que podrían hacer que un programador sea mentalmente inestable. O si su aplicación está mal diseñada y depende de claves primarias incrementales perfectas, puede convertirse en un dolor de cabeza.
Examine
innodb_autoinc_lock_mode = 0
(configuración del servidor y viene con un ligero impacto en el rendimiento), o use un SELECCIONAR primero para asegurarse de que su consulta no falle (que también viene con un impacto en el rendimiento y un código adicional).fuente
SELECT
derrota es el propósito de entregar un gran lote de correosINSERT
electrónicos y no querer preocuparse por los duplicados.Actualizar o insertar sin clave primaria conocida
Si ya tiene una clave única o primaria, la otra responde con
INSERT INTO ... ON DUPLICATE KEY UPDATE ...
oREPLACE INTO ...
debería funcionar bien (tenga en cuenta que reemplazar en elimina si existe y luego inserta, por lo que no actualiza parcialmente los valores existentes).Pero si tiene los valores para
some_column_id
ysome_type
, cuya combinación se sabe que es única. Y desea actualizarsome_value
si existe o insertar si no existe. Y desea hacerlo en una sola consulta (para evitar el uso de una transacción). Esta podría ser una solución:Básicamente, la consulta se ejecuta de esta manera (menos complicado de lo que parece):
WHERE
coincidencia de cláusula.s
), donde los valores de columna se dan explícitamente (s.id es NULL, por lo que generará un nuevo identificador de incremento automático).s
se descarta (debido al LÍMITE 1 en la tablat
), y siempre activará unaON DUPLICATE KEY
que seráUPDATE
lasome_value
columna.s
).Nota: Cada tabla en una base de datos relacional debe tener al menos una
id
columna primaria de incremento automático . Si no tiene esto, agréguelo, incluso cuando no lo necesite a primera vista. Definitivamente es necesario para este "truco".fuente
INSERT INTO ... SELECT FROM
formato. ¿Por qué tu también?INSERT INTO... SELECT FROM...
solución regular . Remítame un enlace a una respuesta que sea la misma, si puede encontrarla, eliminaré esta respuesta, de lo contrario, votó mi respuesta (¿trato?). Asegúrese de verificar que la respuesta que va a vincular solo usa 1 consulta (para actualización + inserción), ninguna transacción, y puede apuntar a cualquier combinación de columnas que se sepa que son únicas (por lo que las columnas por separado no necesita ser único).