CREATE TABLE

CREATE TABLE — define una nueva tabla

Synopsis

CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXISTS ] nombre_tabla ( [
  { nombre_columna tipo_datos [ STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN | DEFAULT } ] [ COMPRESSION método_compresión ] [ COLLATE ordenación ] [ restricción_columna [ ... ] ]
    | restricción_tabla
    | LIKE tabla_origen [ opción_like ... ] }
    [, ... ]
] )
[ INHERITS ( tabla_padre [, ... ] ) ]
[ PARTITION BY { RANGE | LIST | HASH } ( { nombre_columna | ( expresión ) } [ COLLATE ordenación ] [ clase_op ] [, ... ] ) ]
[ USING método ]
[ WITH ( parámetro_almacenamiento [= valor] [, ... ] ) | WITHOUT OIDS ]
[ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]
[ TABLESPACE nombre_tablespace ]

CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXISTS ] nombre_tabla
    OF nombre_tipo [ (
  { nombre_columna [ WITH OPTIONS ] [ restricción_columna [ ... ] ]
    | restricción_tabla }
    [, ... ]
) ]
[ PARTITION BY { RANGE | LIST | HASH } ( { nombre_columna | ( expresión ) } [ COLLATE ordenación ] [ clase_op ] [, ... ] ) ]
[ USING método ]
[ WITH ( parámetro_almacenamiento [= valor] [, ... ] ) | WITHOUT OIDS ]
[ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]
[ TABLESPACE nombre_tablespace ]

CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXISTS ] nombre_tabla
    PARTITION OF tabla_padre [ (
  { nombre_columna [ WITH OPTIONS ] [ restricción_columna [ ... ] ]
    | restricción_tabla }
    [, ... ]
) ] { FOR VALUES especificación_límite_partición | DEFAULT }
[ PARTITION BY { RANGE | LIST | HASH } ( { nombre_columna | ( expresión ) } [ COLLATE ordenación ] [ clase_op ] [, ... ] ) ]
[ USING método ]
[ WITH ( parámetro_almacenamiento [= valor] [, ... ] ) | WITHOUT OIDS ]
[ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]
[ TABLESPACE nombre_tablespace ]

donde restricción_columna es:

[ CONSTRAINT nombre_restricción ]
{ NOT NULL [ NO INHERIT ]  |
  NULL |
  CHECK ( expresión ) [ NO INHERIT ] |
  DEFAULT expr_por_defecto |
  GENERATED ALWAYS AS ( expr_generación ) [ STORED | VIRTUAL ] |
  GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( opciones_secuencia ) ] |
  UNIQUE [ NULLS [ NOT ] DISTINCT ] parámetros_índice |
  PRIMARY KEY parámetros_índice |
  REFERENCES tabla_ref [ ( columna_ref ) ] [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ]
    [ ON DELETE acción_referencial ] [ ON UPDATE acción_referencial ] }
[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ] [ ENFORCED | NOT ENFORCED ]

y restricción_tabla es:

[ CONSTRAINT nombre_restricción ]
{ CHECK ( expresión ) [ NO INHERIT ] |
  NOT NULL nombre_columna [ NO INHERIT ] |
  UNIQUE [ NULLS [ NOT ] DISTINCT ] ( nombre_columna [, ... ] [, nombre_columna WITHOUT OVERLAPS ] ) parámetros_índice |
  PRIMARY KEY ( nombre_columna [, ... ] [, nombre_columna WITHOUT OVERLAPS ] ) parámetros_índice |
  EXCLUDE [ USING método_índice ] ( elemento_exclusión WITH operador [, ... ] ) parámetros_índice [ WHERE ( predicado ) ] |
  FOREIGN KEY ( nombre_columna [, ... ] [, PERIOD nombre_columna ] ) REFERENCES tabla_ref [ ( columna_ref [, ... ] [, PERIOD columna_ref ] ) ]
    [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE acción_referencial ] [ ON UPDATE acción_referencial ] }
[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ] [ ENFORCED | NOT ENFORCED ]

y opción_like es:

{ INCLUDING | EXCLUDING } { COMMENTS | COMPRESSION | CONSTRAINTS | DEFAULTS | GENERATED | IDENTITY | INDEXES | STATISTICS | STORAGE | ALL }

y especificación_límite_partición es:

IN ( expr_límite_partición [, ...] ) |
FROM ( { expr_límite_partición | MINVALUE | MAXVALUE } [, ...] )
  TO ( { expr_límite_partición | MINVALUE | MAXVALUE } [, ...] ) |
WITH ( MODULUS literal_numérico, REMAINDER literal_numérico )

los parámetros_índice en restricciones UNIQUE, PRIMARY KEY y EXCLUDE son:

[ INCLUDE ( nombre_columna [, ... ] ) ]
[ WITH ( parámetro_almacenamiento [= valor] [, ... ] ) ]
[ USING INDEX TABLESPACE nombre_tablespace ]

el elemento_exclusión en una restricción EXCLUDE es:

{ nombre_columna | ( expresión ) } [ COLLATE ordenación ] [ clase_op [ ( parámetro_clase_op = valor [, ... ] ) ] ] [ ASC | DESC ] [ NULLS { FIRST | LAST } ]

la acción_referencial en una restricción FOREIGN KEY/REFERENCES es:

{ NO ACTION | RESTRICT | CASCADE | SET NULL [ ( nombre_columna [, ... ] ) ] | SET DEFAULT [ ( nombre_columna [, ... ] ) ] }

Descripción

CREATE TABLE creará una nueva tabla, inicialmente vacía, en la base de datos actual. La tabla pertenecerá al usuario que emita el comando.

Si se proporciona un nombre de esquema (por ejemplo, CREATE TABLE miesquema.mitabla ...), la tabla se creará en el esquema especificado. De lo contrario, se creará en el esquema actual. Las tablas temporales existen en un esquema especial, por lo que no se puede proporcionar un nombre de esquema al crear una tabla temporal. El nombre de la tabla debe ser distinto del nombre de cualquier otra relación (tabla, secuencia, índice, vista, vista materializada o tabla foránea) en el mismo esquema.

CREATE TABLE también crea automáticamente un tipo de datos que representa el tipo compuesto correspondiente a una fila de la tabla. Por lo tanto, las tablas no pueden tener el mismo nombre que cualquier tipo de datos existente en el mismo esquema.

Las cláusulas opcionales de restricción especifican restricciones (pruebas) que las filas nuevas o actualizadas deben cumplir para que una operación de inserción o actualización tenga éxito. Una restricción es un objeto SQL que ayuda a definir el conjunto de valores válidos en la tabla de diversas maneras.

Hay dos formas de definir restricciones: restricciones de tabla y restricciones de columna. Una restricción de columna se define como parte de la definición de una columna. La definición de una restricción de tabla no está ligada a una columna en particular y puede abarcar más de una columna. Cada restricción de columna también se puede escribir como una restricción de tabla; una restricción de columna es solo una conveniencia notacional para usar cuando la restricción solo afecta a una columna.

Para poder crear una tabla, debes tener el privilegio USAGE en todos los tipos de columna o en el tipo de la cláusula OF, respectivamente.

Parámetros

TEMPORARY o TEMP #

Si se especifica, la tabla se crea como una tabla temporal. Las tablas temporales se eliminan automáticamente al final de una sesión, o opcionalmente al final de la transacción actual (consulta ON COMMIT más abajo). El search_path por defecto incluye primero el esquema temporal, por lo que las tablas permanentes existentes con el mismo nombre no se eligen para nuevos planes mientras exista la tabla temporal, a menos que se haga referencia a ellas con nombres calificados por esquema. Cualquier índice creado en una tabla temporal también es automáticamente temporal.

El demonio de autovacuum no puede acceder y, por lo tanto, no puede realizar vacuum o analyze en tablas temporales. Por esta razón, se deben realizar las operaciones de vacuum y analyze apropiadas mediante comandos SQL de sesión. Por ejemplo, si se va a utilizar una tabla temporal en consultas complejas, es aconsejable ejecutar ANALYZE en la tabla temporal después de que se haya llenado de datos.

Opcionalmente, se puede escribir GLOBAL o LOCAL antes de TEMPORARY o TEMP. Actualmente esto no hace ninguna diferencia en PostgreSQL y está obsoleto; consulta Compatibilidad más abajo.

UNLOGGED #

Si se especifica, la tabla se crea como una tabla no registrada (unlogged). Los datos escritos en tablas no registradas no se escriben en el registro de escritura anticipada (WAL, consulta Chapter 28), lo que las hace considerablemente más rápidas que las tablas ordinarias. Sin embargo, no son seguras ante caídas: una tabla no registrada se trunca automáticamente después de una caída o un apagado no limpio. El contenido de una tabla no registrada tampoco se replica a los servidores en espera (standbys). Cualquier índice creado en una tabla no registrada también es automáticamente no registrado.

Si se especifica esto, cualquier secuencia creada junto con la tabla no registrada (para columnas identity o serial) también se crea como no registrada.

Esta forma no es compatible con tablas particionadas.

IF NOT EXISTS #

No arroja un error si ya existe una relación con el mismo nombre. En este caso se emite una advertencia. Ten en cuenta que no hay garantía de que la relación existente sea similar a la que se habría creado.

nombre_tabla #

El nombre (opcionalmente calificado por esquema) de la tabla a crear.

