A linguagem de manipulação de dados (DML, na sigla em inglês) e as mutações são duas APIs no Spanner que podem ser usadas para modificar dados. Cada uma oferece recursos semelhantes de manipulação de dados. Esta página compara as duas abordagens.
O que é a linguagem de manipulação de dados (DML)?
A linguagem de manipulação de dados (DML) no Spanner permite manipular dados nas tabelas do banco de dados usando instruções INSERT, UPDATE e DELETE. É possível executar instruções DML usando as
bibliotecas de cliente, o
Google Cloud console e o gcloud spanner.
O Spanner oferece as duas implementações de execução DML a seguir, cada uma com propriedades diferentes.
DML padrão : adequado para cargas de trabalho padrão de processamento de transações on-line (OLTP, na sigla em inglês).
Para mais informações, incluindo amostras de código, consulte Como usar a DML
DML particionada: projetada para atualizações e exclusões em massa, como nos exemplos a seguir.
Limpeza periódica e coleta de lixo. Alguns exemplos são excluir linhas antigas ou definir colunas como NULL.
Preenchimento de novas colunas com valores padrão. Um exemplo é o uso de uma instrução UPDATE para definir o valor de uma nova coluna como False, em que o valor atual é NULL.
Para mais informações, incluindo amostras de código, consulte Como usar a DML particionada.
É possível usar gravações em lote para um grande número de operações de gravação sem operações de leitura que não exigem transações atômicas. Para mais informações, consulte Modificar dados usando gravações em lote.
O que são mutações?
Uma mutação representa uma sequência de inserções, atualizações e exclusões que o Spanner aplica atomicamente a diferentes linhas e tabelas em um banco de dados. É possível incluir operações que se aplicam a linhas ou tabelas diferentes em uma mutação. Depois de definir uma ou mais mutações que contêm uma ou mais gravações, é necessário aplicar a mutação para confirmar as gravações. Cada alteração é aplicada na ordem em que foram adicionadas à mutação.
Para mais informações, incluindo amostras de código, consulte Como inserir, atualizar e excluir dados usando mutações.
Comparação de recursos entre DML e mutações
A tabela a seguir resume o suporte à DML e à mutação da operação e dos recursos comuns do banco de dados.
| Operações | DML | Mutações |
|---|---|---|
| Inserir dados | Compatível | Compatível |
| Excluir dados | Compatível | Compatível |
| Atualizar dados | Compatível | Compatível |
| Inserir ou ignorar dados | Compatível | Não compatível |
| Leia suas gravações (RYM, na sigla em inglês) | Compatível | Não compatível |
| Inserir ou atualizar dados (upsert) | Compatível | Compatível |
| Sintaxe SQL | Com suporte | Não compatível |
| Verificação de restrição | Após cada instrução | No momento do commit |
| Aplicação do limite de mutação (incluindo índices) | Por instrução (redefinida após a execução) | Por confirmação (cumulativa) |
DML e mutações divergem em compatibilidade com os recursos a seguir:
Leia suas gravações: leitura de resultados não confirmados em uma transação ativa. As alterações que você faz usando instruções DML são visíveis para declarações subsequentes na mesma transação. Isso é diferente de usar mutações, em que as alterações não são visíveis em nenhuma leitura (incluindo leituras feitas na mesma transação) até a confirmação da transação. Isso ocorre porque as mutações em uma transação são armazenadas no lado do cliente (localmente) e enviadas ao servidor como parte da operação de confirmação. Como resultado, as mutações na solicitação de confirmação não são visíveis para as instruções SQL ou DML na mesma transação.
Verificação de restrição: o Spanner verifica as restrições após cada instrução DML. Isso é diferente de usar mutações, em que o Spanner armazena mutações no cliente até confirmar e verificar as restrições no momento da confirmação. A avaliação de restrições após cada instrução DML permite que o Spanner garanta que os dados retornados por uma consulta subsequente na mesma transação retorne dados consistentes com o esquema.
Aplicação do limite de mutação: para DML, o limite de mutação de 80.000 (incluindo índices) é aplicado por instrução e redefinido após a execução da instrução. Isso permite que uma única transação execute várias instruções DML que excedam coletivamente 80.000 mutações, desde que nenhuma instrução exceda o limite. Para a API Mutation, que só pode ser usada como parte da operação de confirmação, o limite de 80.000 mutações (incluindo índices) é cumulativo em todas as mutações na confirmação. Os dois métodos estão sujeitos ao limite de tamanho de transação de 100 MiB.
Sintaxe SQL: DML fornece uma maneira convencional de manipular dados. É possível reutilizar as habilidades do SQL para alterar os dados com a API DML.
Prática recomendada: evite misturar DML e mutação na mesma transação
Se uma transação contiver instruções DML e mutações na solicitação de confirmação, o Spanner executará as instruções DML antes das mutações. Para não precisar incluir a ordem de execução no código da biblioteca de cliente, use instruções DML ou as mutações em uma única transação, mas não ambas.
O exemplo de Java a seguir ilustra um comportamento potencialmente surpreendente. O código
insere duas linhas nos álbuns usando a API de mutação. O snippet, em seguida, chama
executeUpdate() para atualizar as linhas recém-inseridas e chama executeQuery()
para ler os álbuns atualizados.
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;
}
});
}
Se você executar esse código, verá 0 registros atualizados. Por quê? Isso acontece porque as alterações feitas com "Mutações" não ficam visíveis para as instruções subsequentes até que a transação seja confirmada. O ideal é ter gravações armazenadas em buffer somente no final da transação.
A seguir
Saiba como modificar dados usando a DML.
Saiba como modificar dados usando mutações.
Para encontrar a contagem de mutações para uma transação, consulte Como recuperar estatísticas de confirmação para uma transação.
Saiba mais sobre as práticas recomendadas da linguagem de manipulação de dados (DML, na sigla em inglês).