Gerenciamento de valores padrão da chave primária

Esta página discute estratégias 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:

  • Impedir o ponto de acesso
  • Simplifique as migrações de outros bancos de dados
  • Encapsule a lógica de chave no banco de dados para que você não precise se preocupar com o gerenciamento no aplicativo.

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

  • Uma função UUID que gera valores de UUID da 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 da versão 4 para usar como chave primária. Os UUIDs funcionam bem para novos aplicativos e tabelas com muitas linhas. Eles são distribuídos de maneira aproximadamente uniforme no keyspace, o que impede o hotspotting em escala. A geração de UUID pode criar um grande número de valores (2122), e cada valor é efetivamente único. Por exemplo, você precisaria de 2, 71×1018 valores para uma probabilidade de colisão de 50% ou 1 bilhão por segundo por 86 anos. Isso garante valores exclusivos quando você os usa em tabelas grandes. Os UUIDs são exclusivos, independentemente de serem gerados no banco de dados ou no cliente. Recomendamos o uso de UUIDs sempre que possível. É possível misturar com segurança UUIDs gerados pelo cliente e pelo Spanner na mesma tabela se os UUIDs gerados pelo cliente forem serializados como letras minúsculas, de acordo com a RFC 4122.

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 de chave FanId tem GENERATE_UUID na coluna de valor como valor padrão. O exemplo usa 36 caracteres para os atributos STRING do GoogleSQL e varchar do PostgreSQL porque os UUIDs têm 36 caracteres. Quando você usa a instrução INSERT with THEN RETURN para inserir na tabela Fans, o 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 ao seguinte:

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.

IDENTITY colunas

Com as colunas IDENTITY, é possível gerar automaticamente valores inteiros para colunas de chave e não-chave. As colunas IDENTITY não exigem que os usuários mantenham manualmente uma sequência de base ou gerenciem a relação entre a coluna e a sequência. Quando uma coluna de identidade gerada automaticamente é descartada, a sequência subjacente também é excluída automaticamente.

É possível usar colunas IDENTITY fornecendo um valor inteiro inicial ao gerar a sequência ou deixando o Spanner gerar a sequência de inteiros para você. Para fornecer um valor inteiro inicial, use a opção START COUNTER WITH e um valor inicial INT64 positivo. O Spanner usa esse valor para definir o próximo valor para o contador de sequência interna gerado automaticamente e inverte o valor antes de inseri-lo nesta coluna.

No Spanner, as colunas IDENTITY são compatíveis com o GoogleSQL e o PostgreSQL.

GoogleSQL

O exemplo a seguir mostra como usar colunas IDENTITY para criar uma coluna de chave primária de número inteiro gerada automaticamente para SingerId ao criar uma nova tabela usando o comando CREATE TABLE:

CREATE TABLE Singers (
  SingerId INT64 GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE),
  Name STRING(MAX),
  Rank INT64
) PRIMARY KEY (SingerId);

Também é possível especificar o início do contador para a coluna usando a opção START_WITH_COUNTER. No exemplo abaixo, uma coluna de número inteiro gerada automaticamente é criada para SingerId com valores positivos invertidos e um contador interno que começa em 1.000.

CREATE TABLE Singers (
  SingerId INT64 GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE START COUNTER WITH 1000),
  Name STRING(MAX),
  Rank INT64
) PRIMARY KEY (SingerId);

PostgreSQL

O exemplo a seguir mostra como usar colunas IDENTITY para criar uma coluna de inteiro gerada automaticamente para SingerId ao criar uma nova tabela usando o comando CREATE TABLE:

CREATE TABLE Singers (
  SingerId bigint GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE),
  Name text,
  PRIMARY KEY (SingerId)
);

Também é possível especificar o início do contador para a coluna usando a opção START COUNTER WITH. No exemplo abaixo, uma coluna de número inteiro gerada automaticamente é criada para SingerId, que gera valores positivos invertidos em bit, e o contador interno, antes da inversão de bit, começa em 1.000.

CREATE TABLE Singers (
  SingerId bigint GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE START COUNTER WITH 1000),
  Name text,
  PRIMARY KEY (SingerId)
);

Sequência invertida em bits

Uma sequência de bits invertidos é um objeto de esquema que produz uma sequência de números inteiros e inverte os bits. Esse objeto usa a inversão de bits em um contador interno e privado do Spanner para garantir a exclusividade. Os valores invertidos em bits resultantes ajudam a evitar o uso excessivo em grande 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 excluir uma sequência que produz valores positivos invertidos (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 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 os valores de saída invertidos na coluna. As sequências invertidas de bits são especialmente úteis para chaves primárias, porque os valores invertidos de bits são distribuídos uniformemente no espaço de chaves para que não causem pontos de acesso.

O exemplo a seguir mostra como criar uma sequência invertida e uma tabela em que a coluna de chave 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)
);

Em seguida, use a instrução SQL abaixo 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 ao seguinte:

SingerId
3458764513820540928

Cenários para usar 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 oferece o objeto de esquema de sequência positivo com bits invertidos (PostgreSQL ou GoogleSQL). Caso contrário, para novos aplicativos, recomendamos o uso do identificador universal exclusivo (UUID). Para mais informações, consulte Usar um identificador universal exclusivo (UUID).

Migrações

Para migrações de tabelas para o Spanner, você tem algumas opções:

A seguir