OF nombre_tipo #

Crea una tabla tipada, que toma su estructura del tipo compuesto independiente especificado (es decir, uno creado usando CREATE TYPE) aunque también produce un nuevo tipo compuesto. La tabla tendrá una dependencia del tipo referenciado, lo que significa que las acciones alter y drop en cascada en ese tipo se propagarán a la tabla.

Una tabla tipada siempre tiene los mismos nombres de columna y tipos de datos que el tipo del que se deriva, por lo que no puedes especificar columnas adicionales. Pero el comando CREATE TABLE puede añadir valores por defecto y restricciones a la tabla, así como especificar parámetros de almacenamiento.

nombre_columna #

El nombre de una columna que se va a crear en la nueva tabla.

tipo_datos #

El tipo de datos de la columna. Esto puede incluir especificadores de array. Para obtener más información sobre los tipos de datos compatibles con PostgreSQL, consulta Chapter 8.

COLLATE ordenación #

La cláusula COLLATE asigna una ordenación a la columna (que debe ser de un tipo de datos ordenable). Si no se especifica, se utiliza la ordenación por defecto del tipo de datos de la columna.

STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN | DEFAULT } #

Esta forma establece el modo de almacenamiento para la columna. Esto controla si esta columna se mantiene en línea (inline) o en una tabla secundaria TOAST, y si los datos deben comprimirse o no. PLAIN debe usarse para valores de longitud fija como integer y es en línea, sin comprimir. MAIN es para datos en línea y comprimibles. EXTERNAL es para datos externos y sin comprimir, y EXTENDED es para datos externos y comprimidos. Escribir DEFAULT establece el modo de almacenamiento al modo por defecto para el tipo de datos de la columna. EXTENDED es el valor por defecto para la mayoría de los tipos de datos que admiten almacenamiento que no sea PLAIN. El uso de EXTERNAL hará que las operaciones de subcadena en valores text y bytea muy grandes se ejecuten más rápido, a costa de un mayor espacio de almacenamiento. Consulta Section 66.2 para obtener más información.

COMPRESSION método_compresión #

La cláusula COMPRESSION establece el método de compresión para la columna. La compresión es compatible solo para tipos de datos de ancho variable, y se usa solo cuando el modo de almacenamiento de la columna es main o extended. (Consulta ALTER TABLE para obtener información sobre los modos de almacenamiento de columnas.) Establecer esta propiedad para una tabla particionada no tiene un efecto directo, porque tales tablas no tienen almacenamiento propio, pero el valor configurado será heredado por las particiones recién creadas. Los métodos de compresión admitidos son pglz y lz4. (lz4 está disponible solo si se usó la opción --with-lz4 al construir PostgreSQL.) Además, método_compresión puede ser default para especificar explícitamente el comportamiento por defecto, que consiste en consultar el parámetro de configuración default_toast_compression en el momento de la inserción de datos para determinar el método a utilizar.

INHERITS ( tabla_padre [, ... ] ) #

La cláusula opcional INHERITS especifica una lista de tablas de las cuales la nueva tabla hereda automáticamente todas las columnas. Las tablas padre pueden ser tablas ordinarias o tablas foráneas.

El uso de INHERITS crea una relación persistente entre la nueva tabla hija y su(s) tabla(s) padre. Las modificaciones de esquema en las tablas padre normalmente también se propagan a las hijas, y por defecto los datos de la tabla hija se incluyen en los escaneos de las tablas padre.

Si existe el mismo nombre de columna en más de una tabla padre, se reporta un error a menos que los tipos de datos de las columnas coincidan en cada una de las tablas padre. Si no hay conflicto, las columnas duplicadas se fusionan para formar una sola columna en la nueva tabla. Si la lista de nombres de columna de la nueva tabla contiene un nombre de columna que también es heredado, el tipo de datos también debe coincidir con la(s) columna(s) heredada(s), y las definiciones de las columnas se fusionan en una sola. Si la nueva tabla especifica explícitamente un valor por defecto para la columna, este valor por defecto anula cualquier valor por defecto de las declaraciones heredadas de la columna. De lo contrario, cualquier padre que especifique valores por defecto para la columna debe especificar el mismo valor por defecto, o de lo contrario se reportará un error.

Las restricciones CHECK se fusionan esencialmente de la misma manera que las columnas: si varias tablas padre y/o la definición de la nueva tabla contienen restricciones CHECK con el mismo nombre, estas restricciones deben tener todas la misma expresión de comprobación, o de lo contrario se reportará un error. Las restricciones que tengan el mismo nombre y expresión se fusionarán en una sola copia. No se considerará una restricción marcada como NO INHERIT en un padre. Ten en cuenta que una restricción CHECK sin nombre en la nueva tabla nunca se fusionará, ya que siempre se elegirá un nombre único para ella.

La configuración de STORAGE de las columnas también se copia de las tablas padre.

Si una columna en la tabla padre es una columna de identidad, esa propiedad no se hereda. Una columna en la tabla hija puede declararse como columna de identidad si se desea.

PARTITION BY { RANGE | LIST | HASH } ( { nombre_columna | ( expresión ) } [ clase_op ] [, ...] ) #

La cláusula opcional PARTITION BY especifica una estrategia de particionamiento para la tabla. La tabla así creada se denomina tabla particionada. La lista entre paréntesis de columnas o expresiones forma la clave de partición de la tabla. Al utilizar particionamiento por rango o hash, la clave de partición puede incluir varias columnas o expresiones (hasta 32, pero este límite se puede modificar al construir PostgreSQL), pero para el particionamiento por lista, la clave de partición debe consistir en una sola columna o expresión.

El particionamiento por rango y lista requiere una clase de operador btree, mientras que el particionamiento hash requiere una clase de operador hash. Si no se especifica explícitamente una clase de operador, se utilizará la clase de operador por defecto del tipo apropiado; si no existe una clase de operador por defecto, se producirá un error. Cuando se utiliza particionamiento hash, la clase de operador utilizada debe implementar la función de soporte 2 (consulta Section 36.16.3 para obtener detalles).

Una tabla particionada se divide en subtablas (llamadas particiones), que se crean mediante comandos CREATE TABLE independientes. La tabla particionada en sí está vacía. Una fila de datos insertada en la tabla se enruta a una partición en función del valor de las columnas o expresiones en la clave de partición. Si ninguna partición existente coincide con los valores de la nueva fila, se reportará un error.

Consulta Section 5.12 para obtener más información sobre el particionamiento de tablas.

PARTITION OF tabla_padre { FOR VALUES especificación_límite_partición | DEFAULT } #

Crea la tabla como una partición de la tabla padre especificada. La tabla se puede crear como una partición para valores específicos usando FOR VALUES o como una partición por defecto usando DEFAULT. Cualquier índice, restricción y disparador (trigger) a nivel de fila definido por el usuario que exista en la tabla padre se clonará en la nueva partición.

La especificación_límite_partición debe corresponder al método de particionamiento y a la clave de partición de la tabla padre, y no debe superponerse con ninguna partición existente de ese padre. La forma con IN se utiliza para el particionamiento por lista, la forma con FROM y TO se utiliza para el particionamiento por rango, y la forma con WITH se utiliza para el particionamiento hash.

expr_límite_partición es cualquier expresión libre de variables (no se permiten subconsultas, funciones de ventana, funciones agregadas ni funciones que devuelven conjuntos). Su tipo de datos debe coincidir con el tipo de datos de la columna de la clave de partición correspondiente. La expresión se evalúa una vez en el momento de la creación de la tabla, por lo que incluso puede contener expresiones volátiles como CURRENT_TIMESTAMP.

Al crear una partición por lista, se puede especificar NULL para indicar que la partición permite que la columna de la clave de partición sea nula. Sin embargo, no puede haber más de una partición por lista de este tipo para una tabla padre determinada. No se puede especificar NULL para particiones por rango.

Al crear una partición por rango, el límite inferior especificado con FROM es un límite inclusivo, mientras que el límite superior especificado con TO es un límite exclusivo. Es decir, los valores especificados en la lista FROM son valores válidos de las columnas de la clave de partición correspondiente para esta partición, mientras que los de la lista TO no lo son. Ten en cuenta que esta afirmación debe entenderse de acuerdo con las reglas de comparación por filas (Section 9.25.5). Por ejemplo, dado PARTITION BY RANGE (x,y), un límite de partición FROM (1, 2) TO (3, 4) permite x=1 con cualquier y>=2, x=2 con cualquier y que no sea nulo, y x=3 con cualquier y<4.

Los valores especiales MINVALUE y MAXVALUE se pueden utilizar al crear una partición por rango para indicar que no hay un límite inferior o superior en el valor de la columna. Por ejemplo, una partición definida usando FROM (MINVALUE) TO (10) permite cualquier valor menor que 10, y una partición definida usando FROM (10) TO (MAXVALUE) permite cualquier valor mayor o igual a 10.

Al crear una partición por rango que involucra más de una columna, también puede tener sentido utilizar MAXVALUE como parte del límite inferior, y MINVALUE como parte del límite superior. Por ejemplo, una partición definida usando FROM (0, MAXVALUE) TO (10, MAXVALUE) permite cualquier fila donde la primera columna de la clave de partición sea mayor que 0 y menor o igual a 10. Del mismo modo, una partición definida usando FROM ('a', MINVALUE) TO ('b', MINVALUE) permite cualquier fila donde la primera columna de la clave de partición comience con "a".

