Esta página discute estratégias para gerar valores de chave primária na sua 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 pontos de acesso
- Simplifique migrações de outros bancos de dados
- Encapsule a lógica principal no banco de dados para não precisar se preocupar com o gerenciamento dela no aplicativo.
- Na maioria dos casos, substitui a necessidade de criar e gerenciar suas próprias sequências
Métodos para gerar automaticamente chaves primárias
Para gerar automaticamente valores de chave primária, use as seguintes estratégias em uma coluna com expressões DEFAULT:
- Uma função UUID que gera valores UUID versão 4.
- 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 uma string UUID versão 4 para usar como chave primária. Os UUIDs funcionam bem para novos aplicativos e tabelas com muitas linhas. Elas são distribuídas de forma aproximadamente uniforme no espaço de chaves, o que evita hotspots em grande escala. A geração de UUIDs 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 durante 86 anos. Isso garante valores exclusivos quando você usa em tabelas grandes. Os UUIDs são exclusivos, seja 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 em 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 de 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.
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 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 deixando o Spanner gerar 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 interna gerado automaticamente e inverte os bits do valor 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 colunas IDENTITY para criar uma coluna de chave primária inteira 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 a seguir, uma coluna de números inteiros gerada automaticamente é criada para SingerId,que tem valores positivos invertidos em bits 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 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 bits. 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 de DDL para colunas IDENTITY e são usados para criar colunas de números inteiros exclusivos. Primeiro, defina a opção de banco de dados default_sequence_kind 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 com bits invertidos
Uma sequência com bits invertidos é um objeto de esquema que produz uma sequência de números inteiros e inverte os bits deles. Esse objeto usa inversão de bits em um contador particular e interno do Spanner para garantir a exclusividade. Os valores invertidos em bits resultantes ajudam a evitar pontos de acesso em grande 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 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 inversã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 nextval do PostgreSQL como valor padrão, o Spanner chama automaticamente a função e coloca os valores de saída invertidos por bits na coluna. Sequências com bits invertidos são especialmente úteis para chaves primárias, porque os valores com bits invertidos são distribuídos uniformemente no espaço de chaves para não causar gargalos.
O exemplo a seguir mostra como criar uma sequência invertida por bits 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
Se o aplicativo atual exigir chaves INT64 no GoogleSQL ou chaves bigint no PostgreSQL, o Spanner vai oferecer o objeto de esquema de sequência positiva invertida por bits (PostgreSQL ou
GoogleSQL). Caso contrário, para novos aplicativos, recomendamos usar o 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:
- Se você estiver usando UUIDs no banco de dados de origem, no Spanner,
use uma coluna de chave no tipo
STRINGe a funçãoGENERATE_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
INT64e uma sequência positiva com bits invertidos para o valor padrão da chave primária. Consulte Migrar colunas de chaves com bits invertidos. O Spanner não oferece 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 única e espalhar as gravações em fragmentos lógicos.Se o aplicativo estiver invertendo manualmente os bits da chave
INT64no GoogleSQL ou da chavebigintno PostgreSQL, use uma sequência positiva invertida por bits (GoogleSQL ou PostgreSQL) para gerar novos valores de chave. Para mais informações, consulte Migrar colunas de chaves com bits invertidos.
A seguir
- Saiba mais sobre como usar sequências com controle de acesso refinado.
- Saiba mais sobre as instruções DDL
SEQUENCEpara GoogleSQL ou PostgreSQL. - Saiba mais sobre as funções de sequência no GoogleSQL ou no PostgreSQL.
- Saiba mais sobre sequências no INFORMATION_SCHEMA em GoogleSQL ou PostgreSQL.
- Saiba mais sobre as opções de sequência no INFORMATION_SCHEMA para GoogleSQL.