Valor padrão para a coluna UUID no Postgres

68

No Postgres 9.x, para uma coluna do tipo UUID, como especifico um UUID a ser gerado automaticamente como um valor padrão para qualquer inserção de linha?

Basil Bourque
fonte

Respostas:

94

tl; dr

Chame DEFAULTao definir uma coluna para chamar uma das funções uuid do OSSP . O servidor Postgres invocará automaticamente a função toda vez que uma linha for inserida.

CREATE TABLE tbl 
(
  pkey UUID NOT NULL DEFAULT uuid_generate_v1() , 
  CONSTRAINT pkey_tbl PRIMARY KEY ( pkey )
)

Se você já usa a extensão pgcrypto , considere a resposta bpieck .

Plug-in necessário para gerar UUID

Enquanto o Postgres pronto para uso suporta o armazenamento de valores UUID (Universally Unique Identifier) em seu formato nativo de 128 bits , a geração de valores UUID requer um plug-in. No Postgres, um plug-in é conhecido como extension.

Para instalar um ramal, ligue CREATE EXTENSION. Para evitar a reinstalação, adicione IF NOT EXISTS. Veja minha postagem no blog para obter mais detalhes ou consulte esta página no StackOverflow .

A extensão que queremos é uma biblioteca de código aberto criada em C para trabalhar com UUIDs, OSSP uuid . A compilação desta biblioteca para o Postgres é frequentemente empacotada com uma instalação do Postgres, como os instaladores gráficos fornecidos pelo Enterprise DB ou incluídos por provedores de nuvem como o Amazon RDS for PostgreSQL .

CREATE EXTENSION IF NOT EXISTS "uuid-ossp";

Gerando vários tipos de UUID

Consulte o documento da extensão para ver uma lista de vários comandos oferecidos para gerar vários tipos de valores UUID. Para obter a versão original do UUID criada a partir do endereço MAC do computador, além da data e hora atuais e de um pequeno valor aleatório, ligue uuid_generate_v1().

SELECT uuid_generate_v1();

672124b6-9894-11e5-be38-001d42e813fe

Variações posteriores sobre esse tema foram desenvolvidas para tipos alternativos de UUIDs. Algumas pessoas podem não querer registrar o endereço MAC real do servidor, por exemplo, por questões de segurança ou privacidade. A extensão do Postgres gera cinco tipos de UUIDs, mais o UUID "nulo" 00000000-0000-0000-0000-000000000000.

UUID como valor padrão

Essa chamada de método pode ser feita automaticamente para gerar um valor padrão para qualquer linha recém-inserida. Ao definir a coluna, especifique:

DEFAULT uuid_generate_v1()

Veja esse comando usado na seguinte definição de tabela de exemplo.

CREATE TABLE public.pet_
(
  species_ text NOT NULL,
  name_ text NOT NULL,
  date_of_birth_ text NOT NULL,
  uuid_ uuid NOT NULL DEFAULT uuid_generate_v1(),  -- <====
  CONSTRAINT pet_pkey_ PRIMARY KEY (uuid_)
)
WITH (
  OIDS=FALSE
);
ALTER TABLE public.pet_
  OWNER TO postgres;

Versões UUID

O plugin uuid-ossp pode gerar várias versões do UUID .

  • uuid_generate_v1()
    Contém o endereço MAC do computador atual + momento atual. Comumente usado, mas evite se você for sensível sobre a divulgação do MAC do servidor de banco de dados ou a hora em que esse valor foi gerado. Definido pela especificação como um UUID da Versão 1 .
  • uuid_generate_v1mc()
    Como a Versão 1 , mas com um endereço MAC multicast aleatório em vez do endereço MAC real. Aparentemente, é uma maneira de usar a Versão 1, mas substituindo outro MAC, em vez do MAC real do servidor de banco de dados, se você é sensível a divulgar esse fato.
    O que é um 'MAC multicast aleatório'? Eu não sei exatamente . Após ler a seção 4.1.6 da RFC 4122 , suspeito que este seja um número aleatório usado no lugar do MAC, mas com bits configurados para indicar um endereço MAC multicast em vez do unicast usual, de modo a distinguir essa variação da versão 1 de uma usual real-MAC versão 1 UUID.
  • uuid_generate_v3( namespace uuid, name text )
    Contém um hash de texto MD5 que você fornece. Definido pela especificação como um UUID Versão 3 , UUID baseado em namespace .
  • uuid_generate_v4()
    Com base em dados gerados aleatoriamente para 121-122 dos 128 bits. Seis ou sete bits usados ​​para indicar Versão e Variante. Esse tipo de UUID é prático apenas se implementado com um gerador aleatório criptograficamente forte . Definido pela especificação como um UUID da versão 4 .
  • uuid_generate_v5( namespace uuid, name text )
    Igual à versão 3, mas usando o hash SHA1 . Definido pela especificação como UUID da versão 5 .
  • uuid_nil()
    Um caso especial, todos os bits definidos como zero 00000000-0000-0000-0000-000000000000. Usado como um sinalizador para um valor UUID desconhecido. Conhecido como um UUID nulo .

Para comparar tipos, consulte a pergunta: qual versão do UUID usar?

Se você estiver curioso sobre as versões 3 e 5, consulte esta pergunta, Gerando U5 v5. O que é nome e espaço para nome? .

Para mais discussões, consulte minha resposta a uma pergunta semelhante e meu blog postar valores UUID do JDBC para o Postgres .

Basil Bourque
fonte
1.000.000 de ocorrências no Google para saber como criar colunas do tipo UUID. Zero hits para saber como enlouquecer linhas de consulta por esse pk !! : - @
Clint Eastwood
@ClintEastwood Minha resposta a uma pergunta semelhante e os valores UUID da postagem no blog do JDBC ao Postgres podem ajudá-lo. Se esses forem insuficientes, poste uma nova pergunta. Eu ficaria feliz em dar outra facada nele. Eu entendo sua frustração!
Basil Bourque
@ClintEastwood: a sintaxe para comparar uma coluna UUID com um valor segue a sintaxe das constantes documentadas no manual: postgresql.org/docs/current/static/… e digite casts: postgresql.org/docs/current/static/…
a_horse_with_no_name
11
@BasilBourque: Não é realmente necessário transmitir o resultado, getObject()você também pode usarUUID id = rs.getObject("uuid_", UUID.class);
a_horse_with_no_name
11
@Rokit Para verificar a força do gerador de números aleatórios, observe a implementação de código aberto subjacente envolvida por esta extensão do Postgres, o projeto de biblioteca uuid OSSP , conforme mencionado na minha resposta. E lembre-se, os UUIDs da versão 4 devem ser usados ​​apenas como último recurso, se por algum motivo você não puder escolher os outros tipos. Geralmente, sua primeira escolha deve ser do tipo Versão 1, chamando uuid_generate_v1ou uuid_generate_v1mc.
Basil Bourque 19/01
8

extensão pgcrypto

Apenas uma pequena adição à resposta muito detalhada de Basil:

Como atualmente a maioria está usando pgcrypto , em vez de uuid_generate_v1()você pode usar gen_random_uuid()para um valor UUID da versão 4 .

Primeiro, ative o pgcrypto no seu Postgres.

CREATE EXTENSION "pgcrypto";

Basta definir DEFAULT de uma coluna como DEFAULT gen_random_uuid()

bpieck
fonte