Auf dieser Seite wird beschrieben, wie Sie Spanner-Daten mithilfe von Anweisungen in der Datenbearbeitungssprache (Data Manipulation Language, DML) einfügen, aktualisieren und löschen. Sie können DML-Anweisungen mit den Clientbibliotheken, der Google Cloud Console und dem gcloud
-Befehlszeilentool ausführen. Partitionierte DML-Anweisungen lassen sich mit den Clientbibliotheken und mit dem gcloud
-Befehlszeilentool ausführen.
Die vollständige DML-Syntaxreferenz finden Sie unter Datenbearbeitungssprache (Data Manipulation Language-Syntax) für GoogleSQL-Dialektdatenbanken oder PostgreSQL-Datenbearbeitungssprache für PostgreSQL-Dialekte-Datenbanken.
DML verwenden
DML unterstützt INSERT
-, UPDATE
- und DELETE
-Anweisungen in der Google Cloud Console, der Google Cloud CLI und Clientbibliotheken.
Sperren
Sie führen DML-Anweisungen in Lese- und Schreibtransaktionen aus. Wenn Spanner Daten liest, werden gemeinsame Lesesperren für begrenzte Teile der gelesenen Zeilenbereiche übernommen. 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 mit DML-Anweisungen ändert, werden exklusive Sperren für die Daten übernommen, 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 enthält, verhindern die gemeinsamen Sperren möglicherweise, dass andere Transaktionen parallel weiterarbeiten.
Um Daten so effizient wie möglich zu ändern, verwenden Sie die WHERE
-Klausel, die es Spanner ermöglicht, nur die erforderlichen Zeilen zu lesen. 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 gemeinsamen Sperren ein und ermöglicht 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önnen die folgende DML-Anweisung ausführen. Spanner wird jedoch gezwungen, die gesamte Tabelle zu scannen und gemeinsame Sperren abzurufen, 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äre Schlü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 für FirstName
oder LastName
kein Index vorhanden ist, müssen Sie die gesamte Tabelle nach den Zielsingern durchsuchen. Wenn Sie keinen sekundären Index hinzufügen möchten, um die Aktualisierung effizienter zu machen, 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 SELECT
vor der Aktualisierungstransaktion in einer separaten, schreibgeschützten Transaktion aus, um sie zu ermitteln:
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;
Nebenläufigkeit
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 reine Lesevorgä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.
Wenn die DML-Anweisungen in einer Transaktion zu mehr als 80.000 Mutationen führen, gibt die DML-Anweisung, mit der die Transaktion das Limit überschreitet, einen
BadUsage
-Fehler mit einer Meldung über zu viele Mutationen zurück.Wenn die DML-Anweisungen in einer Transaktion dazu führen, dass ihre Größe 100 MB überschreitet, gibt die DML-Anweisung, die die Transaktion über das Limit hinaus ausführt, einen
BadUsage
-Fehler mit einer Nachricht über das Überschreiten des Limits durch die Transaktion zurück.
Mit DML ausgeführte Mutationen werden nicht an den Client zurückgegeben. Wenn die Commit-Anfrage ausgeführt wird, werden sie in diese Anfrage eingebunden, und sie unterliegen somit der Größenbegrenzung. Auch wenn die von Ihnen gesendete Commit-Anfrage nicht so groß ist, kann die Transaktion dadurch immer noch die Größenbegrenzung überschreiten.
Anweisungen in der Google Cloud Console ausführen
Führen Sie die folgenden Schritte aus, um eine DML-Anweisung in der Google 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
Singers
geschrieben.INSERT Singers (SingerId, FirstName, LastName) VALUES (1, 'Marc', 'Richards')
Klicken Sie auf Abfrage ausführen. In der Google Cloud Console wird das Ergebnis angezeigt.
Anweisungen mit der Google Cloud 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 mithilfe 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.
- Dem Rückgabewert der Methode für die DML-Ausführung können Sie die Anzahl der eingefügten, aktualisierten oder gelöschten Zeilen entnehmen.
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()
.
Einfach loslegen (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, nur für GoogleSQL-Dialekt-Datenbanken, wird eine STRUCT
mit gebundenen Parametern verwendet, um LastName
in Zeilen zu aktualisieren, die nach FirstName
und LastName
gefiltert sind.
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 vorgesehen, in denen Sie Daten aus geänderten Zeilen abrufen möchten. Dies ist besonders nützlich, wenn Sie nicht spezifizierte Werte in den DML-Anweisungen, Standardwerten oder generierten Spalten anzeigen möchten.
So führen Sie zurückgegebene DML-Anweisungen mithilfe der Clientbibliothek aus:
- Erstellen Sie eine Lese-Schreib-Transaktion.
- Rufen Sie die Clientbibliotheksmethode zur 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
anhand einer WHERE
-Klausel aktualisiert und 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, bei 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
Daten lesen, die in derselben Transaktion geschrieben wurden
Ä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 überprüft. Durch das Auswerten der Einschränkungen nach jeder Anweisung kann Spanner garantieren, dass die Daten, die von einer DML-Anweisung zurückgegeben werden, mit dem Schema übereinstimmen.
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 mit der Google Cloud Console, den Clientbibliotheken und dem gcloud
-Befehlszeilentool einen Abfrageplan 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 Google Cloud 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 mithilfe 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()
.
Einfach loslegen (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.
Einfach loslegen (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
.