Datas/horas de confirmação em bases de dados com dialeto GoogleSQL

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, é o momento 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:

  1. Crie uma coluna com o tipo TIMESTAMP com a opção de coluna allow_commit_timestamp definida como true na definição do esquema. Por exemplo:

    CREATE TABLE Performances (
        ...
        LastUpdateTime  TIMESTAMP NOT NULL OPTIONS (allow_commit_timestamp=true)
        ...
    ) PRIMARY KEY (...);
    
  2. 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 colunas, 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 datas/horas únicas.

As indicações de tempo de confirmação do Spanner têm uma granularidade 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 principal e secundária. 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 pontos críticos 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 timestamps 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 anteriores. 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.

Remover 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++

void DmlStandardUpdateWithTimestamp(google::cloud::spanner::Client client) {
  using ::google::cloud::StatusOr;
  namespace spanner = ::google::cloud::spanner;
  auto commit_result = client.Commit(
      [&client](