Ten en cuenta que si se utiliza MINVALUE o MAXVALUE para una columna de un límite de particionamiento, se debe utilizar el mismo valor para todas las columnas siguientes. Por ejemplo, (10, MINVALUE, 0) no es un límite válido; debes escribir (10, MINVALUE, MINVALUE).

También ten en cuenta que algunos tipos de elementos, como timestamp, tienen una noción de "infinito", que es simplemente otro valor que se puede almacenar. Esto es diferente de MINVALUE y MAXVALUE, que no son valores reales que se puedan almacenar, sino formas de decir que el valor no tiene límites. Se puede pensar en MAXVALUE como mayor que cualquier otro valor, incluido "infinito", y en MINVALUE como menor que cualquier otro valor, incluido "menos infinito". Así, el rango FROM ('infinity') TO (MAXVALUE) no es un rango vacío; permite almacenar exactamente un valor: "infinito".

Si se especifica DEFAULT, la tabla se creará como la partición por defecto de la tabla padre. Esta opción no está disponible para tablas particionadas por hash. Un valor de clave de partición que no encaje en ninguna otra partición del padre dado se enrutará a la partición por defecto.

Cuando una tabla tiene una partición DEFAULT existente y se le añade una nueva partición, la partición por defecto debe escanearse para verificar que no contiene ninguna fila que corresponda propiamente a la nueva partición. Si la partición por defecto contiene un gran número de filas, esto puede ser lento. El escaneo se omitirá si la partición por defecto es una tabla foránea o si tiene una restricción que demuestre que no puede contener filas que deban colocarse en la nueva partición.

Al crear una partición hash, se debe especificar un módulo y un resto. El módulo debe ser un entero positivo y el resto debe ser un entero no negativo menor que el módulo. Normalmente, al configurar inicialmente una tabla particionada por hash, debes elegir un módulo igual al número de particiones y asignar a cada tabla el mismo módulo y un resto diferente (consulta los ejemplos más abajo). Sin embargo, no es necesario que cada partición tenga el mismo módulo, solo que cada módulo que ocurra entre las particiones de una tabla particionada por hash sea un factor del siguiente módulo más grande. Esto permite aumentar el número de particiones de forma incremental sin necesidad de mover todos los datos a la vez. Por ejemplo, supón que tienes una tabla particionada por hash con 8 particiones, cada una de las cuales tiene un módulo de 8, pero consideras necesario aumentar el número de particiones a 16. Puedes desacoplar una de las particiones con módulo 8, crear dos nuevas particiones con módulo 16 que cubran la misma parte del espacio de claves (una con un resto igual al resto de la partición desacoplada y la otra con un resto igual a ese valor más 8), y volver a llenarlas con datos. Luego puedes repetir esto, tal vez más adelante, para cada partición con módulo 8 hasta que no quede ninguna. Aunque esto todavía puede implicar un gran movimiento de datos en cada paso, sigue siendo mejor que tener que crear una tabla completamente nueva y mover todos los datos a la vez.

Una partición debe tener los mismos nombres y tipos de columnas que la tabla particionada a la que pertenece. Las modificaciones en los nombres o tipos de columna de una tabla particionada se propagarán automáticamente a todas sus particiones. Las restricciones CHECK serán heredadas automáticamente por cada partición, pero una partición individual puede especificar restricciones CHECK adicionales; las restricciones adicionales con el mismo nombre y condición que en el padre se fusionarán con la restricción del padre. Los valores por defecto se pueden especificar por separado para cada partición. Pero ten en cuenta que el valor por defecto de una partición no se aplica al insertar una fila a través de una tabla particionada.

Las filas insertadas en una tabla particionada se enrutarán automáticamente a la partición correcta. Si no existe una partición adecuada, se producirá un error.

Las operaciones como TRUNCATE que normalmente afectan a una tabla y a todos sus hijos heredados se aplicarán en cascada a todas las particiones, pero también se pueden realizar en una partición individual.

Ten en cuenta que la creación de una partición mediante PARTITION OF requiere adquirir un bloqueo ACCESS EXCLUSIVE en la tabla particionada padre. Del mismo modo, la eliminación de una partición con DROP TABLE requiere adquirir un bloqueo ACCESS EXCLUSIVE en la tabla padre. Es posible utilizar ALTER TABLE ATTACH/DETACH PARTITION para realizar estas operaciones con un bloqueo más débil, reduciendo así la interferencia con operaciones concurrentes en la tabla particionada.

LIKE tabla_origen [ opción_like ... ] #

La cláusula LIKE especifica una tabla de la cual la nueva tabla copia automáticamente todos los nombres de columna, sus tipos de datos y sus restricciones de no nulidad.

A diferencia de INHERITS, la nueva tabla y la tabla original quedan completamente desacopladas una vez finalizada la creación. Los cambios en la tabla original no se aplicarán a la nueva tabla, y no es posible incluir datos de la nueva tabla en los escaneos de la tabla original.

También a diferencia de INHERITS, las columnas y restricciones copiadas por LIKE no se fusionan con columnas y restricciones de nombre similar. Si se especifica el mismo nombre explícitamente o en otra cláusula LIKE, se señala un error.

Las cláusulas opcionales opción_like especifican qué propiedades adicionales de la tabla original se deben copiar. Especificar INCLUDING copia la propiedad, mientras que especificar EXCLUDING la omite. EXCLUDING es el comportamiento por defecto. Si se realizan varias especificaciones para el mismo tipo de objeto, se utiliza la última. Las opciones disponibles son:

INCLUDING COMMENTS #

Se copiarán los comentarios de las columnas copiadas, restricciones de verificación, restricciones de no nulidad, índices y estadísticas extendidas. El comportamiento por defecto es excluir los comentarios, lo que resulta en que los objetos correspondientes en la nueva tabla no tengan comentarios.

INCLUDING COMPRESSION #

Se copiará el método de compresión de las columnas. El comportamiento por defecto es excluir los métodos de compresión, lo que resulta en que las columnas tengan el método de compresión por defecto.

INCLUDING CONSTRAINTS #

Se copiarán las restricciones CHECK. No se hace distinción entre restricciones de columna y restricciones de tabla. Las restricciones de no nulidad siempre se copian a la nueva tabla.

INCLUDING DEFAULTS #

Se copiarán las expresiones por defecto para las definiciones de columna copiadas. De lo contrario, las expresiones por defecto no se copian, lo que resulta en que las columnas copiadas en la nueva tabla tengan valores por defecto nulos. Ten en cuenta que copiar valores por defecto que llaman a funciones de modificación de la base de datos, como nextval, puede crear un vínculo funcional entre la tabla original y la nueva.

INCLUDING GENERATED #

Se copiará cualquier expresión de generación, así como la elección de almacenada/virtual de las definiciones de columna copiadas. Por defecto, las nuevas columnas serán columnas base regulares.

INCLUDING IDENTITY #

Se copiará cualquier especificación de identidad de las definiciones de columna copiadas. Se crea una nueva secuencia para cada columna de identidad de la nueva tabla, independiente de las secuencias asociadas con la tabla antigua.

INCLUDING INDEXES #

Los índices y las restricciones PRIMARY KEY, UNIQUE y EXCLUDE de la tabla original se crearán en la nueva tabla. Los nombres para los nuevos índices y restricciones se eligen de acuerdo con las reglas por defecto, independientemente de cómo se llamaran los originales. (Este comportamiento evita posibles fallas por nombres duplicados para los nuevos índices).

INCLUDING STATISTICS #

Las estadísticas extendidas se copian a la nueva tabla.

INCLUDING STORAGE #

Se copiará la configuración de STORAGE para las definiciones de columna copiadas. El comportamiento por defecto es excluir la configuración de STORAGE, lo que resulta en que las columnas copiadas en la nueva tabla tengan configuraciones por defecto específicas del tipo. Para obtener más información sobre la configuración de STORAGE, consulta Section 66.2.

INCLUDING ALL #

INCLUDING ALL es una forma abreviada que selecciona todas las opciones individuales disponibles. (Podría ser útil escribir cláusulas EXCLUDING individuales después de INCLUDING ALL para seleccionar todas menos algunas opciones específicas).

La cláusula LIKE también se puede usar para copiar definiciones de columna de vistas, tablas foráneas o tipos compuestos. Las opciones inaplicables (por ejemplo, INCLUDING INDEXES de una vista) se ignoran.

CONSTRAINT nombre_restricción #

Un nombre opcional para una restricción de columna o tabla. Si se viola la restricción, el nombre de la restricción está presente en los mensajes de error, por lo que se pueden utilizar nombres de restricción como col must be positive para comunicar información útil sobre la restricción a las aplicaciones cliente. (Se necesitan comillas dobles para especificar nombres de restricción que contengan espacios). Si no se especifica un nombre de restricción, el sistema genera uno.

NOT NULL [ NO INHERIT ] #

La columna no puede contener valores nulos.

Una restricción marcada con NO INHERIT no se propagará a las tablas hijas.

NULL #

La columna puede contener valores nulos. Este es el comportamiento por defecto.

Esta cláusula se proporciona únicamente para compatibilidad con bases de datos SQL no estándar. Se desaconseja su uso en nuevas aplicaciones.

