CREATE TABLE — define una nueva tabla
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 [, ... ] ) ] }
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.
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 , nombreLOGGED
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.
DEFERRABLENOT 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 IMMEDIATEINITIALLY 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.
ENFORCEDNOT 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.
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.
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).
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;
El comando CREATE TABLE cumple con el estándar SQL, con las excepciones que se enumeran a continuación.
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.
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.
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.
EXCLUDE
El tipo de restricción EXCLUDE es una extensión de PostgreSQL.
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.
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.
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.
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.
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.
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.
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.
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.
WITH
La cláusula WITH es una extensión de PostgreSQL; los parámetros de almacenamiento no están en el estándar.
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.
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.
PARTITION BY
La cláusula PARTITION BY es una extensión de PostgreSQL.
PARTITION OF
La cláusula PARTITION OF es una extensión de PostgreSQL.