Esta página discute estratégias para gerar valores de chave primária na tabela usando expressões de valor padrão. As informações nesta página se aplicam a bancos de dados com dialeto GoogleSQL e PostgreSQL. Essas estratégias têm os seguintes benefícios:
- Evitar gargalos
- Simplificar migrações de outros bancos de dados
- Encapsular a lógica da chave no banco de dados para que você não precise se preocupar em gerenciá-la no aplicativo
- Na maioria dos casos, substituir a necessidade de criar e gerenciar suas próprias sequências
Métodos para gerar chaves primárias automaticamente
Para gerar valores de chave primária automaticamente, use as seguintes estratégias em uma coluna que tenha expressões DEFAULT:
- Uma função UUID que gera valores da versão 4 do UUID.
- Colunas
IDENTITYque geram automaticamente valores inteiros para colunas de chave e não chave. SERIALno PostgreSQL eAUTO_INCREMENTno GoogleSQL, que são aliases DDL para colunasIDENTITY.- Um objeto de esquema,
SEQUENCE, que tem uma opçãobit_reversed_positive.SEQUENCEestá disponível para GoogleSQL e PostgreSQL.
Identificador universal exclusivo (UUID)
O Spanner pode gerar automaticamente um 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 uniforme no espaço de chaves, o que evita gargalos em escala. A geração de UUIDs pode criar um grande número de valores (2122), e cada valor é efetivamente exclusivo. Por exemplo, você precisaria de 2, 71×1018 valores para uma probabilidade de colisão de 50% ou 1 bilhão por segundo durante 86 anos. Isso garante valores exclusivos quando você os usa em tabelas grandes. Os UUIDs são exclusivos, seja gerados no banco de dados ou no cliente. Recomendamos que você use UUIDs sempre que possível. É possível misturar 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
NEW_UUID
função do GoogleSQL ou a
gen_random_uuid()
função do PostgreSQL
para gerá-los. O exemplo a seguir mostra como criar uma tabela em que a coluna de chave FanId tem um UUID gerado na coluna de valor como valor padrão.
GoogleSQL
CREATE TABLE Fans (
FanId UUID DEFAULT (NEW_UUID()),
Name STRING(MAX),
) PRIMARY KEY (FanId);
PostgreSQL
CREATE TABLE Fans (
FanId uuid DEFAULT gen_random_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 as funções UUID geradas, consulte a GoogleSQL ou PostgreSQL.
Colunas IDENTITY
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 subjacente ou gerenciem a relação entre a coluna e a sequência subjacente. 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 permitindo que o Spanner gere a sequência de números 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 do contador de sequência interno gerado automaticamente e inverte o valor de bit antes de inseri-lo nessa coluna.
No Spanner, as colunas IDENTITY são compatíveis com o GoogleSQL e o PostgreSQL.
GoogleSQL
O exemplo a seguir mostra como usar IDENTITY colunas para criar uma
coluna de chave primária de números inteiros gerada automaticamente para SingerId ao criar uma nova
tabela usando o
CREATE TABLE
comando:
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 a seguir, uma coluna de números inteiros gerada automaticamente é criada para SingerId que tem valores positivos invertidos por bit 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 números inteiros 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 a seguir, uma coluna de números inteiros gerada automaticamente é criada para SingerId, que gera valores positivos invertidos por bit e o contador interno, antes da inversão de bits,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)
);
SERIAL e AUTO_INCREMENT
O Spanner oferece suporte a SERIAL no PostgreSQL e
AUTO_INCREMENT no GoogleSQL, que são aliases DDL para colunas IDENTITY
e são usados para criar colunas de números inteiros exclusivas. Primeiro, defina a opção default_sequence_kind do banco de dados antes de usar SERIAL ou AUTO_INCREMENT.
Use a seguinte instrução SQL para definir a opção default_squence_kind do banco de dados:
GoogleSQL
ALTER DATABASE db SET OPTIONS (default_sequence_kind = 'bit_reversed_positive');
CREATE TABLE Singers (
id INT64 AUTO_INCREMENT PRIMARY KEY,
name STRING(MAX),
)
PostgreSQL
ALTER DATABASE db SET spanner.default_sequence_kind = 'bit_reversed_positive';
CREATE TABLE Singers (
id serial PRIMARY KEY,
name text
);
Como SERIAL e AUTO_INCREMENT são mapeados para colunas IDENTITY, eles não aparecem quando você serializa o esquema. Para esse esquema, a saída de GetDatabaseDDL seria:
GoogleSQL
ALTER DATABASE db SET OPTIONS (default_sequence_kind = 'bit_reversed_positive');
CREATE TABLE Singers (
id INT64 GENERATED BY DEFAULT AS IDENTITY,
name STRING(MAX),
) PRIMARY KEY (id);
PostgreSQL
ALTER DATABASE db SET spanner.default_sequence_kind = 'bit_reversed_positive';
CREATE TABLE Singers (
id bigint GENERATED BY DEFAULT AS IDENTITY NOT NULL,
name character varying,
PRIMARY KEY(id)
);
Sequência invertida por bit
Uma sequência invertida por bit é um objeto de esquema que produz uma sequência de números inteiros e os inverte por bit. Esse objeto usa a inversão de bits em um contador interno e particular do Spanner para garantir a exclusividade. Os valores invertidos por bit resultantes ajudam a evitar gargalos em escala quando usados em uma chave primária.
No Spanner, use instruções DDL SEQUENCE com o atributo
bit_reversed_positive para criar, alterar ou descartar uma
sequência que produz valores positivos invertidos por bit (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 inversão de bits.
Ao definir 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 os valores de saída invertidos por bit na coluna. As sequências invertidas por bit são especialmente úteis para chaves primárias, porque os valores invertidos por bit são distribuídos uniformemente no espaço de chaves para que não causem gargalos.
O exemplo a seguir mostra como criar uma sequência invertida por bit e uma tabela em que a coluna de chave usa a sequência como 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 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 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
Para novos aplicativos, o Spanner recomenda o uso de identificadores universais exclusivos (UUIDs) para chaves primárias. Para mais informações, consulte Usar um identificador universal exclusivo (UUID).
Se o aplicativo atual exigir chaves INT64 no GoogleSQL ou
bigint chaves no PostgreSQL, o Spanner oferecerá o
objeto de esquema de sequência positiva invertida por bit (PostgreSQL ou
GoogleSQL).
Migrações
Para migrações de tabelas para o Spanner, você tem as seguintes opções:
- Se você estiver usando UUIDs no banco de dados de origem, no Spanner, poderá usar uma coluna de tipo UUID e a função UUID gerada (GoogleSQL ou PostgreSQL) como valor padrão.
- Se você estiver usando uma chave primária de números inteiros e o aplicativo só precisar que a chave seja exclusiva, use uma coluna de chave em
INT64e uma sequência positiva invertida por bit para o valor padrão da chave primária. Consulte Migrar colunas de chave invertidas por bit. - O Spanner não oferece suporte a uma maneira de gerar valores monotônicos.
Se você estiver usando uma chave monotônica, como o tipo
SERIALdo PostgreSQL ou o atributoAUTO_INCREMENTdo MySQL, e precisar de novas chaves monotônicas no Spanner, use uma chave composta. Para mais informações, consulte Trocar a ordem das chaves e Gerar o hash da chave exclusiva e espalhar as gravações em fragmentos lógicos. - Se o aplicativo estiver invertendo manualmente a chave
INT64em GoogleSQL ou a chavebigintem PostgreSQL, use uma sequência positiva invertida por bit (GoogleSQL ou PostgreSQL) e faça com que ela gere novos valores de chave para você. Para mais informações, consulte Migrar colunas de chave invertidas por bit.
A seguir
- Saiba mais sobre como usar sequências com controle de acesso refinado.
- Saiba mais sobre instruções DDL
SEQUENCEpara GoogleSQL ou PostgreSQL. - Saiba mais sobre funções de sequência no GoogleSQL ou PostgreSQL.
- Saiba mais sobre sequências no INFORMATION_SCHEMA em GoogleSQL ou PostgreSQL.
- Saiba mais sobre opções de sequência no INFORMATION_SCHEMA para GoogleSQL.