CHECK ( expresión ) [ NO INHERIT ] #

La cláusula CHECK especifica una expresión que produce un resultado booleano que las filas nuevas o actualizadas deben cumplir para que una operación de inserción o actualización tenga éxito. Las expresiones que evalúan a TRUE o UNKNOWN tienen éxito. Si alguna fila de una operación de inserción o actualización produce un resultado FALSE, se genera una excepción de error y la inserción o actualización no altera la base de datos. Una restricción de verificación especificada como una restricción de columna debe hacer referencia únicamente al valor de esa columna, mientras que una expresión que aparece en una restricción de tabla puede hacer referencia a varias columnas.

Actualmente, las expresiones CHECK no pueden contener subconsultas ni hacer referencia a variables que no sean columnas de la fila actual (consulta Section 5.5.1). Se puede hacer referencia a la columna del sistema tableoid, pero no a ninguna otra columna del sistema.

Una restricción marcada con NO INHERIT no se propagará a las tablas hijas.

Cuando una tabla tiene varias restricciones CHECK, se probarán para cada fila en orden alfabético por nombre, después de verificar las restricciones NOT NULL. (Las versiones de PostgreSQL anteriores a la 9.5 no respetaban ningún orden de ejecución particular para las restricciones CHECK).

DEFAULT expr_por_defecto #

La cláusula DEFAULT asigna un valor de datos por defecto para la columna en cuya definición aparece. El valor es cualquier expresión libre de variables (en particular, no se permiten referencias cruzadas a otras columnas de la tabla actual). Tampoco se permiten subconsultas. El tipo de datos de la expresión por defecto debe coincidir con el tipo de datos de la columna.

La expresión por defecto se utilizará en cualquier operación de inserción que no especifique un valor para la columna. Si no hay un valor por defecto para una columna, el valor por defecto es nulo.

GENERATED ALWAYS AS ( expr_generación ) [ STORED | VIRTUAL ] #

Esta cláusula crea la columna como una columna generada. No se puede escribir en la columna, y al leerla se devolverá el resultado de la expresión especificada.

Cuando se especifica VIRTUAL, la columna se calculará cuando se lea y no ocupará almacenamiento. Cuando se especifica STORED, la columna se calculará en la escritura y se almacenará en el disco. VIRTUAL es el comportamiento por defecto.

La expresión de generación puede hacer referencia a otras columnas de la tabla, pero no a otras columnas generadas. Todas las funciones y operadores utilizados deben ser inmutables. No se permiten referencias a otras tablas.

Una columna generada virtual no puede tener un tipo definido por el usuario, y la expresión de generación de una columna generada virtual no debe hacer referencia a funciones o tipos definidos por el usuario, es decir, solo puede usar funciones o tipos incorporados. Esto se aplica también indirectamente, como para funciones o tipos que subyacen a operadores o conversiones (casts). (Esta restricción no existe para las columnas generadas almacenadas).

GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( opciones_secuencia ) ] #

Esta cláusula crea la columna como una columna de identidad. Tendrá una secuencia implícita asociada y, en las filas recién insertadas, la columna tendrá automáticamente valores asignados a partir de esa secuencia. Dicha columna es implícitamente NOT NULL.

Las cláusulas ALWAYS y BY DEFAULT determinan cómo se manejan los valores especificados explícitamente por el usuario en los comandos INSERT y UPDATE.

En un comando INSERT, si se selecciona ALWAYS, se acepta un valor especificado por el usuario solo si la sentencia INSERT especifica OVERRIDING SYSTEM VALUE. Si se selecciona BY DEFAULT, el valor especificado por el usuario tiene prioridad. Consulta INSERT para obtener detalles. (En el comando COPY, los valores especificados por el usuario siempre se utilizan independientemente de esta configuración).

En un comando UPDATE, si se selecciona ALWAYS, se rechazará cualquier actualización de la columna a cualquier valor que no sea DEFAULT. Si se selecciona BY DEFAULT, la columna se puede actualizar normalmente. (No hay una cláusula OVERRIDING para el comando UPDATE).

La cláusula opcional opciones_secuencia se puede utilizar para anular los parámetros de la secuencia. Las opciones disponibles incluyen las que se muestran para CREATE SEQUENCE, más SEQUENCE NAME nombre, LOGGED y UNLOGGED, que permiten la selección del nombre y el nivel de persistencia de la secuencia. Sin SEQUENCE NAME, el sistema elige un nombre no utilizado para la secuencia. Sin LOGGED o UNLOGGED, la secuencia tendrá el mismo nivel de persistencia que la tabla.

UNIQUE [ NULLS [ NOT ] DISTINCT ] (restricción de columna)
UNIQUE [ NULLS [ NOT ] DISTINCT ] ( nombre_columna [, ... ] [, nombre_columna WITHOUT OVERLAPS ] ) [ INCLUDE ( nombre_columna [, ...]) ] (restricción de tabla) #

La restricción UNIQUE especifica que un grupo de una o más columnas de una tabla puede contener únicamente valores únicos. El comportamiento de una restricción de tabla única es el mismo que el de una restricción de columna única, con la capacidad adicional de abarcar varias columnas. Por lo tanto, la restricción exige que dos filas cualesquiera difieran en al menos una de estas columnas.

Si se especifica la opción WITHOUT OVERLAPS para la última columna, se comprueba que esa columna no tenga superposiciones en lugar de comprobar la igualdad. En ese caso, las otras columnas de la restricción permitirán duplicados siempre que los duplicados no se superpongan en la columna WITHOUT OVERLAPS. (A esto a veces se le llama clave temporal, si la columna es un rango de fechas o marcas de tiempo, pero PostgreSQL permite rangos sobre cualquier tipo base). En efecto, tal restricción se aplica con una restricción EXCLUDE en lugar de una restricción UNIQUE. Por ejemplo, UNIQUE (id, valid_at WITHOUT OVERLAPS) se comporta como EXCLUDE USING GIST (id WITH =, valid_at WITH &&). La columna WITHOUT OVERLAPS debe tener un tipo de rango o multirango. No se permiten rangos o multirangos vacíos. Las columnas que no son WITHOUT OVERLAPS de la restricción pueden ser de cualquier tipo que se pueda comparar por igualdad en un índice GiST. Por defecto, solo se admiten tipos de rango, pero puedes usar otros tipos agregando la extensión btree_gist (que es la forma esperada de usar esta característica).

A efectos de una restricción única, los valores nulos no se consideran iguales, a menos que se especifique NULLS NOT DISTINCT.

Cada restricción única debe nombrar un conjunto de columnas que sea diferente del conjunto de columnas nombrado por cualquier otra restricción única o de clave primaria definida para la tabla. (De lo contrario, las restricciones únicas redundantes se descartarán).

Al establecer una restricción única para una jerarquía de particiones de varios niveles, todas las columnas de la clave de partición de la tabla particionada objetivo, así como las de todas sus tablas particionadas descendientes, deben incluirse en la definición de la restricción.

Agregar una restricción única creará automáticamente un índice btree único en la columna o grupo de columnas utilizado en la restricción. Pero si la restricción incluye una cláusula WITHOUT OVERLAPS, utilizará un índice GiST. El índice creado tiene el mismo nombre que la restricción única.

La cláusula opcional INCLUDE agrega a ese índice una o más columnas que son simplemente carga útil (payload): no se exige unicidad sobre ellas, y el índice no se puede buscar sobre la base de esas columnas. Sin embargo, se pueden recuperar mediante un escaneo solo de índice (index-only scan). Ten en cuenta que aunque la restricción no se aplica a las columnas incluidas, sigue dependiendo de ellas. En consecuencia, algunas operaciones en tales columnas (por ejemplo, DROP COLUMN) pueden causar la eliminación en cascada de la restricción y del índice.

PRIMARY KEY (restricción de columna)
PRIMARY KEY ( nombre_columna [, ... ] [, nombre_columna WITHOUT OVERLAPS ] ) [ INCLUDE ( nombre_columna [, ...]) ] (restricción de tabla) #

La restricción PRIMARY KEY especifica que una columna o columnas de una tabla pueden contener únicamente valores únicos (no duplicados) y no nulos. Solo se puede especificar una clave primaria para una tabla, ya sea como una restricción de columna o como una restricción de tabla.

La restricción de clave primaria debe nombrar un conjunto de columnas que sea diferente del conjunto de columnas nombrado por cualquier restricción única definida para la misma tabla. (De lo contrario, la restricción única es redundante y se descartará).

PRIMARY KEY impone las mismas restricciones de datos que una combinación de UNIQUE y NOT NULL. Sin embargo, identificar un conjunto de columnas como clave primaria también proporciona metadatos sobre el diseño del esquema, ya que una clave primaria implica que otras tablas pueden confiar en este conjunto de columnas como identificador único para las filas.

Cuando se colocan en una tabla particionada, las restricciones PRIMARY KEY comparten las restricciones descritas anteriormente para las restricciones UNIQUE.

Agregar una restricción PRIMARY KEY creará automáticamente un índice btree único en la columna o grupo de columnas utilizado en la restricción, o GiST si se especificó WITHOUT OVERLAPS.

