Auf dieser Seite wird beschrieben, wie Sie Cloud Spanner-Daten mithilfe von DML-Anweisungen (Data Manipulation Language, Datenbearbeitungssprache) einfügen, aktualisieren und löschen. Sie können DML-Anweisungen mit den Clientbibliotheken, der Google Cloud Console und der Google Cloud CLI ausführen. Sie können partitionierte DML-Anweisungen mit den Clientbibliotheken und der gcloud CLI ausführen.
Eine vollständige Referenz zur DML-Syntax finden Sie unter Syntax der Datenbearbeitungssprache für Datenbanken im GoogleSQL-Dialekt oder unter Datenbearbeitungssprache für PostgreSQL für Datenbanken im PostgreSQL-Dialekt.
DML verwenden
DML unterstützt INSERT-, UPDATE- und DELETE-Anweisungen in derGoogle Cloud Console, der gcloud CLI und den Clientbibliotheken.
Sperren
Sie führen DML-Anweisungen in Lese- und Schreibtransaktionen aus. Wenn Spanner Daten liest, werden freigegebene Lesesperren für begrenzte Teile der Zeilenbereiche erworben, die Sie lesen. Insbesondere werden diese Sperren nur für die Spalten übernommen, auf die Sie zugreifen. Die Sperren können Daten enthalten, die die Filterbedingung der WHERE-Klausel nicht erfüllen.
Wenn Spanner Daten mithilfe von DML-Anweisungen ändert, werden exklusive Sperren für die spezifischen Daten erworben, die Sie ändern. Darüber hinaus werden gemeinsame Sperren auf die gleiche Weise wie beim Lesen von Daten angewendet. Wenn Ihre Anfrage große Zeilenbereiche oder eine ganze Tabelle umfasst, können die freigegebenen Sperren verhindern, dass andere Transaktionen parallel ausgeführt werden.
Wenn Sie Daten so effizient wie möglich ändern möchten, verwenden Sie eine WHERE-Klausel, mit der Spanner nur die erforderlichen Zeilen lesen kann. Sie können dafür einen Filter für den Primärschlüssel oder für den Schlüssel eines Sekundärindex nutzen. Die WHERE-Klausel schränkt den Umfang der freigegebenen Sperren ein und ermöglicht es Spanner, die Aktualisierung effizienter zu verarbeiten.
Angenommen, einer der Musiker in der Tabelle Singers ändert seinen Vornamen und Sie müssen den Namen in Ihrer Datenbank aktualisieren. Sie könnten die folgende DML-Anweisung ausführen, aber dadurch wird Spanner gezwungen, die gesamte Tabelle zu scannen, und es werden freigegebene Sperren erworben, die die gesamte Tabelle abdecken. Daher muss Spanner mehr Daten als nötig lesen und gleichzeitige Transaktionen können die Daten nicht parallel ändern:
-- ANTI-PATTERN: SENDING AN UPDATE WITHOUT THE PRIMARY KEY COLUMN
-- IN THE WHERE CLAUSE
UPDATE Singers SET FirstName = "Marcel"
WHERE FirstName = "Marc" AND LastName = "Richards";
Für eine effizientere Aktualisierung nehmen Sie die Spalte SingerId in die WHERE-Klausel auf. Die Spalte SingerId ist die einzige Primärschlüsselspalte für die Tabelle Singers:
-- ANTI-PATTERN: SENDING AN UPDATE THAT MUST SCAN THE ENTIRE TABLE
UPDATE Singers SET FirstName = "Marcel"
WHERE FirstName = "Marc" AND LastName = "Richards"
Wenn kein Index für FirstName oder LastName vorhanden ist, müssen Sie die gesamte Tabelle scannen, um die Zielsänger zu finden. Wenn Sie keinen sekundären Index hinzufügen möchten, um die Aktualisierung effizienter zu gestalten, fügen Sie die Spalte SingerId in die WHERE-Klausel ein.
Die Spalte SingerId ist die einzige Primärschlüsselspalte für die Tabelle Singers. Führen Sie dazu vor der Aktualisierungstransaktion SELECT in einer separaten, schreibgeschützten Transaktion aus:
SELECT SingerId
FROM Singers
WHERE FirstName = "Marc" AND LastName = "Richards"
-- Recommended: Including a seekable filter in the where clause
UPDATE Singers SET FirstName = "Marcel"
WHERE SingerId = 1;
Gleichzeitigkeit
Spanner führt alle SQL-Anweisungen (SELECT, INSERT, UPDATE und DELETE) innerhalb einer Transaktion nacheinander aus. Sie werden nicht gleichzeitig ausgeführt. Die einzige Ausnahme ist, dass Spanner möglicherweise mehrere SELECT-Anweisungen gleichzeitig ausführt, da es sich um Lesezugriff-Vorgänge handelt.
Transaktionslimits
Für eine Transaktion, die DML-Anweisungen enthält, gelten dieselben Limits wie für jede andere Transaktion. Bei umfangreichen Änderungen kann es sinnvoll sein, die partitionierte DML zu verwenden.
Das Mutationslimit wird unterschiedlich angewendet, je nachdem, ob Sie DML-Anweisungen oder die Mutation API verwenden:
DML-Anweisungen: Das Limit von 80.000 Mutationen (einschließlich Indexen) gilt pro Anweisung und wird am Ende jeder Anweisung zurückgesetzt. Wenn eine einzelne DML-Anweisung dieses Limit überschreitet, schlägt sie fehl und gibt den Fehler
BadUsagezurück. Eine Transaktion kann jedoch mehr als 80.000 Mutationen enthalten, wenn sie mehrere DML-Anweisungen enthält, solange jede einzelne Anweisung unter diesem Limit bleibt.Mutation API: Mutationen mit der Mutation API können im Gegensatz zu DML nur im Rahmen des Commit-Vorgangs angewendet werden, nicht mitten in einer Transaktion. Das Limit von 80.000 Mutationen (einschließlich Indexe) bezieht sich auf die Gesamtzahl der Mutationen im Commit. Wenn in einer Transaktion Mutationen verwendet werden (entweder allein oder zusammen mit DML), gilt dieses kumulative Limit für alle Mutationen im Commit.
Transaktionsgröße: Für alle Transaktionen gilt eine Größenbeschränkung von 100 MiB. Wenn die Anweisungen in einer Transaktion bei DML zu einer Transaktion mit mehr als 100 MiB führen, schlägt die Anweisung, die das Limit überschreitet, mit dem Fehler
BadUsagefehl. Mit DML ausgeführte Mutationen werden nicht auf das Limit von 80.000 Anweisungen angerechnet,aber auf das Limit für die Transaktionsgröße, wenn sie festgeschrieben werden.
Anweisungen in der Google Cloud Console ausführen
Führen Sie die folgenden Schritte aus, um eine DML-Anweisung in derGoogle Cloud Console auszuführen.
Rufen Sie die Spanner-Seite Instanzen auf.
Wählen Sie Ihr Projekt aus der Drop-down-Liste in der Symbolleiste aus.
Klicken Sie auf den Namen der Instanz, die Ihre Datenbank enthält, um die Seite Instanzdetails aufzurufen.
Klicken Sie auf dem Tab Übersicht auf den Namen Ihrer Datenbank. Die Seite mit den Datenbankdetails wird angezeigt.
Klicken Sie auf Spanner Studio.
Geben Sie eine DML-Anweisung ein. Durch die im Folgenden aufgeführte Anweisung wird beispielsweise eine neue Zeile in die Tabelle
Singersgeschrieben.INSERT Singers (SingerId, FirstName, LastName) VALUES (1, 'Marc', 'Richards')Klicken Sie auf Abfrage ausführen. In der Google Cloud Konsole wird das Ergebnis angezeigt.
Anweisungen mit der gcloud CLI ausführen
Zum Ausführen von DML-Anweisungen können Sie den Befehl gcloud spanner databases execute-sql verwenden. Im folgenden Beispiel wird eine neue Zeile zur Tabelle Singers hinzugefügt.
gcloud spanner databases execute-sql example-db --instance=test-instance \ --sql="INSERT Singers (SingerId, FirstName, LastName) VALUES (1, 'Marc', 'Richards')"
Daten mit der Clientbibliothek ändern
Wenn Sie DML-Anweisungen mithilfe der Clientbibliothek ausführen möchten, gehen Sie so vor:
- Erstellen Sie eine Lese-Schreib-Transaktion.
- Rufen Sie die Methode der Clientbibliothek auf, mit der DML ausgeführt wird, und übergeben Sie dabei die DML-Anweisung.
- Verwenden Sie den Rückgabewert der DML-Ausführungsmethode, um die Anzahl der eingefügten, aktualisierten oder gelöschten Zeilen abzurufen.
Im folgenden Codebeispiel wird eine neue Zeile in die Tabelle Singers eingefügt.
C++
Für das Ausführen einer DML-Anweisung verwenden Sie die Funktion ExecuteDml().
C#
Für das Ausführen einer DML-Anweisung verwenden Sie die Methode ExecuteNonQueryAsync().
Go
Für das Ausführen einer DML-Anweisung verwenden Sie die Methode Update().
Java
Für das Ausführen einer DML-Anweisung verwenden Sie die Methode executeUpdate().
Node.js
Für das Ausführen einer DML-Anweisung verwenden Sie die Methode runUpdate().
PHP
Für das Ausführen einer DML-Anweisung verwenden Sie die Methode executeUpdate().
Python
Für das Ausführen einer DML-Anweisung verwenden Sie die Methode execute_update().
Ruby
Für das Ausführen einer DML-Anweisung verwenden Sie die Methode execute_update().
Mit dem im Folgenden aufgeführten Codebeispiel wird die Spalte MarketingBudget der Tabelle Albums anhand einer WHERE-Klausel aktualisiert.
C++
C#
Go
Java
Node.js
PHP
Python
Ruby
Im folgenden Codebeispiel werden alle Zeilen in der Tabelle Singers gelöscht, wobei für die Spalte FirstName der Wert Alice gilt.
C++
C#
Go
Java
Node.js
PHP
Python
Ruby
Im folgenden Beispiel, das nur für Datenbanken mit GoogleSQL-Dialekt gilt, wird ein STRUCT mit gebundenen Parametern verwendet, um die LastName in Zeilen zu aktualisieren, die nach FirstName und LastName gefiltert wurden.
GoogleSQL
C++
C#
Go
Java
Node.js
PHP
Python
Ruby
Daten mit den zurückgegebenen DML-Anweisungen ändern
Die THEN RETURN-Klausel (GoogleSQL-Dialekt-Datenbanken) oder die RETURNING-Klausel (PostgreSQL-Dialekt-Datenbanken) ist für Szenarien gedacht, in denen Sie Daten aus geänderten Zeilen abrufen möchten. Dies ist besonders nützlich, wenn Sie nicht angegebene Werte in den DML-Anweisungen, Standardwerten oder generierten Spalten sehen möchten.
So führen Sie DML-Anweisungen mit Rückgabe mithilfe der Clientbibliothek aus:
- Erstellen Sie eine Lese-Schreib-Transaktion.
- Rufen Sie die Clientbibliotheksmethode für die Abfrageausführung auf und übergeben Sie die zurückgegebene DML-Anweisung, um Ergebnisse zu erhalten.
Im folgenden Codebeispiel wird eine neue Zeile in die Tabelle Singers eingefügt und die generierte Spalte „FullName“ der eingefügten Datensätze zurückgegeben.
GoogleSQL
C++
C#
Go
Java
Node.js
PHP
Python
Ruby
PostgreSQL
C++
C#
Go
Java
Node.js
PHP
Python
Ruby
Im folgenden Codebeispiel wird die Spalte MarketingBudget der Tabelle Albums basierend auf einer WHERE-Klausel aktualisiert. Außerdem wird die geänderte Spalte MarketingBudget der aktualisierten Datensätze zurückgegeben.
GoogleSQL
C++
C#
Go
Java
Node.js
PHP
Python
Ruby
PostgreSQL
C++
C#
Go
Java
Node.js
PHP
Python
Ruby
Im folgenden Codebeispiel werden alle Zeilen in der Tabelle Singers gelöscht, in denen die Spalte FirstName den Wert Alice hat. Außerdem werden die Spalten SingerId und FullName der gelöschten Datensätze zurückgegeben.
GoogleSQL
C++
C#
Go
Java
Node.js
PHP
Python
Ruby
PostgreSQL
C++
C#
Go
Java
Node.js
PHP
Python
Ruby
In derselben Transaktion geschriebene Daten lesen
Änderungen, die Sie innerhalb von DML-Anweisungen vornehmen, sind für nachfolgende Anweisungen in derselben Transaktion sichtbar. Dies unterscheidet sich von Mutationen, bei deren Verwendung Änderungen erst sichtbar werden, wenn der Commit der Transaktion durchgeführt wird.
Spanner prüft die 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 der Einschränkungen nach jeder Anweisung kann Cloud Spanner garantieren, dass die von einer DML-Anweisung zurückgegebenen Daten mit dem Schema konsistent sind.
Im folgenden Beispiel wird eine Zeile in der Tabelle Singers aktualisiert und dann eine SELECT-Anweisung zur Ausgabe der neuen Werte ausgeführt.
C++
C#
Go
Java
Node.js
PHP
Python
Ruby
Abfrageplan abrufen
Sie können einen Abfrageplan mit der Google Cloud Console, den Clientbibliotheken und der gcloud CLI abrufen.
Partitionierte DML verwenden
Die partitionierte DML wurde für Sammelaktualisierungen und -löschungen konzipiert, insbesondere für regelmäßiges Bereinigen und Backfilling.
Anweisungen mit der gcloud CLI ausführen
Zum Ausführen einer partitionierten DML-Anweisung verwenden Sie den Befehl gcloud spanner databases execute-sql mit der Option --enable-partitioned-dml. Im folgenden Beispiel werden Zeilen in der Tabelle Albums aktualisiert.
gcloud spanner databases execute-sql example-db \ --instance=test-instance --enable-partitioned-dml \ --sql='UPDATE Albums SET MarketingBudget = 0 WHERE MarketingBudget IS NULL'
Daten mit der Clientbibliothek ändern
Mit den folgenden Codebeispielen wird die Spalte MarketingBudget der Tabelle Albums aktualisiert.
C++
Zum Ausführen einer partitionierten DML-Anweisung verwenden Sie die Funktion ExecutePartitionedDml().
C#
Zum Ausführen einer partitionierten DML-Anweisung verwenden Sie die Methode ExecutePartitionedUpdateAsync().
Go
Zum Ausführen einer partitionierten DML-Anweisung verwenden Sie die Methode PartitionedUpdate().
Java
Zum Ausführen einer partitionierten DML-Anweisung verwenden Sie die Methode executePartitionedUpdate().
Node.js
Zum Ausführen einer partitionierten DML-Anweisung verwenden Sie die Methode runPartitionedUpdate().
PHP
Zum Ausführen einer partitionierten DML-Anweisung verwenden Sie die Methode executePartitionedUpdate().
Python
Zum Ausführen einer partitionierten DML-Anweisung verwenden Sie die Methode execute_partitioned_dml().
Ruby
Zum Ausführen einer partitionierten DML-Anweisung verwenden Sie die Methode execute_partitioned_update().
Im folgenden Codebeispiel werden Zeilen aus der Tabelle Singers anhand der Spalte SingerId gelöscht.
C++
C#
Go
Java
Node.js
PHP
Python
Ruby
Batch-DML verwenden
Zum Vermeiden der zusätzlichen Latenz, die durch mehrere serielle Anfragen entsteht, verwenden Sie Batch-DML. Sie können dann mehrere INSERT-, UPDATE- oder DELETE-Anweisungen in einer einzigen Transaktion senden:
C++
Verwenden Sie die Funktion ExecuteBatchDml(), um eine Liste von DML-Anweisungen auszuführen.
C#
Verwenden Sie die Methode connection.CreateBatchDmlCommand(), um Ihren Batch-Befehl zu erstellen, verwenden Sie die Methode Add, um DML-Anweisungen hinzuzufügen, und führen Sie die Anweisungen mit der Methode ExecuteNonQueryAsync() aus.
Go
Zum Ausführen eines Arrays von DML-Statement-Objekten verwenden Sie die Methode BatchUpdate().
Java
Zum Ausführen von ArrayList für mehrere DML-Statement-Objekte verwenden Sie die Methode transaction.batchUpdate().
Node.js
Zum Ausführen einer Liste von DML-Anweisungen verwenden Sie transaction.batchUpdate().
PHP
Verwenden Sie executeUpdateBatch(), um eine Liste von DML-Anweisungen zu erstellen, und dann commit(), um die Anweisungen auszuführen.
Python
Zum Ausführen von mehreren DML-Anweisungsstrings verwenden Sie transaction.batch_update().
Ruby
Zum Ausführen von mehreren DML-Anweisungsstrings verwenden Sie transaction.batch_update.