CREATE DOMAIN

CREATE DOMAIN — definir un nuevo dominio

Synopsis

CREATE DOMAIN name [ AS ] data_type
    [ COLLATE collation ]
    [ DEFAULT expression ]
    [ domain_constraint [ ... ] ]

donde domain_constraint es:

[ CONSTRAINT constraint_name ]
{ NOT NULL | NULL | CHECK (expression) }

Descripción

CREATE DOMAIN crea un nuevo dominio. Un dominio es esencialmente un tipo de datos con restricciones opcionales (restricciones sobre el conjunto de valores permitidos). El usuario que define un dominio se convierte en su propietario.

Si se proporciona un nombre de esquema (por ejemplo, CREATE DOMAIN myschema.mydomain ...), el dominio se crea en el esquema especificado. De lo contrario, se crea en el esquema actual. El nombre del dominio debe ser único entre los tipos y dominios existentes en su esquema.

Los dominios son útiles para abstraer restricciones comunes en los campos en un solo lugar para facilitar su mantenimiento. Por ejemplo, varias tablas podrían contener columnas de dirección de correo electrónico, y todas requerirían la misma restricción CHECK para verificar la sintaxis de la dirección. Definir un dominio es preferible a configurar la restricción de cada tabla de forma individual.

Para poder crear un dominio, debes tener el privilegio USAGE en el tipo subyacente.

Parámetros

name

El nombre (opcionalmente calificado por esquema) del dominio que se va a crear.

data_type

El tipo de datos subyacente del dominio. Puede incluir especificadores de matriz (array).

collation

Una colación (ordenación) opcional para el dominio. Si no se especifica ninguna colación, el dominio tiene el mismo comportamiento de colación que su tipo de datos subyacente. El tipo subyacente debe ser colacionable si se especifica COLLATE.

DEFAULT expression

La cláusula DEFAULT especifica un valor por defecto para las columnas del tipo de datos del dominio. El valor es cualquier expresión libre de variables (pero no se permiten subconsultas). El tipo de datos de la expresión por defecto debe coincidir con el tipo de datos del dominio. Si no se especifica ningún valor por defecto, entonces el valor por defecto es el valor nulo (null).

La expresión por defecto se utilizará en cualquier operación de inserción que no especifique un valor para la columna. Si se define un valor por defecto para una columna particular, anula cualquier valor por defecto asociado con el dominio. A su vez, el valor por defecto del dominio anula cualquier valor por defecto asociado con el tipo de datos subyacente.

CONSTRAINT constraint_name

Un nombre opcional para una restricción. Si no se especifica, el sistema genera un nombre.

NOT NULL

Evita que los valores de este dominio sean nulos (pero consulta las notas a continuación).

NULL

Permite que los valores de este dominio sean nulos. Este es el valor por defecto.

Esta cláusula solo está pensada para la compatibilidad con bases de datos SQL no estándar. Se desaconseja su uso en aplicaciones nuevas.

CHECK (expression)

Las cláusulas CHECK especifican restricciones de integridad o pruebas que los valores del dominio deben cumplir. Cada restricción debe ser una expresión que produzca un resultado booleano. Debe usar la palabra clave VALUE para referirse al valor que se está probando. Las expresiones que se evalúan como TRUE o UNKNOWN tienen éxito. Si la expresión produce un resultado FALSE, se informa de un error y no se permite que el valor se convierta al tipo de dominio.

Actualmente, las expresiones CHECK no pueden contener subconsultas ni hacer referencia a variables que no sean VALUE.

Cuando un dominio tiene múltiples restricciones CHECK, se probarán en orden alfabético por su nombre. (Las versiones de PostgreSQL anteriores a la 9.5 no respetaban ningún orden de disparo particular para las restricciones CHECK).

Notas

Las restricciones de dominio, particularmente NOT NULL, se comprueban al convertir un valor al tipo de dominio. Es posible que una columna que es nominalmente del tipo de dominio se lea como nula a pesar de existir tal restricción. Por ejemplo, esto puede suceder en una consulta de combinación externa (outer join), si la columna del dominio está en el lado anulable de la combinación externa. Un ejemplo más sutil es:

INSERT INTO tab (domcol) VALUES ((SELECT domcol FROM tab WHERE false));

La subconsulta SELECT escalar vacía producirá un valor nulo que se considera que es del tipo de dominio, por lo que no se aplica ninguna otra comprobación de restricciones sobre él, y la inserción tendrá éxito.

Es muy difícil evitar este tipo de problemas debido a la suposición general de SQL de que un valor nulo es un valor válido para cada tipo de datos. Por lo tanto, la mejor práctica es diseñar las restricciones de un dominio de manera que se permita un valor nulo, y luego aplicar restricciones NOT NULL a las columnas del tipo de dominio según sea necesario, en lugar de aplicarlas directamente al tipo de dominio.

PostgreSQL asume que las condiciones de las restricciones CHECK son inmutables, es decir, que siempre darán el mismo resultado para el mismo valor de entrada. Esta suposición es lo que justifica examinar las restricciones CHECK únicamente cuando un valor se convierte por primera vez a un tipo de dominio, y no en otros momentos. (Esto es esencialmente lo mismo que el tratamiento de las restricciones CHECK de tabla, como se describe en la Section 5.5.1).

Un ejemplo de una forma común de romper esta suposición es hacer referencia a una función definida por el usuario en una expresión CHECK, y luego cambiar el comportamiento de esa función. PostgreSQL no lo prohíbe, pero no notará si hay valores almacenados del tipo de dominio que ahora violan la restricción CHECK. Eso causaría que un volcado y restauración posterior de la base de datos falle. La forma recomendada de manejar tal cambio es eliminar la restricción (usando ALTER DOMAIN), ajustar la definición de la función y volver a añadir la restricción, volviendo a comprobarla contra los datos almacenados.

También es una buena práctica asegurarse de que las expresiones CHECK del dominio no lancen errores.

Ejemplos

Este ejemplo crea el tipo de datos us_postal_code y luego utiliza el tipo en la definición de una tabla. Se utiliza una prueba de expresión regular para verificar que el valor parece un código postal válido de los EE. UU.:

CREATE DOMAIN us_postal_code AS TEXT
CHECK(
   VALUE ~ '^\d{5}$'
OR VALUE ~ '^\d{5}-\d{4}$'
);

CREATE TABLE us_snail_addy (
  address_id SERIAL PRIMARY KEY,
  street1 TEXT NOT NULL,
  street2 TEXT,
  street3 TEXT,
  city TEXT NOT NULL,
  postal us_postal_code NOT NULL
);

Compatibilidad

El comando CREATE DOMAIN cumple con el estándar SQL.

La sintaxis NOT NULL en este comando es una extensión de PostgreSQL. (Una forma que cumple con el estándar para escribir lo mismo para tipos de datos no compuestos sería CHECK (VALUE IS NOT NULL). Sin embargo, según las the section called “Notas”, estas restricciones es mejor evitarlas en la práctica de todos modos). La «restricción» NULL es una extensión de PostgreSQL (consulta también la Compatibilidad).

Consulte también

ALTER DOMAIN, DROP DOMAIN