La cláusula opcional INCLUDE agrega a ese índice una o más columnas que son simplemente carga útil (payload): no se exige unicidad sobre ellas, y el índice no se puede buscar sobre la base de esas columnas. Sin embargo, se pueden recuperar mediante un escaneo solo de índice. Ten en cuenta que aunque la restricción no se aplica a las columnas incluidas, sigue dependiendo de ellas. En consecuencia, algunas operaciones en tales columnas (por ejemplo, DROP COLUMN) pueden causar la eliminación en cascada de la restricción y del índice.

EXCLUDE [ USING método_índice ] ( elemento_exclusión WITH operador [, ... ] ) parámetros_índice [ WHERE ( predicado ) ] #

La cláusula EXCLUDE define una restricción de exclusión, que garantiza que si se comparan dos filas cualesquiera en las columnas o expresiones especificadas utilizando los operadores especificados, no todas estas comparaciones devolverán TRUE. Si todos los operadores especificados prueban la igualdad, esto es equivalente a una restricción UNIQUE, aunque una restricción única ordinaria será más rápida. Sin embargo, las restricciones de exclusión pueden especificar restricciones que son más generales que la simple igualdad. Por ejemplo, puedes especificar una restricción de que no haya dos filas en la tabla que contengan círculos superpuestos (consulta Section 8.8) utilizando el operador &&. Los operadores deben ser conmutativos.

Las restricciones de exclusión se implementan utilizando un índice que tiene el mismo nombre que la restricción, por lo que cada operador especificado debe estar asociado con una clase de operador adecuada (consulta Section 11.10) para el método de acceso al índice método_índice. Cada elemento_exclusión define una columna del índice, por lo que opcionalmente puede especificar una ordenación, una clase de operador, parámetros de clase de operador y/o opciones de ordenación; estos se describen detalladamente en CREATE INDEX.

El método de acceso debe admitir amgettuple (consulta Chapter 63); en la actualidad esto significa que no se puede usar GIN. Aunque está permitido, tiene poco sentido usar índices B-tree o hash con una restricción de exclusión, porque esto no hace nada que una restricción única ordinaria no haga mejor. Por lo tanto, en la práctica el método de acceso siempre será GiST o SP-GiST.

El predicado permite especificar una restricción de exclusión en un subconjunto de la tabla; internamente esto crea un índice parcial. Ten en cuenta que se requieren paréntesis alrededor del predicado.

Al establecer una restricción de exclusión para una jerarquía de particiones de varios niveles, todas las columnas de la clave de partición de la tabla particionada objetivo, así como las de todas sus tablas particionadas descendientes, deben incluirse en la definición de la restricción. Además, esas columnas deben compararse utilizando el operador de igualdad. Estas restricciones garantizan que las filas potencialmente conflictivas existan en la misma partición. La restricción también puede hacer referencia a otras columnas que no forman parte de ninguna clave de partición, las cuales se pueden comparar utilizando cualquier operador adecuado.

REFERENCES tabla_ref [ ( columna_ref ) ] [ MATCH tipo_match ] [ ON DELETE acción_referencial ] [ ON UPDATE acción_referencial ] (restricción de columna)
FOREIGN KEY ( nombre_columna [, ... ] [, PERIOD nombre_columna ] ) REFERENCES tabla_ref [ ( columna_ref [, ... ] [, PERIOD columna_ref ] ) ] [ MATCH tipo_match ] [ ON DELETE acción_referencial ] [ ON UPDATE acción_referencial ] (restricción de tabla) #

Estas cláusulas especifican una restricción de clave foránea, que requiere que un grupo de una o más columnas de la nueva tabla contenga únicamente valores que coincidan con los valores en las columnas referenciadas de alguna fila de la tabla referenciada. Si se omite la lista de columnas referenciadas (columna_ref), se utiliza la clave primaria de la tabla referenciada (tabla_ref). De lo contrario, la lista de columnas referenciadas debe referirse a las columnas de una restricción de clave primaria o única no diferible o ser las columnas de un índice único no parcial.

Si la última columna está marcada con PERIOD, se trata de una manera especial. Mientras que las columnas que no son PERIOD se comparan por igualdad (y debe haber al menos una de ellas), la columna PERIOD no se compara de esa forma. En su lugar, la restricción se considera satisfecha si la tabla referenciada tiene registros coincidentes (basados en las partes de la clave que no son PERIOD) cuyos valores de PERIOD combinados cubren por completo los del registro que hace la referencia. En otras palabras, la referencia debe tener un referente para toda su duración. Esta columna debe ser de tipo rango o multirango. Además, la tabla referenciada debe tener una clave primaria o restricción única declarada con WITHOUT OVERLAPS. Finalmente, si la clave foránea tiene una especificación nombre_columna marcada con PERIOD, la correspondiente columna_ref, si está presente, también debe estar marcada como PERIOD. Si se omite la cláusula de la columna referenciada y por lo tanto se elige la restricción de clave primaria de la tabla referenciada, la clave primaria debe tener su columna final marcada como WITHOUT OVERLAPS.

Para cada par de columnas que hace la referencia y columna referenciada, si son de un tipo de datos ordenable, las ordenaciones deben ser ambas deterministas o, de lo contrario, ambas iguales. Esto garantiza que ambas columnas tengan una noción coherente de la igualdad.

El usuario debe tener el permiso REFERENCES en la tabla referenciada (ya sea en toda la tabla o en las columnas referenciadas específicas). La adición de una restricción de clave foránea requiere un bloqueo SHARE ROW EXCLUSIVE en la tabla referenciada. Ten en cuenta que las restricciones de clave foránea no se pueden definir entre tablas temporales y tablas permanentes.

Un valor insertado en las columnas que hacen la referencia se compara con los valores de la tabla referenciada y las columnas referenciadas utilizando el tipo de coincidencia dado. Hay tres tipos de coincidencia: MATCH FULL, MATCH PARTIAL y MATCH SIMPLE (que es el comportamiento por defecto). MATCH FULL no permitirá que una columna de una clave foránea de varias columnas sea nula a menos que todas las columnas de la clave foránea sean nulas; si todas son nulas, no se requiere que la fila tenga una coincidencia en la tabla referenciada. MATCH SIMPLE permite que cualquiera de las columnas de la clave foránea sea nula; si alguna de ellas es nula, no se requiere que la fila tenga una coincidencia en la tabla referenciada. MATCH PARTIAL aún no está implementado. (Por supuesto, se pueden aplicar restricciones NOT NULL a las columnas que hacen la referencia para evitar que surjan estos casos).

Además, cuando se cambian los datos en las columnas referenciadas, se realizan ciertas acciones en los datos de las columnas de esta tabla. La cláusula ON DELETE especifica la acción a realizar cuando se elimina una fila referenciada en la tabla referenciada. Del mismo modo, la cláusula ON UPDATE especifica la acción a realizar cuando una columna referenciada en la tabla referenciada se actualiza a un nuevo valor. Si la fila se actualiza, pero la columna referenciada no cambia realmente, no se realiza ninguna acción. Las acciones referenciales se ejecutan como parte del comando de cambio de datos, incluso si la restricción está diferida. Existen las siguientes acciones posibles para cada cláusula:

NO ACTION #

Produce un error si la eliminación o actualización creara una violación de la restricción de clave foránea. Si la restricción está diferida, este error se producirá en el momento de la verificación de la restricción si todavía existen filas que hagan la referencia. Esta es la acción por defecto.

RESTRICT #

Produce un error si una fila que se va a eliminar o actualizar coincide con una fila en la tabla que hace la referencia. Esto evita la acción incluso si el estado posterior a la acción no violara la restricción de clave foránea. En particular, evita las actualizaciones de filas referenciadas a valores que son distintos pero se comparan como iguales. (Pero no evita las actualizaciones sin efecto que actualizan una columna al mismo valor).

En una clave foránea temporal, esta opción no está admitida.

CASCADE #

Elimina cualquier fila que haga referencia a la fila eliminada, o actualiza los valores de las columnas que hacen la referencia a los nuevos valores de las columnas referenciadas, respectivamente.

En una clave foránea temporal, esta opción no está admitida.

SET NULL [ ( nombre_columna [, ... ] ) ] #

Establece todas las columnas que hacen la referencia, o un subconjunto especificado de las mismas, en nulo. Solo se puede especificar un subconjunto de columnas para las acciones ON DELETE.

En una clave foránea temporal, esta opción no está admitida.

SET DEFAULT [ ( nombre_columna [, ... ] ) ] #

Establece todas las columnas que hacen la referencia, o un subconjunto especificado de las mismas, en sus valores por defecto. Solo se puede especificar un subconjunto de columnas para las acciones ON DELETE. (Debe haber una fila en la tabla referenciada que coincida con los valores por defecto, si no son nulos, o de lo contrario la operación fallará).

En una clave foránea temporal, esta opción no está admitida.

Si las columnas referenciadas cambian con frecuencia, podría ser aconsejable agregar un índice a las columnas que hacen la referencia para que las acciones referenciales asociadas con la restricción de clave foránea se puedan realizar de manera más eficiente.

DEFERRABLE
NOT DEFERRABLE #

