30
Instalar PostgreSQL en Ubuntu Linux Instalacion Instalar Postgresql en Ubuntu es bastante sencillo, yo uso Ubuntu 7.04 e instalo postgresql desde los repositorios oficiales que tienen PostgreSQL 8.2. Para instalar se puede utilizar synaptic e instalando el paquete llamado 'postgresql-8.2' o usando aptitude en una terminal. Para instalar abra un terminal y ejecute el siguiente comando: $sudo aptitude install postgresql-8.2 Escriba 'Y'(si) para descargar e instalar automaticamente y cuando finalice el proceso postgresql estara correctamente instalado pero no se inicia automaticamente, debe iniciarse el servicio manualmente. Iniciando el Servicio PostgreSQL Manualmente Esta tarea puede realizarse usando la interfaz grafica o con una terminal: Iniciar usando Servicios de Ubuntu: Hacer click en el menu System->Administration->Services y marcar el servicio: Database Server(postgresql-8.2) como se muestra a continuación: Con esta acción se iniciara la base de datos. 1

Manual Postgres

Embed Size (px)

DESCRIPTION

Como hacer instalacion de esta manejador de base de datos en ubuntu

Citation preview

Page 1: Manual Postgres

Instalar PostgreSQL en Ubuntu Linux

Instalacion

Instalar Postgresql en Ubuntu es bastante sencillo, yo uso Ubuntu 7.04 e instalo postgresql desde los repositorios oficiales que tienen PostgreSQL 8.2. Para instalar se puede utilizar synaptic e instalando el paquete llamado 'postgresql-8.2' o usando aptitude en una terminal.

Para instalar abra un terminal y ejecute el siguiente comando:

$sudo aptitude install postgresql-8.2

Escriba 'Y'(si) para descargar e instalar automaticamente y cuando finalice el proceso postgresql estara correctamente instalado pero no se inicia automaticamente, debe iniciarse el servicio manualmente.

Iniciando el Servicio PostgreSQL ManualmenteEsta tarea puede realizarse usando la interfaz grafica o con una terminal:

Iniciar usando Servicios de Ubuntu:Hacer click en el menu System->Administration->Services y marcar el servicio:

Database Server(postgresql-8.2) como se muestra a continuación:

Con esta acción se iniciara la base de datos.

Iniciar usando usando Terminal:

Abra una terminal y ejecute el siguiente comando:$ sudo /etc/init.d/postgresql-8.3 stop* Stopping PostgreSQL 8.3 database server                               [ OK ]$ sudo /etc/init.d/postgresql-8.3 start* Starting PostgreSQL 8.3 database server                               [ OK ]Listo, ya se ha instalado e iniciadio la Base de Datos. Existe un Pequeño problema que realmente no es un problema, es una caracteristica de Seguridad del Paquete de Instalacion de Ubuntu que no revela cual es la

1

Page 2: Manual Postgres

contraseña que se le asigno al usuario 'postgres', sin embargo, he creado la siguiente guia para ayudar a solventarlo:

Cambiar Contraseña de Usuario 'postgres' en Ubuntu

En un post anterior ya he comentado que el instalador de PostgreSQL para Ubuntu asigna una contraseña aleatoria al usuario 'postgres' y que esta debe ser cambiada manualmente post-instalación. Esto no es un error en el instalador, es una comportamiento de seguridad por defecto del instalador.

Cambiano la contraseña

Para cambiar la contraseña en una instalación por defecto o porque simplemente se olvido la contraseña y no existen mas usuarios se hace lo siguiente en una terminal:

1) Impersonar al usuario 'postgres'.$sudo su postgres

2) Ejecutar la utilidad psql$psql

En este momento se esta conectando a la base de datos usando el usuario 'postgres', con este usuario puede cambiar contraseñas de muchos usuarios incluso del mismo 'postgres'. Ahora vamos a cambiar la contraseña, ejecute sobre la linea de comandos actual la siguiente secuencia donde 'passwd' es la contraseña nueva(debe utilizarse comillas simples):

alter user postgres with password 'passwd';

Si el programa response con el mensaje 'ALTER ROLE' la contraseña se ha cambiado correctamente.

Para salir se la utilidad escriba: \q

para salir del usuario 'postgres' escriba lo siguiente: exit

Listo. La contraseña se ha cambiado correctamente.

Probando la conexion

Para probar la conexion se puede utilizar la misma utilidad 'psql' de la siguiente forma:

psql -U postgres -W

Presione ENTER e introduzca la nueva contraseña(usted debio haberla cambiado en el ejemplo anterior, si no lo hizo la contraseña es 'passwd').

2

Page 3: Manual Postgres

Para PostgreSQL (7.2.1)

Verificar la instalación.

Para verificar que Postgres está corriendo:  nautilus:~# ps auxw | grep postgresproduce una salida similar a:  postgres 1263  0.0  0.7 8840 1852 pts/1 S 11:56 0:00 /usr/lib/postgresql/bin/postmaster  postgres 1265  0.0  0.7 9832 1828 pts/1 S 11:56 0:00 postgres: stats buffer process  postgres 1267  0.0  0.7 8872 1864 pts/1 S 11:56 0:00 postgres: stats collector processEsto indica que el servidor está corriendo.

Postgres puede arrancarse de la manera usual en Debian:  /etc/init.d/postgres start -------> arranca Postgres.  /etc/init.d/postgres stop -------> detiene Postgres.

Para verificar el funcionamiento es preciso operar como el usuario postgres, nombre del administrador universal de Postgres. Operando como supervisor, acceder al usuario postgres mediante su:, invocar psql, el lenguaje de interacción con Postgres, verificar mensajes de conexión, salir de psql. Sigue una transcripción de la sesión:

  nautilus:~# su - postgres asume identidad del usuario postgres desde root.postgres@nautilus:~$ psql -l              List of databases     Name    |  Owner   | Encoding   -----------+----------+----------   template0 | postgres | LATIN1   template1 | postgres | LATIN1  (2 rows)muestra las bases de datos existentes.

  postgres@nautilus:~$ psql template1invoca psql, lenguaje de programación SQL para acceder a Postgres, mostrando algo similar a  Welcome to psql, the PostgreSQL interactive terminal.    Type: \copyright for distribution terms          \h for help with SQL commands          \? for help on internal slash commands          \g or terminate with semicolon to execute query          \q to quit  template1=#

quedando a la espera de comandos. Observar las opciones de ayuda, en particular \q para salir de psql. Dice estar conectado a la base de

