Este tópico descreve como escrever uma data/hora de confirmação para cada operação de inserção e atualização que realizar com o Spanner. Para usar esta funcionalidade, defina a opção allow_commit_timestamp
numa coluna TIMESTAMP
e, em seguida, escreva a data/hora como parte de cada transação.
Vista geral
A data/hora de confirmação, com base na tecnologia TrueTime, é a data/hora em que uma transação é confirmada na base de dados. A opção de coluna allow_commit_timestamp
permite-lhe armazenar atomicamente a data/hora de confirmação numa coluna.
Usando as datas/horas de confirmação armazenadas em tabelas, pode determinar a ordem exata das mutações e criar funcionalidades como registos de alterações.
Para inserir datas/horas de confirmação na sua base de dados, conclua os seguintes passos:
Crie uma coluna com o tipo
TIMESTAMP
com a opção de colunaallow_commit_timestamp
definida comotrue
na definição do esquema. Por exemplo:CREATE TABLE Performances ( ... LastUpdateTime TIMESTAMP NOT NULL OPTIONS (allow_commit_timestamp=true) ... ) PRIMARY KEY (...);
Se estiver a fazer inserções ou atualizações com DML, use a função
PENDING_COMMIT_TIMESTAMP
para escrever a data/hora de confirmação.Se estiver a fazer inserções ou atualizações com mutações, use a string de marcador de posição
spanner.commit_timestamp()
em inserções ou atualizações na coluna de data/hora de confirmação. Também pode usar a constante de data/hora de confirmação fornecida pela biblioteca de cliente. Por exemplo, esta constante no cliente Java éValue.COMMIT_TIMESTAMP
.
Quando o Spanner confirma a transação usando estes marcadores de posição como valores de coluna, a data/hora de confirmação real é escrita na coluna especificada (por exemplo, a coluna LastUpdateTime
). Em seguida, pode usar este valor da coluna para criar um histórico de atualizações da tabela.
Não é garantido que os valores de data/hora de confirmação sejam exclusivos. As transações que escrevem em conjuntos de campos não sobrepostos podem ter a mesma data/hora. As transações que escrevem em conjuntos de campos sobrepostos têm informações de data/hora únicas.
As indicações de tempo de confirmação do Spanner têm um nível de detalhe de microssegundos e são convertidas em nanosegundos quando armazenadas em colunas TIMESTAMP
.
Crie e elimine uma coluna de indicação de tempo de confirmação
Use a opção de coluna allow_commit_timestamp
para adicionar e remover suporte para
datas/horas de confirmação:
- Quando criar uma nova tabela para especificar que uma coluna suporta datas/horas de confirmação.
- Quando alterar uma tabela existente:
- Para adicionar uma nova coluna que suporte as datas/horas de confirmação,
- Para alterar uma coluna
TIMESTAMP
existente de modo a suportar as datas/horas de confirmação: - para alterar uma coluna
TIMESTAMP
existente de modo a remover o suporte da indicação de tempo de confirmação
Chaves e índices
Pode usar uma coluna de data/hora de confirmação como uma coluna de chave principal ou como uma coluna sem chave. As chaves primárias podem ser definidas como ASC
ou DESC
.
ASC
(predefinição) – As chaves ascendentes são ideais para responder a consultas a partir de um momento específico.DESC
– As chaves descendentes mantêm as linhas mais recentes na parte superior da tabela. Oferecem acesso rápido aos registos mais recentes.
A opção allow_commit_timestamp
tem de ser consistente nas chaves primárias das tabelas principais e secundárias. Se a opção não for consistente nas chaves primárias, o Spanner devolve um erro. A opção só pode ser inconsistente quando está a criar ou atualizar o esquema.
A utilização de datas/horas de confirmação nos seguintes cenários cria hotspots que reduzem o desempenho dos dados:
Coluna de data/hora de confirmação como a primeira parte da chave principal de uma tabela:
CREATE TABLE Users ( LastAccess TIMESTAMP NOT NULL, UserId INT64 NOT NULL, ... ) PRIMARY KEY (LastAccess, UserId);
A primeira parte da chave primária de um índice secundário:
CREATE INDEX UsersByLastAccess ON Users(LastAccess)
ou
CREATE INDEX UsersByLastAccessAndName ON Users(LastAccess, FirstName)
Os pontos críticos reduzem o desempenho dos dados, mesmo com taxas de gravação baixas. Não existe sobrecarga de desempenho se as datas/horas de confirmação estiverem ativadas em colunas não principais que não estejam indexadas.
Crie uma coluna de data/hora de confirmação
O LDD seguinte cria uma tabela com uma coluna que suporta carimbos de data/hora de confirmação.
CREATE TABLE Performances (
SingerId INT64 NOT NULL,
VenueId INT64 NOT NULL,
EventDate Date,
Revenue INT64,
LastUpdateTime TIMESTAMP NOT NULL OPTIONS (allow_commit_timestamp=true)
) PRIMARY KEY (SingerId, VenueId, EventDate),
INTERLEAVE IN PARENT Singers ON DELETE CASCADE
A adição da opção altera a coluna de indicação de tempo da seguinte forma:
- Pode usar a string de marcador de posição
spanner.commit_timestamp()
(ou uma constante fornecida pela biblioteca de cliente) para inserções e atualizações. - A coluna só pode conter valores no passado. Para mais informações, consulte o artigo Fornecer o seu próprio valor para a data/hora.
A opção allow_commit_timestamp
é sensível a maiúsculas e minúsculas.
Adicione uma coluna de data/hora de confirmação a uma tabela existente
Para adicionar uma coluna de data/hora de confirmação a uma tabela existente, use a declaração ALTER TABLE
. Por exemplo, para adicionar uma coluna LastUpdateTime
à tabela Performances
, use a seguinte declaração:
ALTER TABLE Performances ADD COLUMN LastUpdateTime TIMESTAMP
NOT NULL OPTIONS (allow_commit_timestamp=true)
Converta uma coluna de data/hora numa coluna de data/hora de confirmação
Pode converter uma coluna de data/hora existente numa coluna de data/hora de confirmação, mas, para isso, o Spanner tem de validar se os valores de data/hora existentes são no passado. Por exemplo:
ALTER TABLE Performances ALTER COLUMN LastUpdateTime
SET OPTIONS (allow_commit_timestamp=true)
Não é possível alterar o tipo de dados nem a anotação NULL
de uma coluna numa declaração ALTER TABLE
que inclua SET OPTIONS
. Para obter detalhes, consulte o artigo
Linguagem de definição de dados.
Remova a opção de indicação de tempo de confirmação
Se quiser remover o suporte de data/hora de confirmação de uma coluna, use a opção
allow_commit_timestamp=null
numa declaração ALTER TABLE
. O comportamento da data/hora de confirmação é removido, mas a coluna continua a ser uma data/hora. A alteração da opção não altera nenhuma outra característica da coluna, como o tipo ou a capacidade de ser nula (NOT NULL
). Por exemplo:
ALTER TABLE Performances ALTER COLUMN LastUpdateTime
SET OPTIONS (allow_commit_timestamp=null)
Escrever uma data/hora de confirmação com uma declaração DML
Use a função PENDING_COMMIT_TIMESTAMP
para escrever a data/hora de confirmação numa declaração DML. O Spanner seleciona a data/hora de confirmação quando a transação é confirmada.
A seguinte declaração DML atualiza a coluna LastUpdateTime
na tabela Performances
com a data/hora de confirmação:
UPDATE Performances SET LastUpdateTime = PENDING_COMMIT_TIMESTAMP()
WHERE SingerId=1 AND VenueId=2 AND EventDate="2015-10-21"
O exemplo de código seguinte usa a função
PENDING_COMMIT_TIMESTAMP
para escrever a data/hora de confirmação na coluna LastUpdateTime
.
C++
C#
Go
Java
Node.js
PHP
Python
Ruby
Ruby
As datas/horas de confirmação só podem ser escritas em colunas anotadas com a opção allow_commit_timestamp=true
.
Se tiver mutações em linhas em várias tabelas, tem de especificar spanner.commit_timestamp()
(ou a constante da biblioteca de cliente) para a coluna de data/hora de confirmação em cada tabela.
Consultar uma coluna de data/hora de confirmação
O exemplo seguinte consulta a coluna de data/hora de confirmação da tabela.
C++
C#
Go
Java
Node.js
PHP
Python
Ruby
Indique o seu próprio valor para a coluna de data/hora de confirmação
Pode fornecer o seu próprio valor para a coluna de data/hora de confirmação, em vez de transmitir spanner.commit_timestamp()
(ou a constante da biblioteca de cliente) como o valor da coluna. O valor tem de ser uma data/hora no passado. Esta restrição garante que a escrita de datas/horas é uma operação barata e rápida. O servidor devolve um erro FailedPrecondition
se for especificado um registo de data/hora futuro.
Crie um registo de alterações
Suponhamos que quer criar um registo de alterações de todas as mutações que ocorrem numa tabela e, em seguida, usar esse registo de alterações para auditoria. Um exemplo seria uma tabela que armazena o histórico de alterações a documentos de processamento de texto. A data/hora de confirmação facilita a criação do histórico de alterações, porque as datas/horas podem aplicar a ordenação das entradas do histórico de alterações. Pode criar um registo de alterações que armazene o histórico de alterações a um determinado documento através de um esquema como o do exemplo seguinte:
CREATE TABLE Documents (
UserId INT64 NOT NULL,
DocumentId INT64 NOT NULL,
Contents STRING(MAX) NOT NULL,
) PRIMARY KEY (UserId, DocumentId);
CREATE TABLE DocumentHistory (
UserId INT64 NOT NULL,
DocumentId INT64 NOT NULL,
Ts TIMESTAMP NOT NULL OPTIONS (allow_commit_timestamp=true),
Delta STRING(MAX),
) PRIMARY KEY (UserId, DocumentId, Ts),
INTERLEAVE IN PARENT Documents ON DELETE NO ACTION;
Para criar um registo de alterações, insira uma nova linha em DocumentHistory
na mesma transação em que insere ou atualiza uma linha em Document
. Na inserção
da nova linha em DocumentHistory
, use o marcador de posição
spanner.commit_timestamp()
(ou a constante da biblioteca de cliente) para indicar
ao Spanner que escreva a data/hora de confirmação na coluna Ts
. A intercalação da tabela DocumentsHistory
com a tabela Documents
permite a localidade dos dados e inserções e atualizações mais eficientes. No entanto, também adiciona a restrição de que as linhas principal e secundária têm de ser eliminadas em conjunto. Para manter as linhas em DocumentHistory
depois de eliminar as linhas em Documents
, não entrelace as tabelas.
Otimize as consultas de dados recentes com indicações de tempo de confirmação
As datas/horas de confirmação permitem uma otimização do Spanner que pode reduzir a E/S de consultas quando são obtidos dados escritos após uma determinada hora.
Para ativar esta otimização, a cláusula WHERE
de uma consulta tem de incluir uma comparação entre a coluna de data/hora de confirmação de uma tabela e uma hora específica que indicar, com os seguintes atributos:
Indique a hora específica como uma expressão constante: um literal, um parâmetro ou uma função cujos próprios argumentos são avaliados como constantes.
Compare se a data/hora de confirmação é mais recente do que a hora indicada através dos operadores
>
ou>=
.Opcionalmente, adicione mais restrições à cláusula
WHERE
comAND
. A extensão da cláusula comOR
desqualifica a consulta desta otimização.
Por exemplo, considere a seguinte tabela Performances
, que inclui uma coluna de data/hora de confirmação:
CREATE TABLE Performances (
SingerId INT64 NOT NULL,
VenueId INT64 NOT NULL,
EventDate DATE,
Revenue INT64,
LastUpdateTime TIMESTAMP NOT NULL OPTIONS (allow_commit_timestamp=true)
) PRIMARY KEY (SingerId, VenueId, EventDate);
Esta consulta beneficia da otimização da data/hora de confirmação descrita anteriormente, porque tem uma comparação maior ou igual entre a coluna de data/hora de confirmação da tabela e uma expressão constante. Neste caso, trata-se de um literal:
SELECT * FROM Performances WHERE LastUpdateTime >= "2022-05-01";
A seguinte consulta também se qualifica para a otimização, uma vez que tem uma comparação do tipo "maior que" entre a data/hora de confirmação e uma função cujos argumentos são todos avaliados como constantes durante a execução da consulta:
SELECT * FROM Performances
WHERE LastUpdateTime > TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY);
O que se segue?
- Use indicações de tempo de confirmação para criar um registo de alterações com o Go.