Esto controla si la restricción se puede diferir. Una restricción que no es diferible se verificará inmediatamente después de cada comando. La verificación de las restricciones que son diferibles se puede posponer hasta el final de la transacción (utilizando el comando SET CONSTRAINTS). NOT DEFERRABLE es el comportamiento por defecto. Actualmente, solo las restricciones UNIQUE, PRIMARY KEY, EXCLUDE y REFERENCES (clave foránea) aceptan esta cláusula. Las restricciones NOT NULL y CHECK no son diferibles. Ten en cuenta que las restricciones diferibles no se pueden utilizar como árbitros de conflictos en una sentencia INSERT que incluya una cláusula ON CONFLICT.

INITIALLY IMMEDIATE
INITIALLY DEFERRED #

Si una restricción es diferible, esta cláusula especifica el momento por defecto para verificar la restricción. Si la restricción es INITIALLY IMMEDIATE, se verifica después de cada sentencia. Este es el comportamiento por defecto. Si la restricción es INITIALLY DEFERRED, se verifica solo al final de la transacción. El momento de verificación de la restricción se puede alterar con el comando SET CONSTRAINTS.

ENFORCED
NOT ENFORCED #

Cuando la restricción es ENFORCED, el sistema de base de datos garantizará que la restricción se cumpla, verificando la restricción en los momentos adecuados (después de cada sentencia o al final de la transacción, según corresponda). Ese es el comportamiento por defecto. Si la restricción es NOT ENFORCED, el sistema de base de datos no verificará la restricción. Corresponde entonces al código de la aplicación garantizar que se cumplan las restricciones. El sistema de base de datos aún podría asumir que los datos realmente cumplen con la restricción para decisiones de optimización en las que esto no afecte la corrección del resultado.

Las restricciones NOT ENFORCED pueden ser útiles como documentación si la verificación real de la restricción en tiempo de ejecución es demasiado costosa.

Actualmente esto solo se admite para restricciones de clave foránea y CHECK.

USING método #

Esta cláusula opcional especifica el método de acceso a la tabla a utilizar para almacenar los contenidos de la nueva tabla; el método debe ser un método de acceso de tipo TABLE. Consulta Chapter 62 para obtener más información. Si no se especifica esta opción, se elige el método de acceso a la tabla por defecto para la nueva tabla. Consulta default_table_access_method para obtener más información.

Al crear una partición, el método de acceso a la tabla es el método de acceso de su tabla particionada, si está establecido.

WITH ( parámetro_almacenamiento [= valor] [, ... ] ) #

Esta cláusula especifica parámetros de almacenamiento opcionales para una tabla o índice; consulta Parámetros de almacenamiento más abajo para obtener más información. Para compatibilidad con versiones anteriores, la cláusula WITH para una tabla también puede incluir OIDS=FALSE para especificar que las filas de la nueva tabla no deben contener OID (identificadores de objeto), OIDS=TRUE ya no está admitido.

WITHOUT OIDS #

Esta es una sintaxis compatible con versiones anteriores para declarar una tabla WITHOUT OIDS, ya no está admitido crear una tabla con OID (WITH OIDS).

ON COMMIT #

El comportamiento de las tablas temporales al final de un bloque de transacción se puede controlar mediante ON COMMIT. Las tres opciones son:

PRESERVE ROWS #

No se realiza ninguna acción especial al final de las transacciones. Este es el comportamiento por defecto.

DELETE ROWS #

Todas las filas de la tabla temporal se eliminarán al final de cada bloque de transacción. Básicamente, se realiza un TRUNCATE automático en cada confirmación (commit). Cuando se utiliza en una tabla particionada, esto no se aplica en cascada a sus particiones.

DROP #

La tabla temporal se eliminará (drop) al final del bloque de transacción actual. Cuando se utiliza en una tabla particionada, esta acción elimina sus particiones, y cuando se utiliza en tablas con hijos heredados, elimina los hijos dependientes.

TABLESPACE nombre_tablespace #

El nombre_tablespace es el nombre del tablespace en el que se va a crear la nueva tabla. Si no se especifica, se consulta default_tablespace, o temp_tablespaces si la tabla es temporal. Para las tablas particionadas, dado que no se requiere almacenamiento para la tabla en sí, el tablespace especificado anula default_tablespace como el tablespace por defecto a utilizar para cualquier partición recién creada cuando no se especifica explícitamente otro tablespace.

USING INDEX TABLESPACE nombre_tablespace #

Esta cláusula permite seleccionar el tablespace en el que se creará el índice asociado a una restricción UNIQUE, PRIMARY KEY o EXCLUDE. Si no se especifica, se consulta default_tablespace, o temp_tablespaces si la tabla es temporal.

Parámetros de almacenamiento

La cláusula WITH puede especificar parámetros de almacenamiento para las tablas y para los índices asociados a una restricción UNIQUE, PRIMARY KEY o EXCLUDE. Los parámetros de almacenamiento para los índices están documentados en CREATE INDEX. Los parámetros de almacenamiento disponibles actualmente para las tablas se enumeran a continuación. Para muchos de estos parámetros, como se muestra, existe un parámetro adicional con el mismo nombre precedido por toast., el cual controla el comportamiento de la tabla secundaria TOAST de la tabla, si la hubiera (consulta Section 66.2 para obtener más información sobre TOAST). Si se establece el valor de un parámetro de tabla y el parámetro toast. equivalente no está configurado, la tabla TOAST utilizará el valor del parámetro de la tabla. No se admite la especificación de estos parámetros para tablas particionadas, pero puedes especificarlos para particiones hoja individuales.

fillfactor (integer) #

El factor de relleno (fillfactor) para una tabla es un porcentaje entre 10 y 100. 100 (empaquetado completo) es el valor por defecto. Cuando se especifica un fillfactor menor, las operaciones INSERT empaquetan las páginas de la tabla solo hasta el porcentaje indicado; el espacio restante en cada página se reserva para actualizar filas en esa página. Esto le da a UPDATE la oportunidad de colocar la copia actualizada de una fila en la misma página que la original, lo cual es más eficiente que colocarla en una página diferente, y hace que las actualizaciones de tuplas de solo montón (HOT) sean más probables. Para una tabla cuyas entradas nunca se actualizan, el empaquetado completo es la mejor opción, pero en tablas con muchas actualizaciones, factores de relleno menores son adecuados. Este parámetro no se puede establecer para tablas TOAST.

toast_tuple_target (integer) #

El parámetro toast_tuple_target especifica la longitud mínima de la tupla requerida antes de intentar comprimir y/o mover valores de columna largos a tablas TOAST, y también es la longitud objetivo por debajo de la cual intentamos reducir la longitud una vez que comienza el proceso de toasting. Esto afecta a las columnas marcadas como External (para mover), Main (para compresión) o Extended (para ambas) y se aplica únicamente a las tuplas nuevas. No tiene efecto en las filas existentes. Por defecto, este parámetro está configurado para permitir al menos 4 tuplas por bloque, lo que con el tamaño de bloque por defecto será de 2040 bytes. Los valores válidos están entre 128 bytes y (tamaño de bloque - encabezado), por defecto 8160 bytes. Cambiar este valor puede no ser útil para filas muy cortas o muy largas. Ten en cuenta que la configuración por defecto suele ser cercana a la óptima, y es posible que establecer este parámetro pueda tener efectos negativos en algunos casos. Este parámetro no se puede establecer para tablas TOAST.

parallel_workers (integer) #

Esto establece el número de procesos de trabajo (workers) que se deben utilizar para ayudar a un escaneo paralelo de esta tabla. Si no se establece, el sistema determinará un valor basado en el tamaño de la relación. El número real de procesos de trabajo elegidos por el planificador o por sentencias de utilidad que utilizan escaneos paralelos puede ser menor, por ejemplo, debido a la configuración de max_worker_processes.

autovacuum_enabled, toast.autovacuum_enabled (boolean) #

Activa o desactiva el demonio de autovacuum para una tabla en particular. Si es true, el demonio de autovacuum realizará operaciones automáticas de VACUUM y/o ANALYZE en esta tabla siguiendo las reglas analizadas en Section 24.1.6. Si es false, esta tabla no será procesada por autovacuum, excepto para evitar el agotamiento (wraparound) de ID de transacción. Consulta Section 24.1.5 para obtener más información sobre la prevención del wraparound. Ten en cuenta que el demonio de autovacuum no se ejecuta en absoluto (excepto para evitar el wraparound de ID de transacción) si el parámetro autovacuum es false; configurar los parámetros de almacenamiento de tablas individuales no anula eso. Por lo tanto, rara vez tiene sentido establecer explícitamente este parámetro de almacenamiento en true, solo en false.

vacuum_index_cleanup, toast.vacuum_index_cleanup (enum) #

Fuerza o desactiva la limpieza de índices cuando se ejecuta VACUUM en esta tabla. El valor por defecto es AUTO. Con OFF, la limpieza de índices se desactiva; con ON, se activa; y con AUTO, se toma una decisión de forma dinámica cada vez que se ejecuta VACUUM. El comportamiento dinámico permite a VACUUM evitar escanear innecesariamente los índices para eliminar muy pocas tuplas muertas. Desactivar a la fuerza toda la limpieza de índices puede acelerar significativamente VACUUM, pero también puede provocar índices gravemente inflados si las modificaciones de la tabla son frecuentes. El parámetro INDEX_CLEANUP de VACUUM, si se especifica, anula el valor de esta opción.

vacuum_truncate, toast.vacuum_truncate (boolean) #

Valor por tabla para el parámetro vacuum_truncate. El parámetro TRUNCATE de VACUUM, si se especifica, anula el valor de esta opción.

