El lenguaje de manipulación de datos particionado (DML particionado) se ha diseñado para los siguientes tipos de actualizaciones y eliminaciones en bloque:
- Limpieza periódica y recolección de elementos no utilizados. Por ejemplo, puedes eliminar filas antiguas o asignar el valor
NULL
a las columnas. - Rellenar las nuevas columnas con valores predeterminados. Por ejemplo, puede usar una instrucción
UPDATE
para asignar el valorFalse
a una columna nueva cuando el valor actual esNULL
.
DML particionado no es adecuado para el procesamiento de transacciones a pequeña escala. Si quieres ejecutar una instrucción en algunas filas, usa DMLs transaccionales con claves primarias identificables. Para obtener más información, consulta Usar DML.
Si necesitas confirmar un gran número de escrituras ciegas, pero no necesitas una transacción atómica, puedes modificar en bloque tus tablas de Spanner mediante la escritura por lotes. Para obtener más información, consulta Modificar datos mediante escrituras por lotes.
Puedes obtener información valiosa sobre las consultas DML con particiones activas y su progreso a partir de las tablas de estadísticas de tu base de datos de Spanner. Para obtener más información, consulta Estadísticas de DMLs con particiones activas.
DML y DML particionado
Spanner admite dos modos de ejecución para las instrucciones DML:
DML, que es adecuada para el procesamiento de transacciones. Para obtener más información, consulta Usar DML.
DML particionado, que permite realizar operaciones a gran escala en toda la base de datos con un impacto mínimo en el procesamiento de transacciones simultáneas. Para ello, se particiona el espacio de claves y se ejecuta la instrucción en particiones en transacciones independientes de menor alcance. Para obtener más información, consulta Usar DML con particiones.
En la siguiente tabla se destacan algunas de las diferencias entre los dos modos de ejecución.
DML | DML particionado |
---|---|
Las filas que no coincidan con la cláusula WHERE podrían estar bloqueadas. |
Solo se bloquean las filas que coinciden con la cláusula WHERE . |
Se aplican límites de tamaño de las transacciones. | Spanner gestiona los límites de transacciones y los límites de simultaneidad por transacción. |
No es necesario que las instrucciones sean idempotentes. | Una instrucción DML debe ser idempotente para garantizar que los resultados sean coherentes. |
Una transacción puede incluir varias instrucciones DML y SQL. | Una transacción particionada solo puede incluir una instrucción DML. |
No hay restricciones en la complejidad de las instrucciones. | Las instrucciones deben ser totalmente particionables. |
Creas transacciones de lectura y escritura en tu código de cliente. | Spanner crea las transacciones. |
Particionable e idempotente
Cuando se ejecuta una instrucción DML particionada, las filas de una partición no tienen acceso a las filas de otras particiones y no puedes elegir cómo crea Spanner las particiones. El particionado asegura la escalabilidad, pero también significa que las instrucciones de DML particionadas deben ser totalmente particionables. Es decir, la instrucción DML particionada debe poder expresarse como la unión de un conjunto de instrucciones, donde cada instrucción accede a una sola fila de la tabla y ninguna instrucción accede a otras tablas. Por ejemplo, no se pueden particionar las instrucciones de DML que acceden a varias tablas o que realizan una combinación automática. Si la instrucción DML no se puede particionar, Spanner devuelve el error BadUsage
.
Estas declaraciones de DML se pueden particionar por completo, ya que cada declaración se puede aplicar a una sola fila de la tabla:
UPDATE Singers SET LastName = NULL WHERE LastName = '';
DELETE FROM Albums WHERE MarketingBudget > 10000;
Esta instrucción DML no se puede particionar por completo porque accede a varias tablas:
# Not fully partitionable
DELETE FROM Singers WHERE
SingerId NOT IN (SELECT SingerId FROM Concerts);
Spanner puede ejecutar una instrucción de DML particionada varias veces en algunas particiones debido a los reintentos a nivel de red. Por lo tanto, es posible que una instrucción se ejecute más de una vez en una fila. Por lo tanto, la instrucción debe ser idempotente para obtener resultados coherentes. Una instrucción es idempotente si, al ejecutarla varias veces en una sola fila, se obtiene el mismo resultado.
Esta declaración de DML es idempotente:
UPDATE Singers SET MarketingBudget = 1000 WHERE true;
Esta declaración de DML no es idempotente:
UPDATE Singers SET MarketingBudget = 1.5 * MarketingBudget WHERE true;
Bloqueo de filas
Spanner adquiere un bloqueo solo si una fila es candidata para actualizarse o eliminarse. Este comportamiento es diferente al de la ejecución de DML, que puede bloquear con lectura las filas que no coinciden con la cláusula WHERE
.
Ejecución y transacciones
Si una instrucción DML está particionada o no, depende del método de la biblioteca de cliente que elijas para ejecutarla. Cada biblioteca de cliente proporciona métodos independientes para la ejecución de DML y la ejecución de DML con particiones.
Solo puedes ejecutar una instrucción DML particionada en una llamada al método de la biblioteca del cliente.
Spanner no aplica las instrucciones DML con particiones de forma atómica en toda la tabla. Sin embargo, Spanner aplica las instrucciones DML particionadas de forma atómica en cada partición.
Las DML particionadas no admiten confirmaciones ni restauraciones. Spanner ejecuta y aplica la instrucción DML inmediatamente.
- Si cancelas la operación, Spanner cancela las particiones en ejecución y no inicia las particiones restantes. Spanner no revierte ninguna partición que ya se haya ejecutado.
- Si la ejecución de la instrucción provoca un error, la ejecución se detiene en todas las particiones y Spanner devuelve ese error en toda la operación. Algunos ejemplos de errores son las infracciones de las restricciones de tipo de datos, las infracciones de
UNIQUE INDEX
y las infracciones deON DELETE NO ACTION
. En función del momento en el que se haya producido el error de ejecución, es posible que la instrucción se haya ejecutado correctamente en algunas particiones y que nunca se haya ejecutado en otras.
Si la instrucción DML particionada se ejecuta correctamente, Spanner habrá ejecutado la instrucción al menos una vez en cada partición del intervalo de claves.
Recuento de filas modificadas
Una instrucción DML con particiones devuelve un límite inferior del número de filas modificadas. Puede que no sea un recuento exacto del número de filas modificadas, ya que no hay ninguna garantía de que Spanner cuente todas las filas modificadas.
Límites de las transacciones
Spanner crea las particiones y las transacciones que necesita para ejecutar una instrucción DML particionada. Se aplican límites de transacciones o límites de simultaneidad por transacción, pero Spanner intenta mantener las transacciones dentro de los límites.
Spanner permite un máximo de 20.000 instrucciones de DML particionado simultáneas por base de datos.
Funciones no compatibles
Spanner no admite algunas funciones de DML particionado:
- No se admite
INSERT
. - Google Cloud Consola: no puedes ejecutar instrucciones de DML particionado en la Google Cloud consola.
- Planes de consulta y creación de perfiles: la CLI de Google Cloud y las bibliotecas de cliente no admiten planes de consulta ni creación de perfiles.
- Subconsultas que leen datos de otra tabla o de una fila diferente de la misma tabla.
En casos complejos, como mover una tabla o realizar transformaciones que requieran combinaciones entre tablas, te recomendamos que uses el conector de Dataflow.
Ejemplos
En el siguiente ejemplo de código se actualiza la columna MarketingBudget
de la tabla Albums
.
C++
Usa la función ExecutePartitionedDml()
para ejecutar una instrucción DML con particiones.
C#
Usa el método ExecutePartitionedUpdateAsync()
para ejecutar una instrucción DML particionada.
Go
Usa el método PartitionedUpdate()
para ejecutar una instrucción DML particionada.
Java
Usa el método executePartitionedUpdate()
para ejecutar una instrucción DML particionada.
Node.js
Usa el método runPartitionedUpdate()
para ejecutar una instrucción DML particionada.
PHP
Usa el método executePartitionedUpdate()
para ejecutar una instrucción DML particionada.
Python
Usa el método execute_partitioned_dml()
para ejecutar una instrucción DML particionada.
Ruby
Usa el método execute_partitioned_update()
para ejecutar una instrucción DML particionada.
En el siguiente ejemplo de código se eliminan filas de la tabla Singers
en función de la columna SingerId
.
C++
C#
Go
Java
Node.js
PHP
Python
Ruby
Siguientes pasos
Consulta cómo modificar datos mediante DML.
Consulta las prácticas recomendadas del lenguaje de manipulación de datos (DML).
Para obtener información sobre las diferencias entre DML y mutaciones, consulta Comparar DMLs y mutaciones.
En otros casos de transformación de datos, utilice el conector de Dataflow.