3

Page 4: Manual Postgres

datos template1, lo cual queda consignado en el indicador de comando. Los comandos inexistentes no dan salida alguna. La muestra de opciones se pagina con los comandos de Unix more o less; en ambos casos se avanza con la barra de espacio y se sale con 'q' (ver página man en Unix, man less).

  template1=> \qsale de psql.  postgres@nautilus:~$ exit  logout  nautilus:~# abandona la identidad del usuario postgres, vuelve a ser root.

Usuario de PostgreSQL.

Los usuarios de PostgreSQL deben ser "creados para PostgreSQL", es decir, creados en los registros internos de PostgreSQL antes de poder operar con la base de datos. El usuario de Unix debe ser declarado usuario de PostgreSQL. Esta operación debe hacerse operando como el usuario postgres, accediendo a este usuario desde root como se mostró antes.Es sumamente importante crear un usuario con privilegios de administrador para la base de datos, para evitar tener que operar como root y luego impersonar postgres. Este usuario es plenipotenciario para Postgres.

Como root, asumiento la identidad del usuario postgres, el comando Unix createuser crea un nuevo usuario de PostgreSQL, con el siguiente diálogo:  nautilus:~# su - postgres   postgres@nautilus:~$ createuser  Enter name of user to add: victor  Shall the new user be allowed to create databases? (y/n) y  Shall the new user be allowed to create more new users? (y/n) y  CREATE USER  postgres@nautilus:~$ crea el usuario victor con privilegios de crear bases de datos y nuevos usuarios. Los usuarios de Postgres son diferentes a los de Unix; en principio conviene mantener una correspondencia, es decir, crear en PostgreSQL un usuario existente en Unix como se hizo aquí. Usuarios propios de PostgreSQL pueden crearse con comandos SQL; deberá no sólo crearse el usuario sino adjudicársele permisos sobre las bases de datos que corresponda (ver en Manual del Administrador el tema Usuarios y Permisos).  nautilus:/root$ exit  exit  nautilus:~# sale de usuario postgres, queda en root.

Crear una base de datos de prueba.

Operando en la cuenta del usuario habilitado en PostgreSQL, en el shell de Unix,   victor@nautilus:~$ createdb prueba  CREATE DATABASErepite el comando SQL y crea la base de datos "prueba", sin tablas ni ningún otro elemento; estos podrán

4

Page 5: Manual Postgres

crearse usando PgAccess o usando el propio lenguaje psql. Los comandos en psql terminan con ";". Si se olvida, no se muestra ningún mensaje ni se ejecuta el comando.

  victor@nautilus:~$ psql prueba  Welcome to psql, the PostgreSQL interactive terminal.  Type:  \copyright for distribution terms         \h for help with SQL commands         \? for help on internal slash commands         \g or terminate with semicolon to execute query         \q to quitConecta a la base de datos creada.

  prueba=# \l          List of databases     Name    |  Owner   | Encoding   -----------+----------+----------   prueba    | victor   | LATIN1   template0 | postgres | LATIN1   template1 | postgres | LATIN1  (3 rows)Lista las bases de datos existentes.

Puede crearse una base de datos con comandos SQL, sin usar el script del shell:  victor@nautilus:~$ psql template1ingresa en psql.  template1=# CREATE DATABASE prueba2;  CREATE DATABASEcrea la nueva base de datos.  template1=# \llista bases de datos existentes, mostrando la recientemente creada.  template1=# DROP DATABASE victor;  DROP DATABASEdestruye la base de datos indicada.  template1=# \llista bases de datos existentes, verificando la desaparición de la eliminada.

Puede accederse a la base de datos creada usando psql:  victor@nautilus:~$ psql pruebaconecta a la base de datos "prueba"; si se omite el nombre de la base de datos da error.

Destruir una base de datos.

Operando como usuario administrador, ingresar en psql.  template1=> DROP DATABASE prueba;  DESTROYDB  template1=>destruye la base de datos "prueba". Recordar terminar los comandos con ";". Si se olvida, no se muestra ningún mensaje ni se ejecuta el comando.

5

Page 6: Manual Postgres

2.2 Conceptos PostgreSQL es un sistema de gestión de base de datos relacional (RDBMS). Esto significa que es un sistema de gestión de los datos almacenados en las relaciones. Relación es esencialmente un término matemático para el cuadro. El concepto de almacenamiento de datos en las tablas es tan común hoy que en sí puede parecer obvio, pero hay una serie de otras formas de organización de bases de datos. Archivos y directorios en Unix como sistema operativo de un ejemplo de una base de datos jerárquica. Un desarrollo más moderno es la base de datos orientada a objetos.

Cada tabla es el nombre de una colección de filas. Cada fila de una tabla dada tiene el mismo nombre de las columnas, y cada columna es de un determinado tipo de datos. Considerando que las columnas tienen un orden fijo en cada fila, es importante recordar que SQL no garantiza el orden de las filas dentro de la tabla de ninguna manera (aunque pueden ser ordenados expresamente para la pantalla).

Cuadros se agrupan en bases de datos, y una colección de bases de datos gestionadas por un único servidor PostgreSQL ejemplo, constituye una base de datos de clúster.

2.3. Creación de un nuevo TablaPuede crear una nueva tabla especificando el nombre de la tabla, junto con todos los nombres de columna y sus tipos:

CREATE TABLE tiempo ( ciudad varchar (80), temp_lo int, - baja temperatura temp_hi int, - alta temperatura prcp real, - la precipitación date date );

Usted puede entrar en este psql con los saltos de línea. Psql reconocerá que el comando no está terminado hasta el punto y coma.

Espacio en blanco (es decir, espacios, tabulaciones y saltos de línea) pueden ser utilizadas libremente en comandos SQL. Eso significa que usted puede escribir el comando alineados diferente a la de arriba, o incluso la totalidad en una sola línea. Dos guiones ( "-") introducir comentarios. Sea cual sea sigue es ignorado hasta el final de la línea. SQL no tiene en cuenta mayúsculas sobre las palabras claves y los identificadores, excepto cuando son identificadores entre comillas dobles para preservar el caso (no se hizo anteriormente).

varchar (80) se especifica un tipo de datos que puede almacenar cadenas de caracteres arbitrarios de hasta 80 caracteres de longitud. int es el tipo entero normal. verdadero es un tipo único de precisión para el almacenamiento de números de punto flotante. fecha debería ser auto-explicativo. (Sí, la columna de tipo fecha se llama también la fecha. Esto puede ser conveniente o confusa - que usted elija.)