autovacuum_vacuum_threshold, toast.autovacuum_vacuum_threshold (integer) #

Valor por tabla para el parámetro autovacuum_vacuum_threshold.

autovacuum_vacuum_max_threshold, toast.autovacuum_vacuum_max_threshold (integer) #

Valor por tabla para el parámetro autovacuum_vacuum_max_threshold.

autovacuum_vacuum_scale_factor, toast.autovacuum_vacuum_scale_factor (floating point) #

Valor por tabla para el parámetro autovacuum_vacuum_scale_factor.

autovacuum_vacuum_insert_threshold, toast.autovacuum_vacuum_insert_threshold (integer) #

Valor por tabla para el parámetro autovacuum_vacuum_insert_threshold. Se puede utilizar el valor especial de -1 para desactivar los vacuum por inserción en la tabla.

autovacuum_vacuum_insert_scale_factor, toast.autovacuum_vacuum_insert_scale_factor (floating point) #

Valor por tabla para el parámetro autovacuum_vacuum_insert_scale_factor.

autovacuum_analyze_threshold (integer) #

Valor por tabla para el parámetro autovacuum_analyze_threshold.

autovacuum_analyze_scale_factor (floating point) #

Valor por tabla para el parámetro autovacuum_analyze_scale_factor.

autovacuum_vacuum_cost_delay, toast.autovacuum_vacuum_cost_delay (floating point) #

Valor por tabla para el parámetro autovacuum_vacuum_cost_delay.

autovacuum_vacuum_cost_limit, toast.autovacuum_vacuum_cost_limit (integer) #

Valor por tabla para el parámetro autovacuum_vacuum_cost_limit.

autovacuum_freeze_min_age, toast.autovacuum_freeze_min_age (integer) #

Valor por tabla para el parámetro vacuum_freeze_min_age. Ten en cuenta que autovacuum ignorará los parámetros autovacuum_freeze_min_age por tabla que sean mayores que la mitad de la configuración del sistema autovacuum_freeze_max_age.

autovacuum_freeze_max_age, toast.autovacuum_freeze_max_age (integer) #

Valor por tabla para el parámetro autovacuum_freeze_max_age. Ten en cuenta que autovacuum ignorará los parámetros autovacuum_freeze_max_age por tabla que sean mayores que la configuración a nivel de sistema (solo se puede establecer un valor menor).

autovacuum_freeze_table_age, toast.autovacuum_freeze_table_age (integer) #

Valor por tabla para el parámetro vacuum_freeze_table_age.

autovacuum_multixact_freeze_min_age, toast.autovacuum_multixact_freeze_min_age (integer) #

Valor por tabla para el parámetro vacuum_multixact_freeze_min_age. Ten en cuenta que autovacuum ignorará los parámetros autovacuum_multixact_freeze_min_age por tabla que sean mayores que la mitad de la configuración a nivel de sistema autovacuum_multixact_freeze_max_age.

autovacuum_multixact_freeze_max_age, toast.autovacuum_multixact_freeze_max_age (integer) #

Valor por tabla para el parámetro autovacuum_multixact_freeze_max_age. Ten en cuenta que autovacuum ignorará los parámetros autovacuum_multixact_freeze_max_age por tabla que sean mayores que la configuración a nivel de sistema (solo se puede establecer un valor menor).

autovacuum_multixact_freeze_table_age, toast.autovacuum_multixact_freeze_table_age (integer) #

Valor por tabla para el parámetro vacuum_multixact_freeze_table_age.

log_autovacuum_min_duration, toast.log_autovacuum_min_duration (integer) #

Valor por tabla para el parámetro log_autovacuum_min_duration.

vacuum_max_eager_freeze_failure_rate, toast.vacuum_max_eager_freeze_failure_rate (floating point) #

Valor por tabla para el parámetro vacuum_max_eager_freeze_failure_rate.

user_catalog_table (boolean) #

Declara la tabla como una tabla de catálogo adicional a efectos de replicación lógica. Consulta Section 47.6.2 para obtener detalles. Este parámetro no se puede establecer para tablas TOAST.

Notas

PostgreSQL crea automáticamente un índice para cada restricción única y restricción de clave primaria para exigir la unicidad. Por lo tanto, no es necesario crear un índice explícitamente para las columnas de clave primaria. (Consulta CREATE INDEX para obtener más información).

Las restricciones únicas y las claves primarias no se heredan en la implementación actual. Esto hace que la combinación de herencia y restricciones únicas sea bastante disfuncional.

Una tabla no puede tener más de 1600 columnas. (En la práctica, el límite efectivo suele ser menor debido a las restricciones de longitud de la tupla).

Ejemplos

Crea la tabla films y la tabla distributors:

CREATE TABLE films (
    code        char(5) CONSTRAINT firstkey PRIMARY KEY,
    title       varchar(40) NOT NULL,
    did         integer NOT NULL,
    date_prod   date,
    kind        varchar(10),
    len         interval hour to minute
);

CREATE TABLE distributors (
     did    integer PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
     name   varchar(40) NOT NULL CHECK (name <> '')
);

Crea una tabla con un array bidimensional:

CREATE TABLE array_int (
    vector  int[][]
);

Define una restricción de tabla única para la tabla films. Las restricciones de tabla únicas se pueden definir en una o más columnas de la tabla:

CREATE TABLE films (
    code        char(5),
    title       varchar(40),
    did         integer,
    date_prod   date,
    kind        varchar(10),
    len         interval hour to minute,
    CONSTRAINT production UNIQUE(date_prod)
);

Define una restricción de columna CHECK:

CREATE TABLE distributors (
    did     integer CHECK (did > 100),
    name    varchar(40)
);

Define una restricción de tabla CHECK:

CREATE TABLE distributors (
    did     integer,
    name    varchar(40),
    CONSTRAINT con1 CHECK (did > 100 AND name <> '')
);

Define una restricción de tabla de clave primaria para la tabla films:

CREATE TABLE films (
    code        char(5),
    title       varchar(40),
    did         integer,
    date_prod   date,
    kind        varchar(10),
    len         interval hour to minute,
    CONSTRAINT code_title PRIMARY KEY(code,title)
);

Define una restricción de clave primaria para la tabla distributors. Los siguientes dos ejemplos son equivalentes, el primero utilizando la sintaxis de restricción de tabla, el segundo la sintaxis de restricción de columna:

CREATE TABLE distributors (
    did     integer,
    name    varchar(40),
    PRIMARY KEY(did)
);

CREATE TABLE distributors (
    did     integer PRIMARY KEY,
    name    varchar(40)
);

Asigna un valor por defecto de constante literal para la columna name, configura el valor por defecto de la columna did para que se genere seleccionando el siguiente valor de un objeto de secuencia, y haz que el valor por defecto de modtime sea la hora en que se inserta la fila:

CREATE TABLE distributors (
    name      varchar(40) DEFAULT 'Luso Films',
    did       integer DEFAULT nextval('distributors_serial'),
    modtime   timestamp DEFAULT current_timestamp
);

Define dos restricciones de columna NOT NULL en la tabla distributors, una de las cuales tiene un nombre explícito:

CREATE TABLE distributors (
    did     integer CONSTRAINT no_null NOT NULL,
    name    varchar(40) NOT NULL
);

Define una restricción única para la columna name:

CREATE TABLE distributors (
    did     integer,
    name    varchar(40) UNIQUE
);

Lo mismo, especificado como una restricción de tabla:

CREATE TABLE distributors (
    did     integer,
    name    varchar(40),
    UNIQUE(name)
);

Crea la misma tabla, especificando un factor de relleno del 70% tanto para la tabla como para su índice único:

CREATE TABLE distributors (
    did     integer,
    name    varchar(40),
    UNIQUE(name) WITH (fillfactor=70)
)
WITH (fillfactor=70);

Crea la tabla circles con una restricción de exclusión que evita que dos círculos se superpongan:

CREATE TABLE circles (
    c circle,
    EXCLUDE USING gist (c WITH &&)
);

Crea la tabla cinemas en el tablespace diskvol1:

CREATE TABLE cinemas (
        id serial,
        name text,
        location text
) TABLESPACE diskvol1;

Crea un tipo compuesto y una tabla tipada:

CREATE TYPE employee_type AS (name text, salary numeric);

CREATE TABLE employees OF employee_type (
    PRIMARY KEY (name),
    salary WITH OPTIONS DEFAULT 1000
);

Crea una tabla particionada por rango:

CREATE TABLE measurement (
    logdate         date not null,
    peaktemp        int,
    unitsales       int
) PARTITION BY RANGE (logdate);

Crea una tabla particionada por rango con varias columnas en la clave de partición:

CREATE TABLE measurement_year_month (
    logdate         date not null,
    peaktemp        int,
    unitsales       int
) PARTITION BY RANGE (EXTRACT(YEAR FROM logdate), EXTRACT(MONTH FROM logdate));

Crea una tabla particionada por lista:

CREATE TABLE cities (
    city_id      bigserial not null,
    name         text not null,
    population   bigint
) PARTITION BY LIST (left(lower(name), 1));

Crea una tabla particionada por hash:

CREATE TABLE orders (
    order_id     bigint not null,
    cust_id      bigint not null,
    status       text
) PARTITION BY HASH (order_id);

