Gerenciamento de valores padrão da chave primária

Nesta página, discutimos estratégias a serem usadas para gerar valores de chave primária na tabela usando expressões de valor padrão. Essas estratégias têm os seguintes benefícios:

  • Evitar uso excessivo de ponto de acesso
  • Simplifique migrações de outros bancos de dados
  • Encapsule a lógica de chave no banco de dados para não precisar se preocupar em gerenciá-la no aplicativo

É possível usar as seguintes estratégias em uma coluna que tenha expressões DEFAULT:

  • Uma função UUID que gera valores UUID versão 4
  • Um objeto de esquema, SEQUENCE, que tem uma opção bit_reversed_positive. SEQUENCE está disponível para GoogleSQL e PostgreSQL.

Métodos para gerar chaves primárias automaticamente

Identificador universal exclusivo (UUID)

O Spanner pode gerar automaticamente uma string UUID versão 4 para usar como chave primária. UUIDs funcionam bem para novos aplicativos e tabelas com muitas linhas. Eles são distribuídos de maneira quase uniforme no espaço da chave, o que evita o uso excessivo do ponto de acesso em escala. A geração de UUID pode criar um grande número de valores (2122) e cada valor é efetivamente único. Por exemplo, você precisa de valores de 2, 71×1018 para uma probabilidade de 50% de colisão ou 1 bilhão por segundo por 86 anos. Isso garante valores exclusivos quando usado em tabelas grandes. Os UUIDs são exclusivos, independentemente de serem gerados no banco de dados ou no cliente. Recomendamos que você use UUIDs sempre que possível. É possível misturar com segurança os UUIDs gerados pelo cliente e pelo Spanner na mesma tabela se eles forem serializados como minúsculas, de acordo com a RFC 4122 (link em inglês).

Para uma coluna que precisa de valores padrão, use a função GENERATE_UUID para gerá-los. O exemplo a seguir mostra como criar uma tabela em que a coluna da chave FanId tem GENERATE_UUID na coluna de valor como valor padrão. O exemplo usa 36 caracteres para os atributos Google SQL STRING e PostgreSQL varchar porque os UUIDs têm 36 caracteres. Quando você usa a instrução INSERT with THEN RETURN para inserir na tabela Fans, GENERATE_UUID gera e retorna um valor UUID para FanId.

GoogleSQL

CREATE TABLE Fans (
  FanId STRING(36) DEFAULT (GENERATE_UUID()),
  Name STRING(MAX),
) PRIMARY KEY (FanId);

PostgreSQL

CREATE TABLE Fans (
  FanId varchar(36) DEFAULT spanner.generate_uuid(),
  Name text,
  PRIMARY KEY (FanId)
);

GoogleSQL

INSERT INTO Fans (Name) VALUES ('Melissa Garcia')
THEN RETURN FanId;

PostgreSQL

INSERT INTO fans (name) VALUES ('Melissa Garcia')
RETURNING (fanid);

Essa instrução retorna um resultado semelhante a este:

FanId
6af91072-f009-4c15-8c42-ebe38ae83751

Para mais informações sobre a função GENERATE_UUID(), consulte a página de referência do GoogleSQL ou do PostgreSQL.

Sequência invertida em bits

Uma sequência invertida de bits é um objeto de esquema que produz uma sequência de números inteiros e faz a reversão de bits. Esse objeto usa a reversão de bits em um contador interno e particular do Spanner para garantir a exclusividade. Os valores reversos de bits resultantes ajudam a evitar o uso excessivo de pontos de acesso em escala quando usados em uma chave primária.

No Spanner, você usa instruções DDL SEQUENCE com o atributo bit_reversed_positive para criar, alterar ou descartar uma sequência que produz valores positivos revertidos em bits (GoogleSQL ou PostgreSQL).

Cada sequência mantém um conjunto de contadores internos e os usa para gerar um valor. O contador de sequência fornece a entrada para o algoritmo de reversão de bits.

Quando você define uma coluna com uma expressão DEFAULT que usa a função GET-NEXT-SEQUENCE-VALUE do GoogleSQL ou a função nextval do PostgreSQL como valor padrão, o Spanner chama automaticamente a função e coloca na coluna os valores de saída revertidos em bits. As sequências invertidas em bits são especialmente úteis para chaves primárias porque os valores revertidos em bits são distribuídos uniformemente pelo espaço da chave para que não causem uso excessivo do ponto de acesso.

O exemplo abaixo mostra como criar uma sequência invertida em bits e uma tabela em que a coluna principal usa a sequência como o valor padrão:

GoogleSQL

CREATE SEQUENCE SingerIdSequence OPTIONS (
  sequence_kind="bit_reversed_positive"
);

CREATE TABLE Singers (
  SingerId INT64 DEFAULT (GET_NEXT_SEQUENCE_VALUE(SEQUENCE SingerIdSequence)),
  Name STRING(MAX),
  Rank INT64,
) PRIMARY KEY (SingerId);

PostgreSQL

CREATE SEQUENCE SingerIdSequence bit_reversed_positive;

CREATE TABLE Singers (
  SingerId bigint DEFAULT nextval('SingerIdSequence'),
  Name text,
  PRIMARY KEY (SingerId)
);

É possível usar a seguinte instrução SQL para inserir e retornar o valor da chave primária:

GoogleSQL

INSERT INTO Singers (Name) VALUES ('Melissa Garcia')
THEN RETURN SingerId;

PostgreSQL

INSERT INTO Singers (name) VALUES ('Melissa Garcia')
RETURNING (SingerId);

Essa instrução retorna um resultado semelhante a este:

SingerId
3458764513820540928

Cenários para o uso de UUIDs e sequências como valores padrão para chaves primárias

Os cenários para UUIDs e sequências incluem o seguinte:

  • Novos aplicativos
  • Migrações

As seções a seguir descrevem cada cenário.

Novos aplicativos

Se o aplicativo atual exigir chaves INT64 no GoogleSQL ou chaves bigint no PostgreSQL, o Spanner oferecerá o objeto de esquema de sequência positiva invertida em bits (PostgreSQL ou GoogleSQL). Caso contrário, para novos aplicativos, recomendamos o uso do Identificador universal exclusivo (UUID, na sigla em inglês). Para mais informações, consulte Usar um identificador universal exclusivo (UUID).

Migrações

Para migrações de tabelas para o Spanner, há algumas opções:

  • Se você estiver usando UUIDs no banco de dados de origem, no Spanner, será possível usar uma coluna de chave no tipo STRING e a função GENERATE_UUID() (GoogleSQL ou PostgreSQL) como valor padrão.
  • Se você estiver usando uma chave primária de número inteiro e o aplicativo só precisar que a chave seja exclusiva, use uma coluna de chave em INT64 e uma sequência positiva invertida de bits para o valor padrão da chave primária. Consulte Como migrar colunas de chave reversas de bits.
  • O Spanner não é compatível com uma maneira de gerar valores monotônicos.

    Se você estiver usando uma chave monotônica, como o tipo SERIAL do PostgreSQL, ou o atributo AUTO_INCREMENT do MySQL, e precisar de novas chaves monotônicas no Spanner, use uma chave composta. Consulte Trocar a ordem das chaves e Gerar hash da chave exclusiva e espalhar as gravações em fragmentos lógicos.

  • Se seu aplicativo está revertendo manualmente a chave INT64 no GoogleSQL ou a chave bigint no PostgreSQL, você pode usar uma sequência positiva invertida em bits (GoogleSQL ou PostgreSQL) e fazer com que ela gere novas chaves-valor para você. Consulte Como migrar colunas de chave reversas de bits.

A seguir