Questo argomento descrive come scrivere un timestamp di commit per ogni inserimento e aggiornamento dell'operazione che esegui con Spanner.
Panoramica dei timestamp di commit
Il timestamp del commit, basato su TrueTime. tecnologia, è il momento in cui del commit della transazione nel database. Puoi archiviare atomicamente il commit il timestamp di una transazione in una colonna. Utilizzando i timestamp di commit archiviati nelle tabelle, puoi determinare l'ordine delle mutazioni e le funzionalità di creazione come i log delle modifiche.
Per inserire timestamp di commit nel database:
Crea una colonna di tipo
SPANNER.COMMIT_TIMESTAMP
. Ad esempio:CREATE TABLE Performances ( ... LastUpdateTime SPANNER.COMMIT_TIMESTAMP NOT NULL, ... PRIMARY KEY (...) ) ;
Se esegui inserimenti o aggiornamenti con DML, usa la funzione
SPANNER.PENDING_COMMIT_TIMESTAMP()
per scrivere il commit timestamp.Se esegui inserimenti o aggiornamenti con istruzioni preparate o mutazioni, utilizza la stringa segnaposto
SPANNER.COMMIT_TIMESTAMP()
per del timestamp di commit. Puoi utilizzare anche la costante di timestamp di commit fornita dalla libreria client. Ad esempio, questo nel client Java èValue.COMMIT_TIMESTAMP
.
Quando Spanner esegue il commit della transazione utilizzando questi segnaposto come di colonna, il timestamp di commit effettivo viene scritto nella colonna specificata. Puoi quindi usare questo valore colonna per creare una cronologia degli aggiornamenti della tabella.
Non è garantito che i valori dei timestamp di commit siano univoci. Transazioni che in insiemi di campi non sovrapposti potrebbero avere lo stesso timestamp. Le transazioni che scrivono in insiemi sovrapposti di campi hanno timestamp univoci.
I timestamp di commit di Spanner hanno una granularità in microsecondi,
e vengono convertiti in nanosecondi se archiviati in SPANNER.COMMIT_TIMESTAMP
colonne.
Chiavi e indici
Puoi utilizzare una colonna del timestamp di commit come colonna di chiave primaria o come non chiave
colonna. Le chiavi primarie possono essere definite come ASC
o DESC
.
ASC
(predefinito): le chiavi crescenti sono ideali per rispondere a query da un a un determinato periodo di tempo.DESC
: le chiavi discendenti consentono di mantenere le righe più recenti nella parte superiore della tabella. Forniscono un accesso rapido ai record più recenti.
Evita gli hotspot
L'uso di timestamp di commit nei seguenti scenari crea hotspot, che ridurre le prestazioni dei dati:
La colonna timestamp di commit come prima parte della chiave primaria di una tabella.
CREATE TABLE Users ( LastAccess SPANNER.COMMIT_TIMESTAMP NOT NULL, UserId INT64 NOT NULL, ... PRIMARY KEY (LastAccess, UserId) ) ;
Esegui il commit della colonna di chiave primaria con timestamp come prima parte di un indice secondario.
CREATE INDEX UsersByLastAccess ON Users(LastAccess)
o
CREATE INDEX UsersByLastAccessAndName ON Users(LastAccess, FirstName)
Gli hotspot riducono le prestazioni dei dati, anche con basse velocità di scrittura. Non c'è alcun overhead del rendimento se i timestamp di commit sono abilitati su colonne non chiave che non sono indicizzate.
Aggiungi una colonna del timestamp di commit a una tabella esistente
Per aggiungere una colonna di timestamp di commit a una tabella esistente, utilizza ALTER TABLE
l'Informativa. Ad esempio, per aggiungere una colonna LastUpdateTime
a Performances
utilizza la seguente istruzione:
ALTER TABLE Performances ADD COLUMN LastUpdateTime SPANNER.COMMIT_TIMESTAMP
NOT NULL;
Scrivi un timestamp di commit utilizzando un'istruzione DML
Utilizzerai la funzione SPANNER.PENDING_COMMIT_TIMESTAMP()
per scrivere il commit
in un'istruzione DML. Spanner seleziona il timestamp di commit quando la transazione
commit.
La seguente istruzione DML aggiorna la colonna LastUpdateTime
in
Tabella Performances
con il timestamp di commit:
UPDATE Performances SET LastUpdateTime = SPANNER.PENDING_COMMIT_TIMESTAMP()
WHERE SingerId=1 AND VenueId=2 AND EventDate="2015-10-21"
Inserire una riga utilizzando una mutazione
Quando inserisci una riga, Spanner scrive solo il valore del timestamp di commit
se includi la colonna nell'elenco e passi il
Stringa segnaposto spanner.commit_timestamp()
(o costante della libreria client)
come valore. Ad esempio:
C++
C#
Vai
Java
Node.js
PHP
Python
Ruby
Se sono presenti mutazioni sulle righe di più tabelle, devi specificare
spanner.commit_timestamp()
(o costante della libreria client) per il commit
colonna timestamp in ogni tabella.
Aggiorna una riga utilizzando una mutazione
Quando aggiorna una riga, Spanner scrive solo il valore del timestamp di commit
se includi la colonna nell'elenco e passi il
Stringa segnaposto spanner.commit_timestamp()
(o costante della libreria client)
come valore. Non puoi aggiornare la chiave primaria di una riga. Per aggiornare
chiave primaria, elimina la riga esistente e creane una nuova.
Ad esempio, per aggiornare una colonna del timestamp di commit denominata LastUpdateTime
:
C++
C#
Vai
Java
Node.js
PHP
Python
Ruby
Se sono presenti mutazioni sulle righe di più tabelle, devi specificare
spanner.commit_timestamp()
(o la libreria client
costante) per la colonna del timestamp di commit in ogni tabella.
Esegui una query su una colonna del timestamp di commit
L'esempio seguente esegue query sulla colonna del timestamp di commit della tabella.
C++
C#
Vai
Java
Node.js
PHP
Python
Ruby
Specifica un valore per la colonna del timestamp del commit
Nel codice, puoi fornire il tuo valore per la colonna del timestamp di commit
anziché passare spanner.commit_timestamp()
(o la libreria client disponibile
costante) come
. Il valore deve essere un timestamp nel passato. Questa restrizione
assicura che la scrittura dei timestamp sia un'operazione rapida e poco costosa. Un
un modo semplice per confermare che un valore è nel passato
è confrontarlo con il valore restituito dalla funzione SQL CURRENT_TIMESTAMP
.
Il server restituisce un errore FailedPrecondition
in caso di
il timestamp specificato.
Crea un log delle modifiche
Supponiamo di voler creare un log delle modifiche di ogni mutazione che si verifica a un e utilizzare il log delle modifiche per il controllo. Un esempio potrebbe essere una tabella che archivia la cronologia delle modifiche apportate ai documenti di videoscrittura. Il timestamp di commit semplifica la creazione del log delle modifiche, perché i timestamp possono imporre l'ordine delle voci del log delle modifiche. Potresti creare un che archivia la cronologia delle modifiche apportate a un determinato documento utilizzando uno schema come nell'esempio seguente:
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;
Per creare un log delle modifiche, inserisci una nuova riga in DocumentHistory
nella stessa
transazione in cui inserisci o aggiorni una riga in Document
. Durante l'inserimento
della nuova riga in DocumentHistory
, usa il segnaposto
spanner.commit_timestamp()
(o costante della libreria client) per indicare
Spanner per scrivere il timestamp di commit nella colonna Ts
. Interfoliazione
la tabella DocumentsHistory
con la tabella Documents
consentirà di inserire
località e di inserimenti e aggiornamenti più efficienti. Tuttavia, aggiunge anche
il vincolo che le righe padre e figlio
devono essere eliminati insieme. Per mantenere le righe in DocumentHistory
dopo le righe
in Documents
vengono eliminate, non alternare le tabelle.
Ottimizza le query sui dati recenti con timestamp di commit
I timestamp di commit consentono un'ottimizzazione Spanner che può ridurre l'I/O delle query durante il recupero dei dati scritti dopo una nel tempo.
Per attivare questa ottimizzazione, la clausola WHERE
di una query deve includere un
confronto tra la colonna del timestamp di commit di una tabella e un intervallo di tempo specifico
che fornisci, con i seguenti attributi:
Specifica il tempo specifico come espressione costante: un valore letterale, una o una funzione i cui argomenti restituiscono costanti.
Confronta se il timestamp di commit è più recente del timestamp in un dato momento, tramite gli operatori
>
o>=
.Se vuoi, aggiungi ulteriori limitazioni alla clausola
WHERE
conAND
. L'estensione della clausola conOR
rende la query non idonea e ottimizzazione.
Ad esempio, considera la seguente tabella Performances
, che include
una colonna con timestamp di commit:
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)
);
Questa query trae vantaggio dall'ottimizzazione del timestamp del commit descritta in precedenza, perché ha un confronto maggiore o uguale a la colonna del timestamp di commit della tabella e un'espressione costante, in questo case, un valore letterale:
SELECT * FROM Performances WHERE LastUpdateTime >= '2022-01-01';