Crea una partición de una tabla particionada por rango:

CREATE TABLE measurement_y2016m07
    PARTITION OF measurement (
    unitsales DEFAULT 0
) FOR VALUES FROM ('2016-07-01') TO ('2016-08-01');

Crea algunas particiones de una tabla particionada por rango con varias columnas en la clave de partición:

CREATE TABLE measurement_ym_older
    PARTITION OF measurement_year_month
    FOR VALUES FROM (MINVALUE, MINVALUE) TO (2016, 11);

CREATE TABLE measurement_ym_y2016m11
    PARTITION OF measurement_year_month
    FOR VALUES FROM (2016, 11) TO (2016, 12);

CREATE TABLE measurement_ym_y2016m12
    PARTITION OF measurement_year_month
    FOR VALUES FROM (2016, 12) TO (2017, 01);

CREATE TABLE measurement_ym_y2017m01
    PARTITION OF measurement_year_month
    FOR VALUES FROM (2017, 01) TO (2017, 02);

Crea una partición de una tabla particionada por lista:

CREATE TABLE cities_ab
    PARTITION OF cities (
    CONSTRAINT city_id_nonzero CHECK (city_id != 0)
) FOR VALUES IN ('a', 'b');

Crea una partición de una tabla particionada por lista que a su vez está particionada y luego agrégale una partición:

CREATE TABLE cities_ab
    PARTITION OF cities (
    CONSTRAINT city_id_nonzero CHECK (city_id != 0)
) FOR VALUES IN ('a', 'b') PARTITION BY RANGE (population);

CREATE TABLE cities_ab_10000_to_100000
    PARTITION OF cities_ab FOR VALUES FROM (10000) TO (100000);

Crea particiones de una tabla particionada por hash:

CREATE TABLE orders_p1 PARTITION OF orders
    FOR VALUES WITH (MODULUS 4, REMAINDER 0);
CREATE TABLE orders_p2 PARTITION OF orders
    FOR VALUES WITH (MODULUS 4, REMAINDER 1);
CREATE TABLE orders_p3 PARTITION OF orders
    FOR VALUES WITH (MODULUS 4, REMAINDER 2);
CREATE TABLE orders_p4 PARTITION OF orders
    FOR VALUES WITH (MODULUS 4, REMAINDER 3);

Crea una partición por defecto:

CREATE TABLE cities_partdef
    PARTITION OF cities DEFAULT;

Compatibilidad

El comando CREATE TABLE cumple con el estándar SQL, con las excepciones que se enumeran a continuación.

Tablas temporales

Aunque la sintaxis de CREATE TEMPORARY TABLE se asemeja a la del estándar SQL, el efecto no es el mismo. En el estándar, las tablas temporales se definen solo una vez y existen automáticamente (comenzando con contenidos vacíos) en cada sesión que las necesita. En cambio, PostgreSQL requiere que cada sesión emita su propio comando CREATE TEMPORARY TABLE para cada tabla temporal que se vaya a utilizar. Esto permite que diferentes sesiones utilicen el mismo nombre de tabla temporal para diferentes propósitos, mientras que el enfoque del estándar obliga a que todas las instancias de un nombre de tabla temporal determinado tengan la misma estructura de tabla.

La definición del estándar sobre el comportamiento de las tablas temporales es ampliamente ignorada. El comportamiento de PostgreSQL en este punto es similar al de varias otras bases de datos SQL.

El estándar SQL también distingue entre tablas temporales globales y locales, donde una tabla temporal local tiene un conjunto de contenidos separado para cada módulo SQL dentro de cada sesión, aunque su definición se sigue compartiendo entre sesiones. Dado que PostgreSQL no admite módulos SQL, esta distinción no es relevante en PostgreSQL.

Por motivos de compatibilidad, PostgreSQL aceptará las palabras clave GLOBAL y LOCAL en una declaración de tabla temporal, pero actualmente no tienen ningún efecto. Se desaconseja el uso de estas palabras clave, ya que las versiones futuras de PostgreSQL podrían adoptar una interpretación de su significado más conforme con el estándar.

La cláusula ON COMMIT para tablas temporales también se asemeja al estándar SQL, pero tiene algunas diferencias. Si se omite la cláusula ON COMMIT, SQL especifica que el comportamiento por defecto es ON COMMIT DELETE ROWS. Sin embargo, el comportamiento por defecto en PostgreSQL es ON COMMIT PRESERVE ROWS. La opción ON COMMIT DROP no existe en SQL.

Restricciones de unicidad no diferidas

Cuando una restricción UNIQUE o PRIMARY KEY no es diferible, PostgreSQL comprueba la unicidad inmediatamente cada vez que se inserta o modifica una fila. El estándar SQL dice que la unicidad debe aplicarse solo al final de la sentencia; esto hace una diferencia cuando, por ejemplo, un solo comando actualiza varios valores de clave. Para obtener un comportamiento conforme con el estándar, declara la restricción como DEFERRABLE pero no diferida (es decir, INITIALLY IMMEDIATE). Ten en cuenta que esto puede ser significativamente más lento que la comprobación inmediata de unicidad.

Restricciones de verificación de columnas (CHECK)

El estándar SQL dice que las restricciones de columna CHECK solo pueden hacer referencia a la columna a la que se aplican; solo las restricciones de tabla CHECK pueden hacer referencia a varias columnas. PostgreSQL no impone esta restricción; trata las restricciones de verificación de columna y de tabla por igual.

Restricción EXCLUDE

El tipo de restricción EXCLUDE es una extensión de PostgreSQL.

Restricciones de clave foránea

La capacidad de especificar listas de columnas en las acciones de clave foránea SET DEFAULT y SET NULL es una extensión de PostgreSQL.

Es una extensión de PostgreSQL que una restricción de clave foránea pueda hacer referencia a columnas de un índice único en lugar de a columnas de una clave primaria o restricción única.

Restricción NULL

La restricción NULL (en realidad una no-restricción) es una extensión de PostgreSQL al estándar SQL que se incluye por compatibilidad con algunos otros sistemas de bases de datos (y por simetría con la restricción NOT NULL). Dado que es el comportamiento por defecto para cualquier columna, su presencia es simplemente ruido.

Nombres de restricciones

El estándar SQL dice que las restricciones de tabla y de dominio deben tener nombres que sean únicos en todo el esquema que contiene la tabla o el dominio. PostgreSQL es más laxo: solo requiere que los nombres de las restricciones sean únicos entre las restricciones asociadas a una tabla o dominio en particular. Sin embargo, esta libertad adicional no existe para las restricciones basadas en índices (restricciones UNIQUE, PRIMARY KEY y EXCLUDE), porque el índice asociado se llama igual que la restricción, y los nombres de los índices deben ser únicos entre todas las relaciones dentro del mismo esquema.

Herencia

La herencia múltiple a través de la cláusula INHERITS es una extensión del lenguaje PostgreSQL. SQL:1999 y posteriores definen la herencia simple utilizando una sintaxis y semántica diferentes. La herencia al estilo SQL:1999 aún no está admitida por PostgreSQL.

Tablas con cero columnas

PostgreSQL permite crear una tabla sin columnas (por ejemplo, CREATE TABLE foo();). Esta es una extensión del estándar SQL, que no permite tablas de cero columnas. Las tablas de cero columnas no son muy útiles por sí mismas, pero no permitirlas genera casos especiales extraños para ALTER TABLE DROP COLUMN, por lo que parece más limpio ignorar esta restricción de la especificación.

Múltiples columnas de identidad

PostgreSQL permite que una tabla tenga más de una columna de identidad. El estándar especifica que una tabla puede tener como máximo una columna de identidad. Esto se flexibiliza principalmente para dar más margen al realizar cambios de esquema o migraciones. Ten en cuenta que el comando INSERT admite solo una cláusula de anulación que se aplica a toda la sentencia, por lo que tener varias columnas de identidad con diferentes comportamientos no está bien admitido.

Columnas generadas

Las opciones STORED y VIRTUAL no son estándar, pero también se utilizan en otras implementaciones de SQL. El estándar SQL no especifica el almacenamiento de las columnas generadas.

Cláusula LIKE

Aunque existe una cláusula LIKE en el estándar SQL, muchas de las opciones que acepta PostgreSQL para ella no están en el estándar, y algunas de las opciones del estándar no están implementadas por PostgreSQL.

Cláusula WITH

La cláusula WITH es una extensión de PostgreSQL; los parámetros de almacenamiento no están en el estándar.

Tablespaces

El concepto de tablespaces de PostgreSQL no forma parte del estándar. Por lo tanto, las cláusulas TABLESPACE y USING INDEX TABLESPACE son extensiones.

Tablas tipadas

Las tablas tipadas implementan un subconjunto del estándar SQL. De acuerdo con el estándar, una tabla tipada tiene columnas que corresponden al tipo compuesto subyacente, así como otra columna que es la columna de autorreferencia. PostgreSQL no admite explícitamente las columnas de autorreferencia.

Cláusula PARTITION BY

La cláusula PARTITION BY es una extensión de PostgreSQL.

Cláusula PARTITION OF

La cláusula PARTITION OF es una extensión de PostgreSQL.

Consulte también

ALTER TABLE, DROP TABLE, CREATE TABLE AS, CREATE TABLESPACE, CREATE TYPE