PostgreSQL soporta el estándar SQL tipos int, smallint, real, doble precisión, char (N), varchar (N), fecha, hora, fecha y hora, y el intervalo, así como otros tipos de utilidad general y un rico conjunto de tipos geométricos. PostgreSQL puede ser personalizado con un número arbitrario definido por el usuario de los tipos de datos. En consecuencia, los nombres no son de tipo sintáctico palabras clave, excepto cuando sea necesario para apoyar a los casos especiales en el estándar SQL.

6

Page 7: Manual Postgres

El segundo ejemplo almacenará las ciudades y sus asociados la ubicación geográfica:

CREATE TABLE ciudades ( nombre varchar (80), ubicación point );

El tipo de punto (point) es un ejemplo de PostgreSQL específicos de tipo de datos.

Por último, cabe mencionar que si no necesita una tabla más o quiere volver a crear de otro modo se puede eliminar usando el siguiente comando:

DROP TABLE tablename ;

2.4 Insertar datos a una tabla con registros La sentencia INSERT se utiliza para rellenar una tabla con filas:

INSERT INTO tiempo VALUES ( 'San Francisco', 46, 50, 0.25,'1994-11-27 ');

Tenga en cuenta que todos los tipos de datos de uso bastante obvio formatos de entrada. Constantes que no son simples valores numéricos por lo general debe ser rodeado por comillas simples ( '), como en el ejemplo. El tipo de fecha es bastante flexible en lo que se acepta, pero para este tutorial vamos a atenernos a la inequívoca formato se muestra aquí.

El punto que requiere una coordinación de tipo par como entrada, como se muestra aquí:

INSERT INTO ciudad VALUES ( 'San Francisco', '(-194,0, 53,0)');

La sintaxis utilizada hasta la fecha requiere que recordar el orden de las columnas. Una sintaxis alternativa le permite enumerar las columnas explícitamente:

INSERT INTO tiempo (ciudad, temp_lo, temp_hi, prcp, fecha) VALUES ( 'San Francisco', 43, 57, 0,0,'1994-11-29 ');

Puede listar las columnas en un orden diferente si lo desea, o incluso omitir algunas columnas, por ejemplo, si la precipitación es desconocido:

INSERT INTO tiempo (fecha, ciudad, temp_hi, temp_lo) VALUES ('1994-11-29 ',' Hayward ', 54, 37);

Muchos desarrolladores consideran explícitamente la lista de las columnas mejor estilo de confiar en el orden implícita.

Por favor, introduzca todos los comandos se indica más arriba por lo que tiene algunos datos para trabajar en las siguientes secciones.

También podría haber utilizado COPIA para cargar grandes cantidades de datos desde ficheros de texto plano. Este suele ser más rápido debido a que el comando COPY se ha optimizado para esta aplicación al mismo tiempo a menos que la flexibilidad de INSERT. Un ejemplo sería:

COPY weather FROM '/home/user/weather.txt';

donde el nombre de archivo para el archivo de código fuente debe estar disponible para el servidor de backend máquina, no el cliente, desde el backend del servidor lee el archivo directamente. Puede obtener

7

Page 8: Manual Postgres

más información sobre el comando COPY en COPIA.

2.5 Consultar una tabla Para recuperar datos de una tabla, el cuadro se preguntó. Un comando SELECT de SQL se utiliza para hacer esto. La declaración se divide en una lista (la parte que las listas de las columnas a ser devueltas), una mesa lista (la parte que las listas de los cuadros de que para recuperar los datos), y un título opcional (la parte que especifica todas las restricciones) . Por ejemplo, para recuperar todas las filas de la tabla de weather escribe:

SELECT * FROM tiempo;

El * es un comodin para "todas las columnas". [1] Por lo tanto, el mismo resultado se tuvo con:

SELECT ciudad, temp_lo, temp_hi, prcp, fecha FROM tiempo;

El resultado debería ser:

ciudad | temp_lo | temp_hi | prcp | fecha ---------------+---------+---------+------+------------ San Francisco | 46 | 50 | 0.25 | 1994-11-27 San Francisco | 43 | 57 | 0 | 1994-11-29 Hayward | 37 | 54 | | 1994-11-29 (3 rows)

Puede escribir las expresiones, y no sólo simples referencias columna, en la selecta lista. Por ejemplo, usted puede hacer:

SELECT ciudad, (temp_hi + temp_lo) / 2 AS temp_avg, fecha FROM tiempo;

This should give: Esto debería dar:

Ciudad | temp_avg | fecha ---------------+----------+------------ San Francisco | 48 | 1994-11-27 San Francisco | 50 | 1994-11-29 Hayward | 45 | 1994-11-29 (3 rows)

Aviso como la forma en que la cláusula se utiliza para cambiar la columna de salida.(La cláusul AS a es opcional.)

Una consulta puede ser "calificados" por la adición de una cláusula WHERE que especifica que los registros se quería. La cláusula WHERE contiene un booleano (valor de verdad) de expresión, y sólo las filas para que la expresión booleana es verdadera se devuelven. Los habituales operadores booleanos (AND, OR y NOT) se permiten en la calificación. Por ejemplo, la siguiente recupera el clima de San Francisco en los días de lluvia:

SELECT * FROM clima WHERE ciudad = 'San Francisco' AND prcp > 0.0;

Resultado:

ciudad | temp_lo | temp_hi | prcp | fecha ---------------+---------+---------+------+------------ San Francisco | 46 | 50 | 0.25 | 1994-11-27

8

Page 9: Manual Postgres

(1 row)

Usted puede solicitar que los resultados de una consulta se devolverá ordenados en orden:

SELECT * FROM clima ORDER BY ciudad;

ciudad | temp_lo | temp_hi | prcp | fecha ---------------+---------+---------+------+------------ Hayward | 37 | 54 | | 1994-11-29 San Francisco | 43 | 57 | 0 | 1994-11-29 San Francisco | 46 | 50 | 0.25 | 1994-11-27

En este ejemplo, la orden no está totalmente especificada, por lo que se podría conseguir la de San Francisco, ya sea en las filas orden. Sin embargo, usted siempre obtener los resultados se ha indicado si:

SELECT * FROM clima ORDER BY ciudad, temp_lo;

Usted puede solicitar que se eliminan las filas duplicadas de los resultados de una consulta:

SELECT DISTINCT ciudad FROM tiempo;

Ciudad --------------- Hayward San Francisco (2 rows)

Una vez más, el resultado puede variar de pedidos fila. Puede garantizar la coherencia de los resultados mediante el uso de distintos y ORDER BY juntos: [2]

SELECT DISTINCT ciudad FROM tiempo ORDER BY ciudad;

Notes Notas

[1] SELECT * Si bien es útil para desactivar el brazalete consultas, es considerado ampliamente en la producción de mal estilo de código, ya que la adición de una columna a la tabla podría cambiar los resultados.

[2] En algunos sistemas de bases de datos, incluyendo las versiones de PostgreSQL, la aplicación de los distintos órdenes automáticamente las filas y de manera ORDER BY no es necesario. Pero esto no es requerido por el estándar SQL, PostgreSQL y la actual no garantiza que las filas DISTINCT causas que se ordene.

2.6 Joins o Union Entre Tablas Hasta el momento, nuestras preguntas sólo tienen acceso a una mesa a la vez. Las preguntas pueden tener

9

Page 10: Manual Postgres

acceso a varios cuadros a la vez, o acceder a la misma mesa de tal manera que varias filas de la tabla se están tratando al mismo tiempo. Una consulta que permite acceder a varios registros de la misma o de diferentes tablas en un momento se llama un join consulta. Como ejemplo, digamos que usted desea una lista de todos los registros del tiempo junto con la ubicación de la ciudad asociados. Para ello, tenemos que comparar la ciudad, la columna de cada fila de la tabla de tiempo con el nombre de la columna de todos los registros en la tabla de las ciudades, y seleccionar las parejas de filas que coinciden con estos valores.

Nota: Este es sólo un modelo conceptual. La unión se realiza por lo general de manera más eficiente que realmente es posible la comparación de cada par de filas, pero esto es invisible para el usuario.

Esto sería realizado por la siguiente consulta:

SELECT * FROM tiempo, ciudades WHERE ciudad = nombre;

ciudad | temp_lo | temp_hi | prcp | fecha | nombre | localización -----------+---------+---------+------+------------+--------+--------------- San Francisco | 46 | 50 | 0.25 | 1994-11-27 | San Francisco | (-194,53) San Francisco | 43 | 57 | 0 | 1994-11-29 | San Francisco | (-194,53) (2 rows)

Observar dos cosas acerca de los resultados:

No hay ningún resultado fila para la ciudad de Hayward. . Esto se debe a que no hay ninguna entrada coincidente en la cities de Hayward mesa, por lo que la unión hace caso omiso de las filas en el incomparable clima de mesa. Veremos en breve cómo este puede ser fijo.

Hay dos columnas que contienen el nombre de la ciudad. Esto es correcto porque las listas de las columnas de la weather y la cities de mesa se concatenan. En la práctica, esto no es deseable, aunque, por lo que probablemente desea incluir explícitamente la salida de las columnas en lugar de utilizar *:

SELECT ciudad, temp_lo, temp_hi, prcp, fecha, lugar FROM tiempo, ciudades WHERE ciudad = nombre;

Ejercicio: el intento de descubrir la semántica de esta consulta cuando la cláusula WHERE se omite.

Dado que las columnas tenían diferentes nombres, el analizador automáticamente descubrió que el cuadro que pertenecen. Si hay nombres de columna duplicado en los dos cuadros que usted necesita para calificar los nombres de columna para mostrar que uno que significaba, como en:

SELECT weather.city, weather.temp_lo, weather.temp_hi, weather.prcp, weather.date, cities.location FROM tiempo, ciudades WHERE cities.name = weather.city;

En general, se considera buen estilo para calificar todos los nombres de columna en una unión de consulta, de modo que la consulta no dejará un duplicado si la columna es el nombre más tarde añadió a uno de los cuadros.

Únete a las preguntas del tipo visto hasta ahora también se puede escribir en esta forma alternativa:

SELECT *

10

Page 11: Manual Postgres

FROM tiempo INNER JOIN ciudades ON (tiempo.cudad = ciudades.nombre);

Esta sintaxis no es tan usado como la anterior, pero se muestra aquí para ayudarle a comprender los siguientes temas.

Ahora vamos a ver cómo podemos obtener el registro Hayward atrás pulg ¿Qué queremos que la consulta que hacer es escanear el tiempo y el cuadro de cada fila para encontrar la concordancia ciudades fila (s). Si no se pongan en venta se encuentra la fila que queremos algunos "valores vacíos" para ser sustituido por la cities las columnas de las tablas. Este tipo de consulta que se llama un OUTER JOIN. (La suma que hemos visto hasta ahora se une interior). El comando es así:

SELECT * FROM tiempo LEFT OUTER JOIN ciudades ON (tiempo.ciudad = ciudades.nombre);

ciudad | temp_lo | temp_hi | prcp | fecha | nombre | localización --------------+---------+---------+------+------- -----+---------------+----------- Hayward | 37 | 54 | | 1994-11-29 | | San Francisco | 46 | 50 | 0.25 | 1994-11-27 | San Francisco | (-194,53) San Francisco | 43 | 57 | 0 | 1994-11-29 | San Francisco | (-194,53) (3 rows)

Esta consulta se llama un LEFT OUTER JOIN porque el mencionado cuadro a la izquierda de la unión operador tendrá cada uno de sus filas en la salida al menos una vez, mientras que la tabla de la derecha sólo tendrá salida de las filas que coinciden con algunos de la fila mesa de la izquierda. Cuando la salida de una fila de la tabla a la izquierda-para el que no existe el derecho de mesa partido, vacío (nulo) los valores son sustituidos por el derecho-las columnas de la tabla.

Ejercicio: Hay también derecho externas y la plena externas. Trate de averiguar lo que las hacen.

También podemos participar en una mesa frente a sí mismo. Esto se llama una libre adhesión. Como ejemplo, supongamos que queremos encontrar todos los registros meteorológicos que se encuentran en el rango de temperatura de otros registros meteorológicos. Así que tenemos que comparar el temp_lo y columnas de cada temp_hi tiempo a la fila temp_lo y temp_hi todas las demás columnas de tiempo filas. Podemos hacer esto con la siguiente consulta:

SELECT W1.city AS ciudad, W1.temp_lo AS bajo, W1.temp_hi AS alto, W2.city AS ciudad, W2.temp_lo AS bajo, W2.temp_hi AS alto FROM clima W1, clima W2 WHERE W1.temp_lo < W2.temp_lo AND W1.temp_hi > W2.temp_hi;

ciudad | baja | alta | ciudad | baja | alta ---------------+-----+------+---------------+-----+------ San Francisco | 43 | 57 | San Francisco | 46 | 50 Hayward | 37 | 54 | San Francisco | 46 | 50 (2 rows)

Aquí tenemos tabla clima W1 y W2 como para poder distinguir la izquierda y derecha de la adhesión. También puede utilizar este tipo de alias en otras consultas para ahorrar escribir, por ejemplo:

SELECT * FROM clima w, ciudades c WHERE w.city = c.name;

11

Page 12: Manual Postgres

Se encontrará con este estilo de abreviar con bastante frecuencia.

2.7. Funciones agregadas Al igual que la mayoría de los demás productos de base de datos relacional, PostgreSQL soporta funciones de agregado. Una función de agregado calcula un único resultado de múltiples filas de entrada. Por ejemplo, hay que calcular los agregados de la count sum avg (media), max (máximo) y min (mínimo) a lo largo de un conjunto de filas.

Como ejemplo, podemos encontrar la más alta a baja temperatura con la lectura en cualquier lugar:

SELECT MAX (temp_lo) FROM clima;

max ----- 46 (1 row)

Si queremos saber qué ciudad (o ciudades), que se produjo en la lectura, podemos probar:

SELECT ciudad FROM clima WHERE temp_lo = max(temp_lo); EQUIVOCADO

pero esto no funcionará ya que el total max no puede utilizarse en la cláusula WHERE. (Esta restricción existe porque la cláusula WHERE determina qué registros se incluirán en el cálculo global, por lo tanto es obvio que tiene que ser evaluado antes de agregar funciones se computan.) Sin embargo, como suele ser el caso, la consulta puede ser vuelto a lograr el resultado deseado , aquí con una subconsulta:

SELECT ciudad FROM clima WHERE temp_lo = (SELECT max(temp_lo) FROM clima);

Ciudad --------------- San Francisco (1 row)

Esto es correcto porque la subconsulta es un cálculo que calcula por separado su propio conjunto de lo que está sucediendo en la consulta externa.

Agregados son también muy útiles en combinación con las cláusulas GROUP BY. Por ejemplo, podemos obtener el máximo de baja temperatura observados en cada ciudad con:

SELECT ciudad, max (temp_lo) FROM clima GROUP BY ciudad;

Ciudad | máx ---------------+----- Hayward | 37 San Francisco | 46 (2 rows)

que nos da una salida de línea para cada ciudad. Cada resultado global se calcula sobre la mesa las filas que coinciden con la ciudad. Podemos filtrar estas filas agrupadas usando HAVING:

SELECT ciudad, max (temp_lo)

12

Page 13: Manual Postgres

FROM clima GROUP BY ciudad HAVING max(temp_lo) < 40;

Ciudad | máx ---------+----- Hayward | 37 (1 row)

que nos da los mismos resultados sólo para las ciudades que han temp_lo todos los valores por debajo de 40. Por último, si sólo se preocupan por las ciudades cuyos nombres comienzan con "S" que podríamos hacer:

SELECT ciudad, max (temp_lo) FROM clima WHERE ciudad LIKE 'S%' (1) GROUP BY ciudad HAVING max(temp_lo) < 40;

(1) El operador LIKE no coincidencia de patrones y se explica en Sección 9.7.

Es importante comprender la interacción entre los agregados y SQL 's DONDE y habiendo cláusulas. La diferencia fundamental entre el WHERE y HAVING es la siguiente: WHERE selecciona entrada de filas antes de los grupos y los agregados se calculan (por lo tanto, los controles que van en las filas del cómputo global), mientras que el grupo selecciona HAVING filas después de los grupos y los agregados se calculan. . Por lo tanto, la cláusula WHERE no debe contener funciones de agregado, no tiene sentido tratar de usar un conjunto para determinar qué filas se aportaciones a los agregados. Por otra parte, la cláusula HAVING siempre contiene funciones de agregado. (En rigor, se le permite escribir una cláusula HAVING que no utiliza agregados, pero rara vez es útil. La misma condición podría ser utilizada de manera más eficiente el WHERE.)

En el ejemplo anterior, podemos aplicar la restricción en el nombre de la ciudad en WHERE, ya que no necesita agregado. Esto es más eficaz que añadir la restricción en HAVING, porque no hacer la agrupación y sobre el conjunto de cálculos para todas las filas que no chequeo WHERE.

13

Page 14: Manual Postgres

Constraints Limitaciones Data types are a way to limit the kind of data that can be stored in a table. Tipos de datos son una manera de limitar el tipo de datos que pueden almacenarse en una tabla. For many applications, however, the constraint they provide is too coarse. Para muchas aplicaciones, sin embargo, la limitación que ofrecen es demasiado gruesa. For example, a column containing a product price should probably only accept positive values. Por ejemplo, una columna que contiene un producto de precio probablemente sólo aceptar los valores positivos. But there is no standard data type that accepts only positive numbers. Pero no hay ningún tipo de datos estándar que sólo acepta números positivos. Another issue is that you might want to constrain column data with respect to other columns or rows. Otra cuestión es que usted puede ser que desee para limitar los datos de la columna con respecto a otras columnas o filas. For example, in a table containing product information, there should be only one row for each product number. Por ejemplo, en un cuadro que contiene información sobre el producto, sólo puede haber una fila para cada número de producto.

To that end, SQL allows you to define constraints on columns and tables. A tal fin, SQL le permite definir las limitaciones en las columnas y tablas. Constraints give you as much control over the data in your tables as you wish. Las limitaciones de darte el máximo control sobre los datos en las tablas que desee. If a user attempts to store data in a column that would violate a constraint, an error is raised. Si un usuario intenta guardar datos en una columna que viole una limitación, un error. This applies even if the value came from the default value definition. Esto se aplica incluso si el valor ha venido de la definición de valor por defecto.

5.3.1. 5.3.1. Check Constraints Compruebe Limitaciones A check constraint is the most generic constraint type. Un cheque es la limitación más genérica limitación tipo. It allows you to specify that the value in a certain column must satisfy a Boolean (truth-value) expression. Le permite especificar que el valor de una determinada columna debe cumplir un booleano (verdad-valor) de expresión. For instance, to require positive product prices, you could use: Por ejemplo, exigir a los precios de los productos positivo, se puede usar:

14

Page 15: Manual Postgres

CREATE TABLE products ( CREATE TABLE productos ( product_no integer, product_no entero, name text, Nombre del texto, price numeric CHECK (price > 0) precio numérico CHECK (precio> 0) ); );

As you see, the constraint definition comes after the data type, just like default value definitions. Como puede ver, la dificultad viene después de la definición de tipo de datos, como valor por defecto definiciones. Default values and constraints can be listed in any order. Valores por defecto y las limitaciones se pueden enumerar en cualquier orden. A check constraint consists of the key word CHECK followed by an expression in parentheses. Un cheque limitación consiste en la palabra clave VERIFICA seguido por una expresión en paréntesis. The check constraint expression should involve the column thus constrained, otherwise the constraint would not make too much sense. El cheque debe implicar limitación expresión de la columna por lo tanto, limitado, de lo contrario la limitación no tendría demasiado sentido.

You can also give the constraint a separate name. También puede dar el nombre de una limitación. This clarifies error messages and allows you to refer to the constraint when you need to change it. Esto clarifica los mensajes de error y le permite hacer referencia a la limitación cuando es necesario cambiarlo. The syntax is: La sintaxis es:

CREATE TABLE products ( CREATE TABLE productos ( product_no integer, product_no entero, name text, Nombre del texto, price numeric CONSTRAINT positive_price CHECK (price > 0) precio numérico positive_price CONSTRAINT CHECK (precio> 0) ); );

So, to specify a named constraint, use the key word CONSTRAINT followed by an identifier followed by the constraint definition. Así, para especificar el nombre de una limitación, el uso de la palabra clave CONSTRAINT seguido de un identificador seguido por la limitación definición. (If you don't specify a constraint name in this way, the system chooses a name for you.) (Si no especifica una limitación en nombre de esta manera, el sistema elige un nombre para usted.)

A check constraint can also refer to several columns. Una limitación de verificación también puede referirse a varias columnas. Say you store a regular price and a discounted price, and you want to ensure that the discounted price is lower than the regular price: Supongamos que una tienda de precios y un descuento en el precio, y quiere asegurarse de que el precio es inferior al precio regular:

CREATE TABLE products ( CREATE TABLE productos ( product_no integer, product_no entero, name text, Nombre del texto, price numeric CHECK (price > 0), precio numérico CHECK (precio> 0), discounted_price numeric CHECK (discounted_price > 0), discounted_price numérico CHECK (discounted_price> 0), CHECK (price > discounted_price) CHECK (precio> discounted_price) ); );

The first two constraints should look familiar. Las dos primeras limitaciones que parece familiar. The third one uses a new syntax. El tercero utiliza una nueva sintaxis. It is not attached to a particular column, instead it appears as a separate item in the comma-separated column list. No se adjunta a una columna, sino que aparece como un tema separado en la columna separados por comas lista. Column definitions and these constraint definitions can be listed in mixed order. Columna de definiciones y definiciones de estas limitaciones pueden ser listados en orden mixto.

15

Page 16: Manual Postgres

We say that the first two constraints are column constraints, whereas the third one is a table constraint because it is written separately from any one column definition. Nosotros decimos que las dos primeras restricciones son las limitaciones de la columna, mientras que la tercera es una tabla limitación porque se escribe separado de cualquier columna de una definición. Column constraints can also be written as table constraints, while the reverse is not necessarily possible, since a column constraint is supposed to refer to only the column it is attached to. Las limitaciones de la columna también puede ser escrito como las limitaciones de la tabla, mientras que a la inversa no es necesariamente posible, desde una columna de limitación se supone que sólo se refieren a la columna que va adherida. ( PostgreSQL doesn't enforce that rule, but you should follow it if you want your table definitions to work with other database systems.) The above example could also be written as: (PostgreSQL no hace cumplir esta norma, pero usted debe seguir si desea que su tabla de definiciones para trabajar con otros sistemas de bases de datos). El ejemplo anterior también puede ser escrito como:

CREATE TABLE products ( CREATE TABLE productos ( product_no integer, product_no entero, name text, Nombre del texto, price numeric, precio numérico, CHECK (price > 0), CHECK (precio> 0), discounted_price numeric, discounted_price numérico, CHECK (discounted_price > 0), CHECK (discounted_price> 0), CHECK (price > discounted_price) CHECK (precio> discounted_price) ); );

or even: o incluso:

CREATE TABLE products ( CREATE TABLE productos ( product_no integer, product_no entero, name text, Nombre del texto, price numeric CHECK (price > 0), precio numérico CHECK (precio> 0), discounted_price numeric, discounted_price numérico, CHECK (discounted_price > 0 AND price > discounted_price) CHECK (discounted_price> 0 AND precio> discounted_price) ); );

It's a matter of taste. Es una cuestión de gusto.

Names can be assigned to table constraints in just the same way as for column constraints: Nombres pueden ser asignados a las limitaciones en el cuadro del mismo modo que las limitaciones para la columna:

CREATE TABLE products ( CREATE TABLE productos ( product_no integer, product_no entero, name text, Nombre del texto, price numeric, precio numérico, CHECK (price > 0), CHECK (precio> 0), discounted_price numeric, discounted_price numérico, CHECK (discounted_price > 0), CHECK (discounted_price> 0), CONSTRAINT valid_discount CHECK (price > discounted_price) Valid_discount CONSTRAINT CHECK (precio> discounted_price) ); );

It should be noted that a check constraint is satisfied if the check expression evaluates to true or the null value. Cabe señalar que una restricción de verificación se cumple si la expresión se evalúa para comprobar la verdad o el valor nulo. Since most expressions will evaluate to the null value if any operand is null, they will not prevent null values in the constrained columns. Dado que la mayoría de expresiones evaluará al valor nulo si algún operando es nulo, que no impedirá valores nulos en las columnas limitada. To ensure that a

16

Page 17: Manual Postgres

column does not contain null values, the not-null constraint described in the next section can be used. Para asegurarse de que una columna no contiene valores nulos, el no-nula limitación descrita en la siguiente sección se puede utilizar.

5.3.2. 5.3.2. Not-Null Constraints No nulo-Limitaciones A not-null constraint simply specifies that a column must not assume the null value. Una limitación no nulo, simplemente se especifica que una columna no debe asumir el valor nulo. A syntax example: Un ejemplo de sintaxis:

CREATE TABLE products ( CREATE TABLE productos ( product_no integer NOT NULL , product_no integer NOT NULL, name text NOT NULL , de texto Nombre de NOT NULL, price numeric precio numérico ); );

A not-null constraint is always written as a column constraint. Una limitación no nulo es siempre como una columna escrita limitación. A not-null constraint is functionally equivalent to creating a check constraint CHECK ( column_name IS NOT NULL) , but in PostgreSQL creating an explicit not-null constraint is more efficient. Un no-nula limitación es funcionalmente equivalente a la creación de un cheque limitación CHECK (COLUMN_NAME IS NOT NULL), pero en la creación de un PostgreSQL explícita no nulo limitación es más eficiente. The drawback is that you cannot give explicit names to not-null constraints created this way. El inconveniente es que no se pueden dar nombres para no explícita nulo limitaciones creadas de esta manera.

Of course, a column can have more than one constraint. Por supuesto, una columna puede tener más de una limitación. Just write the constraints one after another: Simplemente escriba las limitaciones, uno tras otro:

CREATE TABLE products ( CREATE TABLE productos ( product_no integer NOT NULL, product_no integer NOT NULL, name text NOT NULL, de texto Nombre de NOT NULL, price numeric NOT NULL CHECK (price > 0) precio numérico NOT NULL CHECK (precio> 0) ); );

The order doesn't matter. El orden no importa. It does not necessarily determine in which order the constraints are checked. No determina necesariamente el orden en que las limitaciones están marcadas.

The NOT NULL constraint has an inverse: the NULL constraint. La restricción NOT NULL tiene una inversa: la limitación NULL. This does not mean that the column must be null, which would surely be useless. Esto no significa que la columna debe ser nulo, lo que sin duda ser inútil. Instead, this simply selects the default behavior that the column might be null. En lugar de ello, simplemente selecciona el comportamiento por defecto de la columna que puede ser nula. The NULL constraint is not present in the SQL standard and should not be used in portable applications. NULL limitación no está presente en el estándar SQL y no debe utilizarse en aplicaciones portátiles. (It was only added to PostgreSQL to be compatible with some other database systems.) Some users, however, like it because it makes it easy to toggle the constraint in a script file. (Se añade a PostgreSQL sólo para ser compatible con otros sistemas de bases de datos.) Algunos usuarios, sin embargo, porque lo hace fácil para cambiar la restricción en un archivo de comandos. For example, you could start with: Por ejemplo, usted podría empezar con:

CREATE TABLE products ( CREATE TABLE productos ( product_no integer NULL, product_no entero NULL, name text NULL, de texto Nombre de NULL,

17

Page 18: Manual Postgres

price numeric NULL precio numérico NULL ); );

and then insert the NOT key word where desired. y, a continuación, insertar la palabra clave que no desea.

Tip: In most database designs the majority of columns should be marked not null. Sugerencia: En la mayoría de los diseños de base de datos la mayoría de las columnas no deben estar marcados nula.

5.3.3. Unique Constraints Limitaciones única Única limitaciones asegurar que los datos contenidos en una columna o un grupo de columnas es única con respecto a todas las filas en la tabla. La sintaxis es:

CREATE TABLE productos ( product_no integer UNIQUE , Nombre text, precio numeric );

cuando una columna escrita como obstáculo, y:

CREATE TABLE productos ( product_no integer, Nombre text, precio numeric, UNIQUE (product_no) ÚNICO (product_no) );

cuando se escribe como una tabla de restricción.

Si una única restricción se refiere a un grupo de columnas, las columnas se enumeran separados por comas:

CREATE TABLE example a integer, b integer, c integer, UNIQUE (a, c) );

Esto especifica que la combinación de los valores indicados en las columnas es única en toda la tabla, aunque cualquiera de las columnas no tienen por qué ser (y normalmente no es) única.

Puede asignar su propio nombre para una única limitación, en la forma habitual:

CREATE TABLE productos ( product_no integer CONSTRAINT must_be_different UNIQUE, Nombre del text, precio numeric );

En general, una única limitación es violada cuando hay dos o más filas en la mesa donde los valores de todas las columnas incluidas en la restricción son iguales. Sin embargo, dos valores nulos no se consideran iguales en esta comparación. Esto significa que, incluso en presencia de una única limitación es posible almacenar por duplicado filas que contengan un valor nulo en al menos una de las columnas limitada. Este

18

Page 19: Manual Postgres

comportamiento se ajusta al estándar SQL, pero hemos escuchado que otras bases de datos SQL puede no seguir esta regla. Así que tenga cuidado al desarrollo de aplicaciones que están destinados a ser portátil.

5.3.4. Primary Keys Claves primarias Técnicamente, una clave principal obstáculo es simplemente una combinación de una limitación y no una limitación nulo.Así pues, las siguientes dos definiciones mesa aceptar los mismos datos:

CREATE TABLE productos ( product_no integer UNIQUE NOT NULL, Nombre text, precio numeric );

CREATE TABLE productos ( product_no integer PRIMARY KEY , nombre text, precio numeric );

Primary keys (Claves primarias) también pueden limitar más de una columna, la sintaxis es similar a la única limitaciones:

CREATE TABLE ejemplo ( a integer, b integer, c integer, PRIMARY KEY (a, c) );

Una clave principal se indica que una columna o grupo de columnas puede ser utilizado como un identificador único para las filas en la tabla. (Esta es una consecuencia directa de la definición de una clave principal. Tenga en cuenta que una limitación no, por sí sola, proporcionar un identificador único, ya que no excluye valores nulos.) Esto es útil tanto para propósitos de documentación y de las aplicaciones cliente. Por ejemplo, una aplicación GUI que permite modificar los valores fila probablemente necesita saber la clave principal de una tabla para poder identificar las filas única.

Una tabla puede tener como máximo una clave principal. (No puede ser cualquier número de único y no nulo limitaciones, que son funcionalmente lo mismo, pero sólo uno puede ser identificado como la clave principal.) Base de datos relacional de la teoría dicta que cada mesa debe tener una clave principal. Esta regla no es aplicada por PostgreSQL, pero es mejor seguirla.

5.3.5. Foreign Keys Clave Foranea Una clave foránea se especifica que los valores en una columna (o un grupo de columnas) debe coincidir con los valores que aparecen en algunos fila de otra tabla. Nosotros decimos lo que mantiene la integridad referencial entre dos tablas relacionadas.

Que tiene la tabla de productos que hemos utilizado en varias ocasiones:

CREATE TABLE productos ( product_no integer PRIMARY KEY, nombre text, precio numeric

19

Page 20: Manual Postgres

);

Vamos a suponer también que haya una mesa de almacenar los pedidos de estos productos. Queremos asegurarnos de que las órdenes cuadro sólo contiene las órdenes de los productos a los que realmente existen. Por lo tanto, definir una clave foránea en la tabla de pedidos que las referencias de los productos de mesa:

CREATE TABLE pedidos ( order_id integer PRIMARY KEY, product_no integer REFERENCES products (product_no) , cantidad integer );

Ahora es imposible crear órdenes product_no con entradas que no aparecen en la tabla de productos.

Nosotros decimos que en esta situación, la tabla se ordena la tabla de referencia y los productos de mesa es la tabla referenciada. Del mismo modo, hay referencias y se hace referencia columnas.

También puede acortar el comando de arriba a:

CREATE TABLE pedidos ( order_id integer PRIMARY KEY, product_no integer REFERENCES products , cantidad integer );

porque en ausencia de una lista de columnas de la clave primaria de la tabla de referencia se utiliza como referencia la columna (s).

Un extranjero puede también limitar la clave de referencia y un grupo de columnas. Como de costumbre, entonces tiene que estar escrito en forma de mesa limitación. Aquí está un ejemplo contribuido sintaxis:

CREATE TABLE t1 a integer PRIMARY KEY, b integer, c integer, FOREIGN KEY (b, c) REFERENCES other_table (c1, c2) );

Por supuesto, el número y tipo de columnas de la limitada necesidad de adaptar el número y el tipo de referencia de la columnas.

Puede asignar su propio nombre para una clave foránea, en la forma habitual.

Un cuadro puede contener más de una clave foránea. Este es usado para aplicar muchos-a-muchas relaciones entre tablas. Que tiene tablas sobre los productos y pedidos, pero ahora usted desea permitir que un fin de contener posiblemente muchos productos (por encima de la estructura que no permite). Usted podría utilizar esta estructura de tabla:

CREATE TABLE productos ( product_no integer PRIMARY KEY, nombre text, precio numeric );

CREATE TABLE pedidos ( order_id integer PRIMARY KEY,

20

Page 21: Manual Postgres

shipping_address text, ... ... ); );

