Auf dieser Seite wird beschrieben, wie Sie für jeden Einfüge- und Aktualisierungsvorgang, den Sie mit Cloud Spanner in Datenbanken im PostgreSQL-Dialekt ausführen, einen Commit-Zeitstempel schreiben.
Commit-Zeitstempel einfügen
Der Commit-Zeitstempel basiert auf der TrueTime-Technologie und ist der Zeitpunkt, zu dem in der Datenbank ein Commit für eine Transaktion durchgeführt wird. Sie können den Commit-Zeitstempel einer Transaktion atomar in einer Spalte speichern. Mit den in Tabellen gespeicherten Commit-Zeitstempeln können Sie die genaue Reihenfolge von Mutationen bestimmen und Elemente wie Änderungslogs erstellen.
Führen Sie die folgenden Schritte aus, um Commit-Zeitstempel in eine Datenbank einzufügen:
Erstellen Sie eine Spalte vom Typ
SPANNER.COMMIT_TIMESTAMP. Beispiel:CREATE TABLE Performances ( ... LastUpdateTime SPANNER.COMMIT_TIMESTAMP NOT NULL, ... PRIMARY KEY (...) ) ;Wenn Sie Einfüge- oder Aktualisierungsvorgänge mit DML ausführen, schreiben Sie den Commit-Zeitstempel mithilfe der Funktion
SPANNER.PENDING_COMMIT_TIMESTAMP().Wenn Sie Einfüge- oder Aktualisierungsvorgänge mit vorbereiteten Anweisungen oder Mutationen ausführen, verwenden Sie den Platzhalterstring
SPANNER.COMMIT_TIMESTAMP()für die Commit-Zeitstempelspalte. Sie können auch die von der Clientbibliothek bereitgestellte Konstante für den Commit-Zeitstempel verwenden. Im Java-Client ist diese Konstante beispielsweiseValue.COMMIT_TIMESTAMP.
Wenn Cloud Spanner den Commit der Transaktion mit diesen Platzhaltern als Spaltenwerte durchführt, wird der tatsächliche Commit-Zeitstempel in die angegebene Spalte geschrieben. Sie können dann mit diesem Spaltenwert einen Verlauf der Tabellenaktualisierungen erstellen.
Die Werte der Commit-Zeitstempel sind nicht zwangsläufig eindeutig. Transaktionen, die in nicht überlappende Gruppen von Feldern schreiben, haben möglicherweise denselben Zeitstempel. Transaktionen, die in überlappende Gruppen von Feldern schreiben, haben eindeutige Zeitstempel.
Commit-Zeitstempel von Cloud Spanner haben eine Genauigkeit im Mikrosekundenbereich und werden beim Speichern in SPANNER.COMMIT_TIMESTAMP-Spalten in Nanosekunden umgewandelt.
Schlüssel und Indexe
Sie können eine Commit-Zeitstempelspalte als Primärschlüsselspalte oder als Nicht-Schlüsselspalte verwenden. Primärschlüssel können als ASC oder DESC definiert werden.
ASC(Standardeinstellung): Aufsteigende Schlüssel sind ideal für das Beantworten von Abfragen ab einem bestimmten Zeitpunkt.DESC: Bei absteigenden Schlüsseln bleiben die neuesten Zeilen oben in der Tabelle. Sie bieten schnellen Zugriff auf die neuesten Datensätze.
Heißlaufen vermeiden
Die Verwendung von Commit-Zeitstempeln in folgenden Szenarien führt zu einem Heißlaufen, was die Datenleistung beeinträchtigt:
Die Commit-Zeitstempelspalte ist der erste Teil des Primärschlüssels einer Tabelle.
CREATE TABLE Users ( LastAccess SPANNER.COMMIT_TIMESTAMP NOT NULL, UserId bigint NOT NULL, ... PRIMARY KEY (LastAccess, UserId) ) ;Die Primärschlüsselspalte des Commit-Zeitstempels ist der erste Teil eines sekundären Index.
CREATE INDEX UsersByLastAccess ON Users(LastAccess)oder
CREATE INDEX UsersByLastAccessAndName ON Users(LastAccess, FirstName)
Die Datenleistung wird durch ein Heißlaufen beeinträchtigt, selbst bei niedrigen Schreibraten. Wenn Commit-Zeitstempel für Nicht-Schlüsselspalten ohne Indexierung aktiviert sind, gibt es keine Leistungseinbußen.
Zeitstempelspalte in eine vorhandene Tabelle aufnehmen
Verwenden Sie die Anweisung ALTER TABLE, um einer vorhandenen Tabelle eine Commit-Zeitstempelspalte hinzuzufügen. Geben Sie beispielsweise die folgende Anweisung ein, um der Tabelle Performances die Spalte LastUpdateTime hinzuzufügen:
ALTER TABLE Performances ADD COLUMN LastUpdateTime SPANNER.COMMIT_TIMESTAMP;
Commit-Zeitstempel mit einer DML-Anweisung schreiben
Sie verwenden Sie Funktion SPANNER.PENDING_COMMIT_TIMESTAMP(), um den Commit-Zeitstempel in eine DML-Anweisung zu schreiben. Cloud Spanner wählt den Commit-Zeitstempel aus, wenn der Commit der Transaktion durchgeführt wird.
Mit der folgenden DML-Anweisung wird die Spalte LastUpdateTime der Tabelle Performances mit dem Commit-Zeitstempel aktualisiert.
UPDATE Performances SET LastUpdateTime = SPANNER.PENDING_COMMIT_TIMESTAMP()
WHERE SingerId=1 AND VenueId=2 AND EventDate="2015-10-21"
Zeile mithilfe einer Mutation einfügen
Beim Einfügen einer Zeile schreibt Cloud Spanner den Wert des Commit-Zeitstempels nur dann, wenn die Spalte in die Spaltenliste aufgenommen und der Platzhalterstring spanner.commit_timestamp() bzw. die Konstante der Clientbibliothek als deren Wert übergeben wird. Beispiel:
C++
C#
Go
Java
Node.js
PHP
Python
Ruby
Wenn Sie Mutationen in Zeilen in mehreren Tabellen haben, müssen Sie spanner.commit_timestamp() bzw. die Konstante der Clientbibliothek für die Commit-Zeitstempelspalte in jeder Tabelle angeben.
Zeile mithilfe einer Mutation aktualisieren
Beim Aktualisieren einer Zeile schreibt Cloud Spanner den Wert des Commit-Zeitstempels nur dann, wenn die Spalte in die Spaltenliste aufgenommen und der Platzhalterstring spanner.commit_timestamp() bzw. die Konstante der Clientbibliothek als deren Wert übergeben wird. Der Primärschlüssel einer Zeile kann nicht aktualisiert werden. Zum Aktualisieren des Primärschlüssels müssen Sie die vorhandene Zeile löschen und eine neue Zeile erstellen.
Die Commit-Zeitstempelspalte LastUpdateTime können Sie beispielsweise so aktualisieren:
C++
C#
Go
Java
Node.js
PHP
Python
Ruby
Wenn Sie Mutationen in Zeilen in mehreren Tabellen haben, müssen Sie spanner.commit_timestamp() bzw. die Konstante der Clientbibliothek für die Commit-Zeitstempelspalte in jeder Tabelle angeben.
Commit-Zeitstempelspalte abfragen
Im folgenden Beispiel wird die Commit-Zeitstempelspalte der Tabelle abgefragt.
C++
C#
Go
Java
Node.js
PHP
Python
Ruby
Eigenen Wert für die Commit-Zeitstempelspalte angeben
Sie können in Ihrem Code einen eigenen Wert für die Commit-Zeitstempelspalte angeben, anstatt spanner.commit_timestamp() bzw. die Konstante der Clientbibliothek als Spaltenwert zu übergeben. Der Wert muss ein Zeitstempel sein, der in der Vergangenheit liegt. Mit dieser Einschränkung wird sichergestellt, dass das Schreiben von Zeitstempeln ein kostengünstiger und schneller Vorgang ist. Wenn Sie bestätigen möchten, dass ein Wert in der Vergangenheit liegt, können Sie ihn auch mit dem Wert vergleichen, der von der SQL-Funktion CURRENT_TIMESTAMP zurückgegeben wird. Der Server gibt den Fehler FailedPrecondition zurück, wenn ein zukünftiger Zeitstempel angegeben ist.
Änderungslog erstellen
Angenommen, Sie möchten ein Änderungslog aller Mutationen erstellen, die an einer Tabelle vorgenommen werden, und dieses Änderungslog dann für Audits verwenden. Ein Beispiel wäre eine Tabelle, in der der Änderungsverlauf von Textverarbeitungsdokumenten gespeichert wird. Der Commit-Zeitstempel erleichtert das Erstellen des Änderungslogs, da die entsprechende Reihenfolge der Einträge im Änderungslog durch die Zeitstempel erzwungen werden kann. Sie könnten ein Änderungslog mit dem Änderungsverlauf eines bestimmten Dokuments erstellen, indem Sie ein Schema wie im folgenden Beispiel verwenden:
CREATE TABLE Documents (
UserId int8 NOT NULL,
DocumentId int8 NOT NULL,
Contents text NOT NULL,
PRIMARY KEY (UserId, DocumentId)
);
CREATE TABLE DocumentHistory (
UserId int8 NOT NULL,
DocumentId int8 NOT NULL,
Ts SPANNER.COMMIT_TIMESTAMP NOT NULL,
Delta text,
PRIMARY KEY (UserId, DocumentId, Ts)
) INTERLEAVE IN PARENT Documents;
Zum Erstellen eines Änderungslogs fügen Sie in derselben Transaktion, in der Sie eine Zeile in Document einfügen oder aktualisieren, eine neue Zeile in DocumentHistory ein. Verwenden Sie beim Einfügen der neuen Zeile in DocumentHistory den Platzhalter spanner.commit_timestamp() bzw. die Konstante der Clientbibliothek, damit Cloud Spanner den Commit-Zeitstempel in die Spalte Ts schreibt.
Das Verschachteln der Tabelle DocumentsHistory mit der Tabelle Documents sorgt für Datenlokalität und effizientere Einfüge- und Aktualisierungsvorgänge. Allerdings führt dies auch dazu, dass die über- und untergeordneten Zeilen zusammen gelöscht werden müssen. Damit die Zeilen in DocumentHistory nach dem Löschen von Zeilen in Documents erhalten bleiben, dürfen die Tabellen nicht verschachtelt werden.
Abfragen aktueller Daten mit Commit-Zeitstempeln optimieren
Commit-Zeitstempel optimieren Ihre Cloud Spanner-Datenbank und können die Abfrage-E/A beim Abrufen von Daten reduzieren, die nach einem bestimmten Zeitpunkt geschrieben wurden.
Für diese Optimierung muss die Anweisung WHERE einer Abfrage einen Vergleich zwischen der Commit-Zeitstempelspalte einer Tabelle und einem von Ihnen angegebenen Zeitpunkt mit folgenden Attributen enthalten:
Geben Sie die genaue Zeit als konstanten Ausdruck an: ein Literal, ein Parameter oder eine Funktion, deren eigene Argumente als Konstanten ausgewertet werden.
Vergleichen Sie, ob der Commit-Zeitstempel neuer als die angegebene Zeit ist. Verwenden Sie dazu entweder den Operator
>oder>=.Optional können Sie der Anweisung
WHEREmitANDweitere Einschränkungen hinzufügen. Wenn Sie die Anweisung mitORerweitern, wird die Abfrage von dieser Optimierung ausgeschlossen.
Sehen Sie sich beispielsweise die folgende Tabelle Performances mit einer Commit-Zeitstempelspalte an:
CREATE TABLE Performances (
SingerId bigint NOT NULL,
VenueId bigint NOT NULL,
EventDate timestamp with time zone NOT NULL,
Revenue bigint,
LastUpdateTime spanner.commit_timestamp,
PRIMARY KEY(SingerId, VenueId, EventDate)
);
Diese Abfrage profitiert von der oben beschriebenen Optimierung durch Commit-Zeitstempel, da sie einen „Größer als oder gleich“-Vergleich zwischen der Commit-Zeitstempelspalte der Tabelle und einem konstanten Ausdruck enthält – in diesem Fall ein Literal:
SELECT * FROM Performances WHERE LastUpdateTime >= '2022-01-01';