Data Manipulation Language (DML) und Mutationen sind zwei APIs in Spanner, mit denen Sie Daten ändern können. Sie bieten ähnliche Features zur Datenbearbeitung. Auf dieser Seite werden die Ansätze verglichen.
Was ist die Datenbearbeitungssprache (Data Manipulation Language, DML)?
Mit der Datenbearbeitungssprache (Data Manipulation Language, DML) in Spanner können Sie Daten in Ihren Datenbanktabellen mithilfe von INSERT-, UPDATE- und DELETE-Anweisungen bearbeiten. Sie können DML-Anweisungen mit den Clientbibliotheken, der Google Cloud Console und gcloud spanner ausführen.
Spanner bietet die folgenden zwei Implementierungen der DML-Ausführung mit jeweils unterschiedlichen Eigenschaften.
Standard-DML: Geeignet für standardmäßige OLTP-Arbeitslasten (Online Transaction Processing).
Weitere Informationen und Codebeispiele finden sich unter DML verwenden.
Partitionierte DML: Wurde für Bulk-Aktualisierungen und -Löschvorgänge konzipiert, wie in folgenden Beispielen beschrieben.
Regelmäßige und automatische Speicherbereinigungsvorgänge. Beispiele: Alte Zeilen löschen oder Spalten auf NULL setzen.
Backfilling neuer Spalten mit Standardwerten. Beispiel: Mit einer UPDATE-Anweisung wird der Wert einer neuen Spalte auf „False“ gesetzt, wenn er NULL ist.
Weitere Informationen und Codebeispiele finden sich unter Partitionierte DML verwenden.
Sie können Batch-Schreibvorgänge für eine große Anzahl von Schreibvorgängen ohne Lesevorgänge verwenden, die keine atomaren Transaktionen erfordern. Weitere Informationen finden Sie unter Daten mit Batch-Schreibvorgängen ändern.
Was sind Mutationen?
Eine Mutation stellt eine Sequenz von Einfügungen, Aktualisierungen und Löschungen dar, die Spanner atomar auf verschiedene Zeilen und Tabellen in einer Datenbank anwendet. Sie können Vorgänge aufnehmen, die auf verschiedene Zeilen oder Tabellen in einer Mutation angewendet werden. Nachdem Sie eine oder mehrere Mutationen definiert haben, die je einen oder mehrere Schreibvorgänge enthalten, müssen Sie die Mutation anwenden, um einen Commit für die Schreibvorgänge auszuführen. Änderungen werden in der Reihenfolge angewendet, in der sie der Mutation hinzugefügt wurden.
Weitere Informationen und Codebeispiele finden Sie unter Daten mit Mutationen einfügen, aktualisieren und löschen.
Featurevergleich zwischen DML und Mutationen
In folgender Tabelle sind DML- und Mutationsunterstützung für häufige Datenbankoperationen und -funktionen zusammengefasst.
| Vorgänge | DML | Mutationen |
|---|---|---|
| Daten einfügen | Unterstützt | Unterstützt |
| Daten löschen | Unterstützt | Unterstützt |
| Daten aktualisieren | Unterstützt | Unterstützt |
| Daten einfügen oder ignorieren | Unterstützt | Nicht unterstützt |
| Schreibvorgänge lesen (RYW, Read Your Writes) | Unterstützt | Nicht unterstützt |
| Daten einfügen oder aktualisieren (Upsert) | Unterstützt | Unterstützt |
| SQL-Syntax | Unterstützt | Nicht unterstützt |
| Einschränkung prüfen | Nach jeder Anweisung | Beim Commit |
| Erzwingung des Mutationslimits (einschließlich Indexe) | Pro Anweisung (wird nach der Ausführung zurückgesetzt) | Pro Commit (kumulativ) |
DML und Mutationen unterscheiden sich in ihrer Unterstützung für die folgenden Funktionen:
Read Your Writes: Lesen von nicht festgeschriebenen Ergebnissen innerhalb einer aktiven Transaktion. Änderungen, die Sie mit DML-Anweisungen vornehmen, sind für nachfolgende Anweisungen in derselben Transaktion sichtbar. Dies unterscheidet sich von Mutationen, bei denen Änderungen in Lesevorgängen (einschließlich Lesevorgängen in derselben Transaktion) erst beim Commit der Transaktion sichtbar werden. Grund dafür ist, dass Mutationen in einer Transaktion clientseitig (lokal) gepuffert und als Teil des Commit-Vorgangs an den Server gesendet werden. Folglich sind Mutationen in der Commit-Anfrage für SQL- oder DML-Anweisungen in derselben Transaktion nicht sichtbar.
Einschränkungsprüfung: Cloud Spanner prüft Einschränkungen nach jeder DML-Anweisung. Dies unterscheidet sich von der Verwendung von Mutationen, bei denen Spanner Mutationen im Client bis zum Commit zwischenspeichert und Einschränkungen zum Zeitpunkt des Commits prüft. Durch die Auswertung von Einschränkungen nach jeder DML-Anweisung kann Spanner garantieren, dass die von einer nachfolgenden Abfrage in derselben Transaktion zurückgegebenen Daten mit dem Schema konsistent sind.
Erzwingung des Mutationslimits: Bei DML wird das Mutationslimit von 80.000 (einschließlich Indexen) pro Anweisung angewendet und nach der Ausführung der Anweisung zurückgesetzt. So können in einer einzelnen Transaktion mehrere DML-Anweisungen ausgeführt werden,die zusammen mehr als 80.000 Mutationen umfassen, solange keine einzelne Anweisung das Limit überschreitet. Bei der Mutation API, die nur als Teil des Commit-Vorgangs verwendet werden kann, gilt das Limit von 80.000 Mutationen (einschließlich Indexen) kumulativ für alle Mutationen im Commit. Für beide Methoden gilt die Größenbeschränkung von 100 MiB für Transaktionen.
SQL-Syntax: DML bietet eine herkömmliche Möglichkeit, Daten zu bearbeiten. Sie können SQL-Kompetenzen nutzen, um die Daten mit der DML API zu ändern.
Best Practice: Kombinieren Sie DML und Mutationen nicht in derselben Transaktion
Wenn eine Transaktion sowohl DML-Anweisungen als auch Mutationen in der Commit-Anfrage enthält, führt Spanner die DML-Anweisungen vor den Mutationen aus. Damit Sie die Ausführungsreihenfolge in Ihrem Clientbibliothekscode nicht berücksichtigen müssen, sollten Sie entweder DML-Anweisungen oder die Mutationen in einer einzelnen Transaktion verwenden, aber nicht beides.
Folgendes Java-Beispiel veranschaulicht ein potenziell überraschendes Verhalten. Der Code fügt per Mutation API zwei Zeilen in Alben ein. Das Snippet ruft dann executeUpdate() auf, um die neu eingefügten Zeilen zu aktualisieren und executeQuery() aufzurufen, um die aktualisierten Alben zu lesen.
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;
}
});
}
Bei der Ausführung dieses Codes würde 0 Datensätze aktualisiert angezeigt. Warum? Grund ist, dass die mit Mutationen vorgenommenen Änderungen für nachfolgende Anweisungen erst nach dem Commit der Transaktion sichtbar sind. Idealerweise sollten am Ende der Transaktion nur noch gepufferte Schreibvorgänge existieren.
Nächste Schritte
Erfahren Sie, wie Sie Daten mit DML ändern.
Erfahren Sie, wie Sie Daten mithilfe von Mutationen ändern
Informationen zum Ermitteln der Anzahl der Mutationen für eine Transaktion finden Sie unter Commit-Statistiken für eine Transaktion abrufen.
Informationen zu den Best Practices für die Datenbearbeitungssprache (DML).