El lenguaje de manipulación de datos (DML) y las mutaciones son dos APIs de Spanner que puedes usar para modificar datos. Ambas ofrecen funciones similares de manipulación de datos. En esta página, se comparan ambos enfoques.
¿Qué es el lenguaje de manipulación de datos (DML)?
El lenguaje de manipulación de datos (DML) en Spanner te permite manipular datos en las tablas de tu base de datos con las instrucciones INSERT, UPDATE y DELETE. Puedes ejecutar declaraciones DML con las
bibliotecas cliente, la
Google Cloud consola, y gcloud spanner.
Spanner ofrece las siguientes dos implementaciones de ejecución de DML, cada una con diferentes propiedades.
DML estándar : Adecuado para cargas de trabajo estándar de procesamiento de transacciones en línea (OLTP).
Para obtener más información, incluidas muestras de código, consulta Usa DML
DML particionado : Diseñado para eliminaciones y actualizaciones en forma masiva, como en los siguientes ejemplos.
Recolección de elementos no utilizados y limpieza periódicos. Por ejemplo, la eliminación de filas antiguas o la configuración de columnas como NULL.
El restablecimiento de columnas nuevas con valores predeterminados. Un ejemplo es usar una instrucción UPDATE para establecer el valor de una columna nueva en False cuando es NULL.
Para obtener más información, incluidas muestras de código, consulta Usa DML particionado.
Puedes usar escrituras por lotes para una gran cantidad de operaciones de escritura sin operaciones de lectura que no requieran transacciones atómicas. Para obtener más información, consulta Modifica datos con escrituras por lotes.
¿Qué son las mutaciones?
Una mutación representa una secuencia de inserciones, actualizaciones y eliminaciones que Spanner aplica atómicamente a diferentes filas y tablas de una base de datos. Puedes incluir operaciones que se apliquen a diferentes filas o tablas en una mutación. Después de definir una o más mutaciones que contengan una o más escrituras, debes aplicar la mutación para confirmar las escrituras. Cada cambio se aplica en el orden en que se agregaron a la mutación.
Para obtener más información, incluidas muestras de código, consulta Inserta, actualiza y borra datos mediante mutaciones.
Comparación de funciones entre DML y mutaciones
En la siguiente tabla, se resumen la compatibilidad con DML y mutaciones de las operaciones y funciones comunes de la base de datos.
| Operaciones | DML | Mutaciones |
|---|---|---|
| Inserta datos | Admitido | Admitido |
| Borrar datos | Admitido | Admitido |
| Actualizar datos | Admitido | Admitido |
| Insertar o ignorar datos | Admitido | No compatible |
| Leer tus escrituras (RYW) | Admitido | No compatible |
| Insertar o actualizar datos (Upsert) | Admitido | Admitido |
| Sintaxis de SQL | Admitido | No compatible |
| Verificación de restricciones | Después de cada instrucción | En el momento de la confirmación |
| Aplicación del límite de mutaciones (incluidos los índices) | Por instrucción (se restablece después de la ejecución) | Por confirmación (acumulación) |
DML y las mutaciones difieren en su compatibilidad con las siguientes funciones:
Leer tus escrituras: Leer resultados no confirmados dentro de una transacción activa. Los cambios que realices mediante las declaraciones DML serán visibles para las declaraciones posteriores de la misma transacción. No es lo mismo que usar mutaciones, cuyos cambios no son visibles en ninguna lectura (incluidas las lecturas realizadas en la misma transacción) hasta que la transacción se confirma. Esto se debe a que las mutaciones de una transacción se almacenan en búfer del lado del cliente (de forma local) y se envían al servidor como parte de la operación de confirmación. Como resultado, las mutaciones de la solicitud de confirmación no son visibles para las instrucciones de SQL o declaraciones de DML dentro de la misma transacción.
Verificación de restricciones: Spanner verifica las restricciones después de que se realice cada declaración DML. No es lo mismo que usar mutaciones, para las que Spanner almacena las mutaciones en el cliente hasta la confirmación y verifica las restricciones en el momento de la confirmación. La evaluación de las restricciones después de realizar cada declaración DML permite que Spanner garantice que los datos que muestra una consulta posterior en la misma transacción sean coherentes con el esquema.
Aplicación del límite de mutaciones: Para DML, el límite de mutaciones de 80,000 (incluidos los índices) se aplica por instrucción y se restablece después de que se ejecuta la instrucción. Esto permite que una sola transacción ejecute varias declaraciones DML que, en conjunto, superen las 80,000 mutaciones, siempre que ninguna instrucción supere el límite. Para la API de Mutation, que solo se puede usar como parte de la operación de confirmación, el límite de 80,000 mutaciones (incluidos los índices) es acumulativo en todas las mutaciones de la confirmación. Ambos métodos están sujetos al límite de tamaño de transacción de 100 MiB.
Sintaxis de SQL: DML proporciona una forma convencional de manipular datos. Puedes reutilizar las habilidades de SQL para modificar los datos con la API de DML.
Práctica recomendada: Evita combinar DML y mutaciones en la misma transacción
Si una transacción contiene mutaciones y declaraciones DML en la solicitud de confirmación, Spanner ejecuta las declaraciones DML antes de las mutaciones. Para evitar tener que dar cuenta del orden de ejecución en el código de tu biblioteca cliente, debes usar las declaraciones DML o las mutaciones en una sola transacción, pero no en ambas.
En el siguiente ejemplo de Java, se ilustra un comportamiento potencialmente sorprendente. El código inserta dos filas en Albums con la API de Mutation. Luego, el fragmento llama a executeUpdate() para actualizar las filas recién insertadas y llama a executeQuery() para leer los álbumes actualizados.
static void updateMarketingBudget(DatabaseClient dbClient) {
dbClient
.readWriteTransaction()
.run(
new TransactionCallable<Void>() {
@Override
public Void run(TransactionContext transaction) throws Exception {
transaction.buffer(
Mutation.newInsertBuilder("Albums")
.set("SingerId")
.to(1)
.set("AlbumId")
.to(1)
.set("AlbumTitle")
.to("Total Junk")
.set("MarketingBudget")
.to(800)
.build());
transaction.buffer(
Mutation.newInsertBuilder("Albums")
.set("SingerId")
.to(1)
.set("AlbumId")
.to(2)
.set("AlbumTitle")
.to("Go Go Go")
.set("MarketingBudget")
.to(200)
.build());
// This UPDATE will not include the Albums inserted above.
String sql =
"UPDATE Albums SET MarketingBudget = MarketingBudget * 2"
+ " WHERE SingerId = 1";
long rowCount = transaction.executeUpdate(Statement.of(sql));
System.out.printf("%d records updated.\n", rowCount);
// Read a newly updated record.
sql =
"SELECT SingerId, AlbumId, AlbumTitle FROM Albums"
+ " WHERE SingerId = 1 AND MarketingBudget < 1000";
ResultSet resultSet =
transaction.executeQuery(Statement.of(sql));
while (resultSet.next()) {
System.out.printf(
"%s %s\n",
resultSet.getString("FirstName"),
resultSet.getString("LastName"));
}
return null;
}
});
}
Si ejecutaras este código, verías 0 registros actualizados. ¿Por qué? Esto sucede porque los cambios que realizamos con Mutaciones no son visibles para las declaraciones posteriores hasta que se confirma la transacción. Lo ideal es que solo almacenemos las escrituras en búfer al final de la transacción.
Próximos pasos
Obtén información para modificar datos con DML.
Obtén información para modificar datos con mutaciones.
Para encontrar el recuento de mutaciones de una transacción, consulta Recuperación de las estadísticas de confirmaciones de una transacción.
Obtén información sobre las prácticas recomendadas para el lenguaje de manipulación de datos (DML).