Este tópico descreve como gravar um carimbo de data/hora de confirmação para cada inserção e atualização
que você executa com o Spanner. Para usar esse recurso, defina a opção allow_commit_timestamp
em uma coluna TIMESTAMP
e grave o carimbo de data/hora como parte de cada transação.
Visão geral
O carimbo de data/hora de confirmação, com base na tecnologia
TrueTime, é o momento em que uma
transação é confirmada no banco de dados. A opção de coluna allow_commit_timestamp
permite armazenar de maneira atômica o carimbo de data/hora de confirmação em uma coluna.
Usando os carimbos de data/hora de confirmação armazenados em tabelas, determine a ordem exata de mutações e recursos de versão como registros de alterações.
Para inserir carimbos de data/hora de confirmação no seu banco de dados, siga as etapas a seguir:
Crie uma coluna com o tipo
TIMESTAMP
com a opção de colunaallow_commit_timestamp
definida comotrue
na definição do esquema. Exemplo:CREATE TABLE Performances ( ... LastUpdateTime TIMESTAMP NOT NULL OPTIONS (allow_commit_timestamp=true) ... ) PRIMARY KEY (...);
Se você estiver executando inserções ou atualizações com o DML, use a função
PENDING_COMMIT_TIMESTAMP
para gravar o carimbo de data/hora de confirmação.Se você estiver executando inserções ou atualizações com mutações, use a string de marcador
spanner.commit_timestamp()
nas inserções ou atualizações da coluna de carimbo de data/hora de confirmação. Também é possível usar a constante de carimbo de data/hora de confirmação fornecida pela biblioteca de cliente. Por exemplo, essa constante no cliente Java éValue.COMMIT_TIMESTAMP
.
Quando o Spanner confirma a transação usando esses marcadores como valores de coluna, o carimbo de data/hora real é gravado na coluna especificada (por exemplo, a coluna LastUpdateTime
). Você pode usar esse valor de coluna para criar um histórico de atualizações na tabela.
Os valores de carimbo de data/hora de commit não têm garantia de exclusividade. As transações gravadas em conjuntos de campos não sobrepostos podem ter o mesmo carimbo de data/hora. As transações gravadas em conjuntos de campos sobrepostos têm carimbos de data/hora exclusivos.
Os carimbos de data/hora de confirmação do Spanner têm granularidade de microssegundos,
e convertidos em nanossegundos quando armazenados em colunas TIMESTAMP
.
Criar e excluir uma coluna de carimbo de data/hora de confirmação
Use a opção de coluna allow_commit_timestamp
para adicionar e remover compatibilidade com carimbos de data/hora de commit:
- Ao criar uma nova tabela para especificar que uma coluna é compatível com carimbos de data/hora de commit.
- Ao alterar uma tabela existente:
- para adicionar uma nova coluna compatível com carimbos de data/hora de commit;
- para alterar uma coluna
TIMESTAMP
existente para aceitar carimbos de data/hora de commit; - para alterar uma coluna
TIMESTAMP
existente e remover o suporte de carimbo de data/hora de confirmação.
Chaves e índices
Use uma coluna de carimbo de data/hora de confirmação como uma coluna de chave primária ou como uma coluna sem chave. As chaves primárias podem ser definidas como ASC
ou DESC
.
ASC
(padrão): as chaves crescentes são ideais para responder a consultas de uma hora específica em diante.DESC
: as chaves decrescentes mantêm as linhas mais recentes no topo da tabela. Elas dão acesso rápido aos registros mais recentes.
A opção allow_commit_timestamp
precisa ser consistente entre as chaves primárias das tabelas pai e filho. Se a opção não for consistente entre as
chaves primárias, o Spanner vai retornar um erro. A única ocasião em que a opção pode ser inconsistente é quando você está criando ou atualizando o esquema.
O uso de carimbos de data/hora de confirmação nas situações a seguir cria pontos de acesso que reduzem o desempenho dos dados:
Coluna de carimbo de edata/hora de confirmação como a primeira parte da chave primária 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)
Pontos de acesso reduzem o desempenho dos dados, mesmo com baixas taxas de gravação. Quando os carimbos de data/hora de confirmação são ativados em colunas que não são chave e nem estão indexadas, não há sobrecarga de desempenho.
Criar uma coluna de carimbo de data/hora de confirmação
A DDL a seguir cria uma tabela com uma coluna compatível com carimbos de data/hora de commit.
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
Adicionar a opção altera a coluna do carimbo de data/hora assim:
- Use a string
spanner.commit_timestamp()
de marcador (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 Como fornecer o próprio valor para o carimbo de data/hora.
A opção allow_commit_timestamp
diferencia maiúsculas e minúsculas.
Adicionar uma coluna de carimbo de data/hora de confirmação a uma tabela
Para adicionar uma coluna de carimbo de data/hora de confirmação a uma tabela existente, use a instrução ALTER TABLE
. Por exemplo, para adicionar uma coluna LastUpdateTime
à tabela Performances
, use a seguinte instrução:
ALTER TABLE Performances ADD COLUMN LastUpdateTime TIMESTAMP
NOT NULL OPTIONS (allow_commit_timestamp=true)
Converter uma coluna de carimbo de data/hora em uma coluna de carimbo de data/hora de confirmação
É possível converter uma coluna de carimbo de data/hora existente em uma coluna de carimbo de data/hora de confirmação mas isso exige que o Spanner valide que os sistemas os valores de carimbo de data/hora estejam no passado. 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 em uma instrução ALTER TABLE
que inclui SET OPTIONS
. Para mais detalhes, consulte Linguagem de definição de dados.
Remover a opção de carimbo de data/hora de confirmação
Se você quiser remover o suporte ao carimbo de data/hora de confirmação de uma coluna, use a opção allow_commit_timestamp=null
em uma instrução ALTER TABLE
. O comportamento do carimbo de data/hora de confirmação é removido, mas a coluna continua sendo um carimbo de data/hora. Mudar essa opção não altera outras características da coluna, como tipo ou nulidade (NOT NULL
). Por exemplo:
ALTER TABLE Performances ALTER COLUMN LastUpdateTime
SET OPTIONS (allow_commit_timestamp=null)
Gravar um carimbo de data/hora de confirmação usando uma instrução DML
Use a função PENDING_COMMIT_TIMESTAMP
para gravar o carimbo
de data/hora de confirmação em uma instrução DML. O Spanner seleciona o carimbo de data/hora de confirmação quando a transação
confirmações.
A instrução DML a seguir atualiza a coluna LastUpdateTime
na tabela Performances
com o carimbo de 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 a seguir usa a função PENDING_COMMIT_TIMESTAMP
para gravar o carimbo de data/hora de confirmação na coluna LastUpdateTime
.
C++
C#
Go
Java
Node.js
PHP
Python
Ruby
Ruby
Os carimbos de data/hora de confirmação só podem ser gravados em colunas anotadas com a opção allow_commit_timestamp=true
.
Se você tiver mutações nas linhas de várias tabelas, precisará especificar spanner.commit_timestamp()
(ou a constante da biblioteca de cliente) para a coluna de carimbo de data/hora de confirmação em cada tabela.
Consultar uma coluna de carimbo de data/hora de confirmação
O exemplo a seguir consulta a coluna do carimbo de data/hora de commit da tabela.
C++
C#
Go
Java
Node.js
PHP
Python
Ruby
Forneça seu próprio valor para a coluna do carimbo de data/hora de confirmação
Forneça um valor próprio para a coluna do carimbo 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 precisa ser um carimbo de data/hora no passado. Essa restrição garante que gravar carimbos de data/hora seja uma operação rápida e barata. O servidor
retorna um erro FailedPrecondition
se um carimbo de data/hora futuro for especificado.
Criar um registro de alterações
Suponhamos que você queira criar um registro de alterações de cada mutação feita em uma tabela e use esse registro na auditoria. Um exemplo seria uma tabela que armazenasse o histórico de alterações em documentos de processamento de texto. O carimbo de data/hora de commit facilita a criação do registro de alterações, porque os carimbos de data/hora podem impor a ordem das entradas do registro de alterações. Crie um registro de alterações que armazene o histórico de alterações em um determinado documento usando um esquema como o exemplo a seguir:
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 registro de alterações, insira uma nova linha em DocumentHistory
na mesma transação em que você inserir ou atualizar 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 dizer
ao Spanner para gravar o carimbo de data/hora de confirmação na coluna Ts
. A intercalação da tabela DocumentsHistory
com a tabela Documents
permitirá conhecer a localização dos dados, além de inserções e atualizações mais eficientes. No entanto, ela também adiciona a restrição de que as linhas pai e filho precisam ser excluídas juntas. Para manter as linhas em DocumentHistory
depois que as linhas em Documents
forem excluídas, não intercale as tabelas.
Otimizar consultas de dados recentes com carimbos de data/hora de confirmação
Os carimbos de data/hora de confirmação permitem uma otimização do Spanner que pode reduzir a E/S de consulta ao recuperar dados gravados após uma tempo de resposta.
Para ativar essa otimização, a cláusula WHERE
de uma consulta precisa incluir uma comparação entre a coluna de carimbo de data/hora de confirmação de uma tabela e um horário específico fornecido, com os seguintes atributos:
Forneça o horário específico 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 o carimbo de data/hora da confirmação é mais recente que o tempo especificado usando os operadores
>
ou>=
.Se quiser, adicione outras restrições à cláusula
WHERE
comAND
. Estender a cláusula comOR
desqualifica a consulta deste otimização.
Por exemplo, considere a tabela Performances
a seguir, que inclui
uma coluna de carimbo 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);
Essa consulta se beneficia da otimização de carimbo de data/hora de confirmação descrita anteriormente, porque tem uma comparação maior que ou igual entre a coluna de carimbo de data/hora de confirmação da tabela e uma expressão constante. Neste caso, um literal:
SELECT * FROM Performances WHERE LastUpdateTime >= "2022-05-01";
A consulta a seguir também se qualifica para a otimização, já que tem uma comparação maior que entre o carimbo de data/hora do commit e uma função cujos argumentos são avaliados como constantes durante a execução da consulta:
SELECT * FROM Performances
WHERE LastUpdateTime > TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY);
A seguir
- Use os carimbos de data/hora de confirmação para criar um registro de alterações com o Go.