Valor predeterminado para la columna UUID en Postgres

68

En Postgres 9.x, para una columna de tipo UUID, ¿cómo especifico que se genere automáticamente un UUID como valor predeterminado para cualquier inserción de fila?

Albahaca Bourque
fuente

Respuestas:

94

tl; dr

Llame DEFAULTal definir una columna para invocar una de las funciones de uuid OSSP . El servidor Postgres invocará automáticamente la función cada vez que se inserte una fila.

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

Si ya usa la extensión pgcrypto , considere la Respuesta de bpieck .

Complemento requerido para generar UUID

Si bien Postgres es compatible con el almacenamiento de valores de UUID (identificador único universal) en su forma nativa de 128 bits , la generación de valores de UUID requiere un complemento. En Postgres, un complemento se conoce como extension.

Para instalar una extensión, llame CREATE EXTENSION. Para evitar la reinstalación, agregue IF NOT EXISTS. Vea mi publicación de blog para más detalles, o vea esta página en StackOverflow .

La extensión que queremos es una biblioteca de código abierto construida en C para trabajar con UUID, OSSP uuid . Una compilación de esta biblioteca para Postgres a menudo se incluye con una instalación de Postgres como los instaladores gráficos proporcionados por Enterprise DB o incluidos por proveedores en la nube como Amazon RDS para PostgreSQL .

CREATE EXTENSION IF NOT EXISTS "uuid-ossp";

Generando varios tipos de UUID

Consulte el documento de la extensión para ver una lista de múltiples comandos ofrecidos para generar varios tipos de valores UUID. Para obtener la versión original de UUID construida a partir de la dirección MAC de la computadora más la fecha y hora actual más un pequeño valor aleatorio, llame uuid_generate_v1().

SELECT uuid_generate_v1();

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

Las variaciones posteriores sobre este tema se desarrollaron para tipos alternativos de UUID. Es posible que algunas personas no quieran registrar la dirección MAC real del servidor, por ejemplo, por cuestiones de seguridad o privacidad. La extensión Postgres genera cinco tipos de UUID, más el UUID "nulo" 00000000-0000-0000-0000-000000000000.

UUID como valor predeterminado

Esa llamada al método se puede realizar automáticamente para generar un valor predeterminado para cualquier fila recién insertada. Al definir la columna, especifique:

DEFAULT uuid_generate_v1()

Vea ese comando usado en la siguiente definición de tabla de ejemplo.

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;

Versiones de UUID

El complemento uuid-ossp puede generar varias versiones de UUID .

  • uuid_generate_v1()
    Contiene la dirección MAC de la computadora actual + momento actual. De uso general, pero evite si es sensible acerca de revelar el MAC de su servidor de base de datos o la hora en que se generó este valor. Definido por especificación como un UUID de Versión 1 .
  • uuid_generate_v1mc()
    Al igual que la Versión 1 , pero con una dirección MAC de multidifusión aleatoria en lugar de la dirección MAC real. Aparentemente, es una forma de usar la Versión 1, pero sustituyendo otra MAC en lugar de la MAC real de su servidor de base de datos si es sensible a revelar ese hecho.
    ¿Qué es un 'MAC de multidifusión aleatorio'? No lo se exactamente . Después de leer la sección 4.1.6 de RFC 4122 , sospecho que este es un número aleatorio utilizado en lugar del MAC pero con bits configurados para indicar una dirección MAC de multidifusión en lugar de la unidifusión habitual para distinguir esta variación de la Versión 1 de una habitual real-MAC Versión 1 UUID.
  • uuid_generate_v3( namespace uuid, name text )
    Contiene un hash MD5 de texto que proporciona. Definido por la especificación como un UUID de la Versión 3 , UUID basado en el espacio de nombres .
  • uuid_generate_v4()
    Basado en datos generados aleatoriamente para 121-122 de los 128 bits. Seis o siete bits utilizados para indicar Versión y Variante. Este tipo de UUID es práctico solo si se implementa con un generador aleatorio criptográficamente fuerte . Definido por especificación como un UUID de Versión 4 .
  • uuid_generate_v5( namespace uuid, name text )
    Igual que la Versión 3 pero usando el hashing SHA1 . Definido por especificación como Versión 5 UUID .
  • uuid_nil()
    Un caso especial, todos los bits puestos a cero 00000000-0000-0000-0000-000000000000. Se usa como indicador de un valor de UUID desconocido. Conocido como un UUID nulo .

Para comparar los tipos, vea la pregunta, ¿Qué versión UUID para usar?

Si tiene curiosidad sobre las versiones 3 y 5, consulte esta pregunta, Generando v5 UUID. ¿Qué es el nombre y el espacio de nombres? .

Para obtener más información, consulte mi Respuesta a una pregunta similar y los valores de UUID de mi blog de JDBC a Postgres .

Albahaca Bourque
fuente
1,000,000 de visitas en Google sobre cómo crear columnas de tipo UUID. ¡Cero éxitos sobre cómo enloquecer filas de consultas por ese paquete! : - @
Clint Eastwood
@ClintEastwood Mi respuesta a una pregunta similar y los valores de UUID de mi blog de JDBC a Postgres pueden ayudarlo con eso. Si los resultados son insuficientes, publique una nueva pregunta. Me encantaría darle otra puñalada. Entiendo tu frustración!
Basil Bourque
@ClintEastwood: la sintaxis para comparar una columna UUID con un valor sigue la sintaxis de las constantes documentadas en el manual: postgresql.org/docs/current/static/… y type casts: postgresql.org/docs/current/static/…
a_horse_with_no_name
1
@BasilBourque: No es realmente necesario emitir el resultado getObject(), también puedes usarUUID id = rs.getObject("uuid_", UUID.class);
a_horse_with_no_name el
1
@Rokit Para verificar la fuerza del generador de números aleatorios, mire la implementación de código abierto subyacente que está envuelta por esta extensión de Postgres, el proyecto de biblioteca de uuid OSSP como se menciona en mi Respuesta. Y recuerde, los UUID de la Versión 4 deben usarse solo como último recurso, si por alguna razón no puede elegir los otros tipos. En general, su primera opción debe ser del tipo Versión 1, llamando a uuid_generate_v1o uuid_generate_v1mc.
Basil Bourque
8

extensión pgcrypto

Solo una pequeña adición a la respuesta muy detallada de Basil:

Como actualmente la mayoría usa pgcrypto , en lugar de uuid_generate_v1()usted puede usar gen_random_uuid()un valor de UUID de la Versión 4 .

Primero, habilite pgcrypto en sus Postgres.

CREATE EXTENSION "pgcrypto";

Simplemente establezca DEFAULT de una columna en DEFAULT gen_random_uuid()

bpieck
fuente