CREATE TABLE order_items ( product_no integer REFERENCES products, order_id integer REFERENCES orders, cantidad integer , PRIMARY KEY (product_no, order_id) );

Observe que la clave principal se superpone con las claves foráneas en la última mesa.

Sabemos que las claves foráneas rechazar la creación de los pedidos que no se refieren a los productos. Pero lo que si un producto es removido después de un fin se ha creado lo que las referencias? SQL le permite manejar eso. Intuitivamente, tenemos algunas opciones:

Inhabilitar eliminar un producto de referencia

Eliminar las órdenes y

Otra cosa?

Para ilustrar esto, vamos a aplicar la siguiente política sobre los muchos-a-muchos relación ejemplo anterior: cuando alguien quiere eliminar un producto que sigue siendo de referencia por una orden (a través de order_items), que rechace la misma. Si alguien quita una orden, el orden se eliminan los artículos así como:

CREATE TABLE productos ( product_no integer PRIMARY KEY, nombre text, precio numeric );

CREATE TABLE orders ( CREATE TABLE pedidos ( order_id integer PRIMARY KEY, order_id entero PRIMARY KEY, shipping_address text, shipping_address texto, ... ... ); );

CREATE TABLE order_items ( CREATE TABLE order_items ( product_no integer REFERENCES products ON DELETE RESTRICT , REFERENCIAS productos product_no entero ON DELETE restringir, order_id integer REFERENCES orders ON DELETE CASCADE , REFERENCIAS order_id entero órdenes ON DELETE CASCADE, quantity integer, cantidad entero, PRIMARY KEY (product_no, order_id) PRIMARY KEY (product_no, order_id) ); );

Restricting and cascading deletes are the two most common options. RESTRICT prevents deletion of a referenced row. NO ACTION means that if any referencing rows still exist when the constraint is checked, an error is raised; this is the default behavior if you do not specify anything. Restringir y elimina en cascada son las dos opciones más comunes. RESTRINGIR impide la supresión de una referencia a la fila. ACCIÓN NO significa que si cualquier referencia filas siguen existiendo cuando la limitación está marcada, se planteó un error, que es el comportamiento por defecto si no especifica cualquier cosa. (The essential difference between these two choices is that NO ACTION allows the check to be deferred until later in the transaction, whereas RESTRICT does not.) CASCADE specifies that when a referenced row is deleted, row(s) referencing it

21

Page 22: Manual Postgres

should be automatically deleted as well. (La diferencia esencial entre estas dos opciones es que no permite que el cheque que se aplace hasta después de la transacción, mientras que no restringir.) CASCADE se especifica que cuando uno se hace referencia, se suprime la fila, fila (s) de referencia debería ser eliminado automáticamente también. There are two other options: SET NULL and SET DEFAULT . Hay otras dos opciones: SET NULL y SET DEFAULT. These cause the referencing columns to be set to nulls or default values, respectively, when the referenced row is deleted. Estas referencias a la causa columnas a ser fijados a los valores por defecto o nulos, respectivamente, cuando la fila se hace referencia, se suprime. Note that these do not excuse you from observing any constraints. Tenga en cuenta que estos no le exime de la observación de las limitaciones. For example, if an action specifies SET DEFAULT but the default value would not satisfy the foreign key, the operation will fail. Por ejemplo, si una acción SET DEFAULT especifica el valor por defecto pero no se ajustaría a la clave foránea, la operación fracasará.

Analogous to ON DELETE there is also ON UPDATE which is invoked when a referenced column is changed (updated). Análoga a ON DELETE es también ON UPDATE que se invoca cuando una columna se hace referencia se cambia (actualizado). The possible actions are the same. Las acciones posibles son las mismas.

More information about updating and deleting data is in Chapter 6 . Más información acerca de la actualización y supresión de datos en el capítulo 6.

Finally, we should mention that a foreign key must reference columns that either are a primary key or form a unique constraint. Por último, debemos mencionar que una clave foránea debe hacer referencia a las columnas que, o bien son una clave principal o una forma única limitación. If the foreign key references a unique constraint, there are some additional possibilities regarding how null values are matched. Si la clave foránea hace referencia a un único obstáculo, hay algunas otras posibilidades con respecto a cómo se comparan valores nulos. These are explained in the reference documentation for CREATE TABLE . Estos se explican en la documentación de referencia para CREATE TABLE.

22