You are on page 1of 158

Memorias

PostgreSQL Gua Prctica

ING. SERGIO ARBEY MONSALVE BETANCUR

Medelln-Colombia, 1 de Junio del 2013


Sergio_monsa@hotmail.com

Indice
ndice
Que es PostgreSQL
Historia y Antecedentes
Ventajas de PostgreSQL
Caractersticas de PostgreSQL
Herramientas de PostgreSQL
Comparacin de sistemas administradores de bases de datos relacionales
Informacin general
Soporte del sistema operativo
Caractersticas fundamentales
Tablas y vistas
ndices
Otros objetos
Particionamiento
Arquitectura Conceptual de PostgreSQL
Front End (Cliente - Servidor)
Postmaster
Back End - Arquitectura General del Servidor de Postgres
Intrprete
Polica de trfico
Planificador / Optimizador
Ejecutor
Administracin de Datos
Almacenamiento de Datos
Conclusin
Instalar y Configurar el PostgreSQL 9.x
Instalacin del Servidor de Bases de Datos PostgreSQL 9.x
Configurar el PostgreSQL 9.2
Habilitar Conexiones Remotas al Servidor PostgreSQL 9.2
Optimizacin
Instalar el PostgreSQL en un Directorio Diferente
Instalar el PostgreSQL en un Directorio Diferente usando tablespace
Directorios y Archivos de PostgreSQL
Ubicaciones de los directorios y archivos de PostgrSQL en Linux
Ubicaciones de los directorios y archivos de Datos PostgrSQL en Linux
PostgreSQL Lmites de espacio en disco
Dnde estn nuestros datos en el disco?
Bloques de datos en el disco
PostgreSQL: Espacio en Disco
Tipos de Tablas
Tipos de Datos

2
5
6
7
8
13
15
15
15
16
17
17
18
19
20
21
22
22
23
23
23
23
23
25
27
28
28
32
38
38
41
42
43
43
43
45
46
48
50
50
51

Indice
Gestin de Bases de Datos PostgreSQL
PSQL: La pequea gran herramienta de PostgreSQL
Ejecutando psql desde el sistema operativo
Ejecutando psql en modo interactivo
Controlando una Sesin en psql en modo interactivo
Query multi-lnea en modo interactivo
Usando valores NULL y BLANK
Valores DEFAULT
pg_dump y pg_dumpall
pg_restore
createdb y dropdb
Postmaster y pg_ctl
PgAdmin
Administracin de sesiones
Inicio y Tipos de sesiones
Control de sesiones
Caso de Estudio
Sentencias DDL
CREATE
ALTER .. ADD
ALTER .. DROP
DROP
TRUNCATE
Sentencias DML
SELECT
INSERT
UPDATE
DELETE
Sentencias TCL
COMMIT
SAVEPOINT
RELEASE SAVEPOINT
ROLLBAK
Instalar Script
Caso de Estudio - Continuacin
Sentencias DCL
GRANT
REVOKE
Sentencias XML

54
54
55
58
61
62
63
64
64
66
67
68
69
71
71
71
75
76
76
85
89
92
95
96
96
104
105
106
109
109
109
110
111
114
117
119
119
120
128

Indice
PLpgSQL
Introduccin
Estructura
Utilizacin mediante SELECT
DECLARE
Insertar Datos en una Tabla
Actualizar Datos en una Tabla
Utilizar ROW TYPES
Cursores
Cursores Implcitos con FOR <VAR> IN <QUERY>
Triggers
Validacin
Valores Calculados
Manejo de Errores
Ejercicio Red Social
Consultas Enumeradas
Consultas, Funciones, Procedimientos y Vistas
Consultas
Funciones
Procedimientos
Vistas
Funciones Ventana (Windows Functions)
Automatizacin de Backups
Bibliografia

131
131
131
132
132
132
133
135
136
138
138
140
140
141
142
147
149
149
150
151
151
153
156
158

Que es PostgreSQL
PostgreSQL es un Sistema de Gestin de Bases de Datos Objeto-Relacionales
(ORDBMS) que ha sido desarrollado de varias formas desde la dcada de 1980 y
es un proyecto de software libre distribuido bajo licencia BSD (Berkeley Software
Distribution) y creado con el aporte de varios colaboradores y auspiciantes a nivel
mundial bajo los estndares de ANSI-SQL 92/99.
Con ms de dos dcada de desarrollo, PostgreSQL se ha convertido en la base de
datos de cdigo abierto y con orientacin a objetos ms avanzada disponible en el
momento, ofreciendo las caractersticas propias de los ms potentes motores de
bases de datos comerciales como Oracle, DB2 o SQLServer.
PostgreSQL es el ltimo resultado de una larga evolucin comenzada con el
proyecto de bases de datos relacionales Ingres en la Universidad de Berkeley.
Luego se inici el proyecto Post-Ingres para resolver los problemas con el modelo
de base de datos relacional que se haban presentado.
El proyecto resultante llamado Postgres complet el soporte de tipos de datos y la
base de datos comprenda tambin las relaciones entre tablas o clases.
El proyecto PostgreSQL sigue actualmente un activo proceso de desarrollo a nivel
mundial gracias a un equipo de desarrolladores y contribuidores de cdigo abierto.
PostgreSQL es ampliamente considerado como una de las alternativas de sistema
de bases de datos de cdigo abierto.
El sitio web oficial de PostgreSQL es;
http://www.postgresql.org

Historia y Antecedentes
La implementacin del DBMS (Sistema Manejador de Bases de Datos) Postgres
comenz a desarrollarse en 1986 con la coordinacin del profesor Michael
Stonebraker, y fue patrocinado por algunas fundaciones estatales y militares de
investigacin.
Los conceptos inciales para el sistema fueron presentados con la definicin del
modelo de datos inicial junto con la lgica y arquitectura del gestor de
almacenamiento; desde entonces, Postgres ha pasado por varias versiones. El
primer sistema de pruebas fue operacional en el ao 1987 y la Versin 1 fue
lanzada a unos pocos usuarios en Junio de 1989; despus de revisar el sistema
de reglas de la primera versin, ste fue rediseado y la Versin 2 se lanz en
Junio de 1990. La Versin 3 apareci en 1991 y aadi una implementacin para
mltiples gestores de almacenamiento, un ejecutor de consultas mejorado junto
con un mejor sistema de reglas. En su mayor parte, las siguientes versiones hasta
el lanzamiento de Postgres95 se centraron en los temas de portabilidad y
fiabilidad.
El mantenimiento del cdigo y las tareas de soporte ocupaban demasiado tiempo
que deba dedicarse a la investigacin, as que el proyecto termin oficialmente
con el lanzamiento de la Versin 4.2.
En 1994, Andrew Yu y Jolly Chen aadieron un intrprete de lenguage SQL
(Lenguaje Estructurado de Consultas) a Postgres y el proyecto se denomin
Postgres95, el mismo que fue lanzado a continuacin en la Web para que
encontrara su sitio en el mundo de los gestores de bases de datos como un
descendiente de dominio pblico y cdigo abierto del cdigo original Postgres de
Berkeley. El cdigo de Postgres95 fue optimizado y reducido en tamao en un
25% respecto a sus predecesores; muchos cambios internos mejoraron el
rendimiento y la facilidad de mantenimiento. Postgres95 en su versin v1.0 se
ejecutaba en un 30 a 50% ms rpido que Postgres v4.2 y adems de su
correccin de errores, el lenguaje de consultas Postquel fue reemplazado con SQL
(implementado en el servidor). Tambin se incluy un nuevo programa (psql) para
realizar consultas SQL interactivas.
En 1996 nace el proyecto PostgreSQL, siendo una nueva versin de Postgres95,
tratando de reflejar la relacin entre el Postgres original y las versiones ms
recientes con capacidades de SQL. Los nmeros de versin parten de la 6.0,
volviendo a la secuencia seguida originalmente por el proyecto Postgres de
Berkeley.
El nfasis durante el desarrollo de Postgres95 estaba orientado a identificar,
entender y mejorar los problemas existentes en el cdigo del servidor. Con
PostgreSQL, adems de estas mejoras se puso nfasis para aumentar las
6

caractersticas y capacidades del servidor de bases de datos utilizando los


estndares SQL92/SQL99.
PostgreSQL se distribuye bajo la licencia BSD. La licencia BSD al contrario que la
GPL permite el uso del cdigo fuente en software no libre.
El autor, bajo este tipo de licencia, mantiene la proteccin de copyright nicamente
para la renuncia de garanta y para requerir la adecuada atribucin de la autora
en los trabajos derivados, pero permite la libre redistribucin y modificacin, por lo
que pienso que esta licencia asegura un verdadero software libre, en el sentido
que el usuario tiene libertad ilimitada con respecto al software, y que puede decidir
incluso si redistribuirlo como software no libre.
Actualmente la ltima versin de PostgreSQL disponible para descargar desde su
sitio web:
http://www.postgresql.org/download/

Ventajas de PostgreSQL
Instalacin Ilimitada
Con PostgreSQL, nadie puede demandarlo por violar acuerdos de licencia,
puesto que no hay costo asociado a la licencia del software.
Soporte
Adems de las ofertas de soporte comercial, hay una importante comunidad de
profesionales y entusiastas de PostgreSQL de los que su compaa puede
obtener beneficios y contribuir.
Ahorros considerables en costos de operacin
Ha sido diseado y creado para tener un mantenimiento y ajuste mucho menor
que otros productos, conservando todas las caractersticas, estabilidad y
rendimiento.
Estabilidad y Confiabilidad Legendarias
Es extremadamente comn que compaas reporten que PostgreSQL nunca ha
presentado cadas en varios aos de operacin de alta actividad. Ni una sola
vez. Simplemente funciona.
Multiplataforma
PostgreSQL est disponible en casi cualquier Unix (34 plataformas en la ltima
versin estable - Linux, UNIX, AIX, BSD, HP-UX, Mac OS X, Solaris) y ahora en
versin nativa para Windows.
Extensible
El cdigo fuente est disponible para todos sin costo. Si su equipo necesita
extender o personalizar PostgreSQL de alguna manera, pueden hacerlo con un
mnimo esfuerzo, sin costos adicionales.
Esto es complementado por la comunidad de profesionales y entusiastas de
PostgreSQL alrededor del mundo que tambin extienden PostgreSQL todos los
das.
Diseado para ambientes de alto volumen
PostgreSQL usa una estrategia de almacenamiento de filas llamada MVCC
para conseguir una mejor respuesta en ambientes de grandes volmenes. Los

principales proveedores de sistemas de bases de datos comerciales usan


tambin esta tecnologa, por las mismas razones.
Herramientas grficas de diseo y administracin de BD
Existen varias herramientas grficas de alta calidad para administrar las bases
de datos (pgAdmin , pgAccess) y para hacer diseo de bases de datos (Tora ,
Data Architect).

Caractersticas de PostgreSQL
A continuacin se presentan las ms importantes caractersticas de este sistema
manejador de bases de datos por la cuales es considerado uno de los ms
potentes gestores de bases de datos en el mundo del software libre:
Soporte SQL92/SQL99
Implementa los estndares SQL92/SQL99 con sus operadores, funciones,
clusulas y comandos (DDL y DML), junto con comandos extendidos de
PostgreSQL.
Transacciones
Posee un completo soporte para control de transacciones asegurando la
integridad y consistencia de los datos
Permiten el paso entre dos estados consistentes manteniendo la integridad de
los datos. Un bloque de transacciones comienza con una sentencia BEGIN
WORK y si la transaccin fue vlida se cierra con COMMIT WORK o END
WORK. Si la transaccin falla, se cierra con ABORT o ROLLBACK WORK.
BEGIN WORK;
.......
Sentencias SQL;
.......
COMMIT WORK;
Integridad referencial
PostgreSQL soporta integridad referencial, la cual es utilizada para garantizar la
validez de los datos de la base de datos.
Soporte completo de ACID (Atomicity Consistency Isolation Durability)
Operaciones Atmicas, formadas por comandos que se ejecutan todos o
ninguno de ellos.
Consistencia, que garantiza que la base de datos nunca se quede en un estado
intermedio de una transaccin (con parte de los comandos ejecutados y otra
parte que no).
Aislamiento, que mantiene separadas las transacciones de usuarios distintos
hasta que stas han terminado, es decir controlando la concurrencia de
usuarios.
10

Durabilidad, garantizando que el servidor de bases de datos guarde en un


registro o log de transacciones las actualizaciones realizadas y pendientes de
forma tal que pueda recuperarse de una terminacin brusca como un corte de
energa en la mquina.
MVCC (Control de Concurrencia Multi-Versin)
Tecnologa que PostgreSQL usa para mantener la concurrencia de usuarios y
evitar bloqueos innecesarios de la base de datos.
Bloqueos de tabla y filas
Hay varios modos de bloqueo para controlar el acceso concurrente a los datos
en tablas Algunos de estos modos de bloqueo los adquiere PostgreSQL
automticamente antes de la ejecucin de una declaracin, mientras que otros
son proporcionados para ser usados por las aplicaciones.
Procedimientos almacenados
Permiten optimizar y acelerar las aplicaciones y evitan transferencias
innecesarias a travs de la red.
Constraints y triggers
Tienen la funcin de mantener la integridad y consistencia en la BD. Ejecucin
de acciones antes o despus de un evento de BD.
Multiples tipos de datos predefinidos
Como todos los manejadores de bases de datos, PostgreSQL implementa los
tipos de datos definidos para el estndar SQL3 y aumenta algunos otros.
Soporte de tipos y funciones de usuario
PostgreSQL soporta operadores, funciones mtodos de acceso y tipos de datos
definidos por el usuario.
Incorpora una estructura de datos Array.
Conectividad TCP/IP, JDBC y ODBC
Interfaz con diversos lenguajes
C, C++, Java, Delphi, Python, Perl, PHP, Bash, .....
Savepoints

11

Permite hacer un rolled back sin tener que repetir la transaccin entera.
Point in Time Recovery
Permite salvar el estado de la DB en momentos concretos, para su posterior
recuperacin.
Tablespaces
Permite destinar discos fsicos a un ndice o a una tabla concreta.
Improved Memory and I/O
Optimizaciones en la velocidad de ejecucin y en el consumo de memoria de la
aplicacin.
Aadidos o ampliados
Lenguajes de procedimientos almacenados PL/Java, PL/J, PL/PHP y PL/Perl.
Seguridad
Gestin correcta de usuarios, grupos de usuarios y contraseas, as como
tambin los permisos asignados a cada uno de ellos.
Respaldos (Backups) y Recuperacin caliente
Respaldos y Recuperacin completa de las bases de datos mientras trabaja el
servidor PostgreSQL
Replicacin
Con servidores PostgreSQL funcionando como maestros y otros como
esclavos. Todas las transacciones se las realiza primero en el servidor maestro
para que se puedan actualizar en los esclavos. La replicacin es un proceso
asncrono en PostgreSQL, y se la realiza gracias a un archivo llamado binary
Log que contiene la informacin de las modificaciones y actualizaciones entre
un nodo maestro y uno o mltiples esclavos; la replicacin con servidores
PostgreSQL es un proceso independiente del servidor.
Herencia entre tablas
Por lo que a este gestor de bases de datos se le incluye entre los gestores
objeto-relacionales.

12

Herramientas de PostgreSQL
Existen herramientas libres y gratuitas con interfaces grficas e intuitivas y fciles
de utilizar para la administracin completa de bases de datos PostgreSQL como
son PhpPgAdmin o el PgAdmin que son auspiciados por los mismos creadores del
sistema PostgreSQL. Tambin existen algunas herramientas comerciales entre las
que destaco por su funcionalidad a PostgreSQL Manager.
As tambin hay una variedad de herramientas para la administracin de bases de
datos PostgreSQL en modo consola, fabricadas por los mismos creadores de
PostgreSQL (http://www.postgresql.org) como son por ejemplo el terminal de
cliente interactivo de postgreSQL psql, o las aplicaciones para realizar copias de
seguridad y restauracin de base de datos pg_dump y pg_restore, o herramientas
cliente para crear y eliminar bases de datos como cretedb, dropdb entre otras que
son incluidas en la descarga completa del servidor PostgreSQL.
PgAdmin3
Es una interfaz comprensible para el diseo y administracin de una base de
datos PostgreSQL, diseada para ejecutarse en la mayora de los Sistemas
Operativos.
La aplicacin corre bajo GNU/Linux, FreeBSD y Windows.
La interfaz grfica soporta todas las caractersticas de PostgreSQL y facilita la
administracin.
Tambin incluye un Diseador de Consultas Grfico.
PHPPgAdmin
PHPPgAdmin es una poderosa herramienta de administracin basada en un
interfaz Web para bases de datos PostgreSQL.
Adems de la funcionalidad bsica, dispone de soporte para procedimientos
almacenados, triggers y vistas.
Las versiones de punta van mano a mano con el desarrollo del servidor
PostgreSQL.
Esta versin es una de las ms famosas de los administradores GUI para
PostgreSQL.

13

PSQL
Es la herramienta cannica para la ejecucin de sentencias SQL a travs del
shell del SO.
Es una herramienta de tipo frontend que permite describir sentencias SQL,
ejecutarlas y visualizar sus resultados.
El mtodo de ingreso puede ser mediante la insercin directa del cdigo en la
consola, o la ejecucin de sentencias dentro de un archivo de texto.
Provee diversos meta-comandos para la ejecucin de las sentencias, as como
diversas opciones tipo shell propias de la herramienta.
PgExplorer
PgExplorer es una herramienta de desarrollo para Postgres con una amplia
interfaz grfica.
Entre sus caractersticas se incluye una vista en rbol de las bases de datos y
sus respectivos objetos.
Se puede realizar ingeniera inversa a travs de sentencias SQL o scripts
personalizados.
Hay una amplia gama de asistentes que guan a travs del proceso necesario
para generar comandos SQL para varios objetos y sentencias.
Tambin incluye un Diseador de Consultas Grfico.

14

Comparacin de sistemas administradores de bases de datos


relacionales
Las siguientes tablas comparan informacin general y tcnica de
diferentes RDBMS. Para ms informacin, vea los enlaces de cada producto. No
se incluyen todas.

Informacin general
Creador
Adaptive
Server
Sybase/iAnywhere
Anywhere
Adaptive
Server
Sybase Inc
Enterprise
ANTs Data Server
ANTs Software
DB2
IBM

ltima
Fecha de la primera
versin
versin pblica
estable

Licencia
software

1992

10.0

Propietario

1987

15.0

Propietario

1999
1982

3.6
9

de

[Firebird]

Firebird Foundation

25 de julio de 2000

2.1

Informix
HSQLDB

1985
2001

10.0
1.9

1980

2006

CA-TOSL

InterBase

Informix Software
Hsqldb.Org
Berkeley
University, Computer
Associates
Borland

Propietario
Propietario
Licencia Pblica
InterBase
Propietario
Licencia BSD

1985

7.5.1

SapDB

SAP AG

MaxDB
Microsoft SQL Server
MySQL
Oracle

MySQL AB, SAP AG


?
Microsoft
1989
MySQL AB
Noviembre de 1996
Oracle Corporation
1977
PostgreSQL
Global
Junio de 1989
Development Group
SmallSQL
16 de abril de 2005
D. Richard Hipp
17 de agosto de 2000

Ingres

PostgreSQL
SmallSQL
SQLite

Propietario
GPL con
7.4
drivers LGPL
7.7
GPL o propietario
2008
Propietario
5.0
GPL o propietario
11g Release 2 Propietario
9.0

Licencia BSD

0.12
3.6.16
ltima
Fecha de la primera
versin
versin pblica
estable

Creador

LGPL
Dominio pblico
Licencia
software

de

Soporte del sistema operativo


Windows
Adaptive
Enterprise

Server

Mac OS X

Linux

BSD

Unix

z/OS

ANTs Data Server

DB2

Quiz

[[Firebird]]

No
?

15

HSQLDB

Informix

Ingres

InterBase

No

No

S (Solaris)

SapDB

No

No

MaxDB

No

No

Microsoft SQL Server

No

No

No

No

MySQL

No
Quiz

Oracle

PostgreSQL

No

SmallSQL

S
Linux

S
BSD

S
Unix

Quiz

SQLite

S
Windows

S
Mac OS X

S
No
Quiz
No

z/OS

Caractersticas fundamentales
Informacin acerca de que caractersticas fundamentales de las RDBMS son
implementados nativamente.
ACID
Adaptive
Enterprise

Server

Integridad referencial
S

Transacciones
S

Unicode
S

ANTs Data Server

DB2

Firebird

HSQLDB

Informix

Ingres

InterBase

SapDB

MaxDB

Microsoft SQL Server

MySQL

Depende 1

Depende 1

Depende 1

Oracle

PostgreSQL

SQLite

S
ACID

S
2

No
Integridad referencial

Bsico

S
2

Transacciones

S
Unicode

Nota (1): Para las transacciones y la integridad referencial, el tipo de tabla InnoDB debe
ser usado; el tipo de tabla por defecto, MyISAM,
No soporta estas caractersticas. Sin
embargo, inclusive el tipo de tabla InnoDB permite el almacenamiento de valores que
excedan el rango de datos; algunas vistas violan la limitacin de ACID.
Nota (2): Las limitaciones de CHECK y FOREIGN KEY son analizadas
pero
No forzadas. Transacciones anidadas
No son soportadas.[1]
16

Tablas y vistas
Informacin acerca de que tablas y vistas 3 (unas ms bsicos que otras) son soportados
nativamente.
Tabla temporal
Adaptive
Enterprise

Server

Vista materializada

S 5

ANTs Data Server

DB2

[[Firebird ]]

No

HSQLDB

No

Informix

Ingres

No

InterBase

No

SapDB

No

MaxDB

Microsoft SQL Server

MySQL

No

Oracle

PostgreSQL

No 4

SQLite

No
Similar 6

S
Tabla temporal

No
Vista materializada

Nota (4): La vista materializada puede ser emulada con PL/PgSQL [2].
Nota (5): El servidor provee tempdb, que puede ser usado para tablas temporales
pblicas y privadas (para la sesin). [3]
Nota (6): El servidor MS SQL provee vistas indexadas. [4]

ndices
Informacin acerca de que ndices (otros como los ndices bsicos B-/B+) son soportados
nativamente.
rbol R-/R+
Adaptive
Enterprise

Server

No

ANTs Data Server

DB2

No

Firebird
HSQLDB

Hash

Mapa
bits

No

No

No

No

No

No
?

Expresin Parcial Reversa

No
?

No
?

No
?

No
?

de

No
?

Informix

No

No

No

Ingres

No

No

No

No

17

InterBase

No

No

No

No

SapDB

No

No

No

No

MaxDB

No

No

No

No

Microsoft SQL Server

No

No

No

No

MySQL

Tablas MyISAM solamente Tablas HEAP solamente

No

No

No

No

Oracle

Edicin EE solamente

No

S
No

PostgreSQL

No

SQLite

No

No

No

No

No

rbol R-/R+

No
Mapa
Expresin Parcial Reversa
bits

Hash

de

Otros objetos
Informacin acerca de que otros objetos son soportados nativamente.
Dominio
Adaptive
Enterprise

Server

Cursor

Trigger

Funciones 5

Procedimiento 5

Rutina externa 5

ANTs Data Server

DB2

No

Firebird

No

HSQLDB

Informix

Ingres

InterBase

S
?
S

SapDB

MaxDB

Microsoft SQL Server

No

MySQL

No

S
3

S
3

S
3

S
3

Oracle

PostgreSQL

S
Trigger

No
Funciones

SQLite

No
Dominio

No
Cursor

No
Procedimiento

S
Rutina externa

Nota (3): Estos objetos de base de datos son disponibles a partir de MySQL 5.0 disponible
desde 24/12/2005.
Nota (5): Funcin y procedimiento se refieren a las rutinas internas escritas en SQL o
lenguajes procedurales como PL/SQL. Rutina externa se refiere a la escritura en los
lenguajes anfitriones como C, Java, Cobol, etc. "Procedimiento almacenado" es un
trmino comnmente usado para ese tipo de rutinas. Sin embargo, su definicin vara
entre diferentes vendedores de bases de datos.

18

Particionamiento
Informacin acerca de que mtodos de particionamiento son soportados nativamente.

Adaptive
Enterprise

Server

Rango

Hash

Compuesto (Rango+Hash)

Lista

AA

AA

AA

AA

ANTs Data Server

DB2

Firebird
HSQLDB
Informix

No
?
?

Ingres

InterBase
SapDB
MaxDB

No
?
?
S

No
?
?

No
?
?
S

No
?
?

No
?
?
S

No
?
?

No
?
?

Microsoft SQL Server

No

No

No

MySQL

Oracle

PostgreSQL

No

No

SQLite

S
Rango

S
Hash

S
Compuesto (Rango+Hash)

S
Listas

19

Arquitectura Conceptual de PostgreSQL


PostgreSQL usa un modelo de arquitectura cliente/servidor conocido como
proceso por usuario. Hay un proceso maestro que se ramifica para proporcionar
conexiones adicionales para cada cliente que se intente conectar a PostgreSQL.
PostgreSQL es una arquitectura orientada a objetos dividida en tres grandes
subsistemas:
La aplicacin sobre la que trabaja el
usuario
Postmaster Procesos en el Servidor Un proceso demonio supervisor
Control de la Base de Uno o ms servidores de bases de datos
Back End
datos
en segundo plano (servidor PostgreSQL)
Front End

Procesos en el Cliente

Un nico proceso postmaster controla una coleccin de bases de datos


almacenadas en un host; las aplicaciones de frontend o clientes que quieren
acceder a una determinada base de datos hacen llamadas y envan peticiones de
usuario a travs de la red al proceso postmaster, el cual en respuesta inicia un
proceso en el servidor y conecta el proceso de frontend al nuevo servidor. A partir
de este punto, el proceso cliente (frontend) y el servidor (backend) se comunican
sin la intervencin del postmaster, aunque este proceso siempre se est
ejecutando, esperando peticiones de otros clientes (procesos frontend).

Soporte del sistema operativo

20

En esta arquitectura el proceso postmaster y el proceso backend siempre se


ejecutan en la misma mquina (el servidor de base de datos), mientras que la
aplicacin frontend o cliente se puede ejecutar desde cualquier equipo.
Dentro de estos subsistemas, otras arquitecturas tales como tnel hbrido y filtro
(en los procesos del servidor Postgres), la invocacin implcita (en el Postmaster),
cliente-servidor (con el Postmaster como servidor), y orientado a objetos (en el
control de Base de Datos).

Arquitectura general conceptual de PostgreSQL

Front End (Cliente - Servidor)


Consta de dos partes principales: La aplicacin del cliente y la librera de interface
del cliente.
Las Aplicaciones de cliente, algunas de las cuales se ejecutan en diferentes
sistemas operativos, como: PgAdmin, PhpPgAdmin, EMS SQL Manager,
Mergeant, PGInhaler, SQirreL y otras.
La Librera de interface del Cliente es la forma en que cada una de estas
aplicaciones pueden comunicarse con el Servidor porque la Librera de interface
del Cliente convertir a la apropiada consulta SQL que el Servidor puede
entender e interpretar.
Esto maximiza la cohesin porque el servidor no tiene que interpretar diferentes
lenguajes, sino que nicamente entiende consultas SQL, lo que hace el sistema
ms rpido.
21

Postmaster
Es un proceso demonio supervisor que se ejecuta constantemente.
Utiliza una arquitectura de invocacin implcita para escuchar alguna o todas las
llamadas a la base de datos.
Cuando recibe una llamada desde un cliente, crea un proceso back end (servidor
postgres) para hacerlo coincidir, utilizando una correspondencia 1-1.
Una vez que el proceso se crea, se enlaza el cliente y el proceso postgres para
que ya no tengan que comunicarse a travs del Postmaster.

Back End - Arquitectura General del Servidor de Postgres


Arquitectura de tnel hbrido y filtro.
Cada componente referencia un repositorio compartido de catlogos, reglas y
tablas.
Se pasa una consulta SQL al Servidor Postgres que se transforma gradualmente
en datos de resultados.

Arquitectura conceptual del servidor Postgres

22

Intrprete
Acepta una consulta SQL en forma de texto ASCII.
El analizador lxico busca coincidencia de patrones en la consulta para reconocer
los identificadores y palabras clave.
El Intrprete entonces ensambla estos en un rbol de traduccin.
El Intrprete comprueba que la consulta SQL tenga una sintaxis vlida, pero no
entiende la semntica.

Polica de trfico
Enva comandos simples para el ejecutor y los complejos se envan al planificador
/ optimizador.

Planificador / Optimizador
Las Consultas SQL se pueden ejecutar en diferente orden y producen los mismos
resultados.
El Planificador / Optimizador elegir la mejor ruta o la ms eficiente si existen
varias posibilidades.
A continuacin, se pasa hacia el Ejecutor.

Ejecutor
Recibe el plan de Planificador / Optimizador en la forma de un rbol.
Extrae las tablas de datos necesarias.
Recursivamente pasa por el plan, y lleva a cabo las acciones necesarias en cada
nodo.
Enva al tnel y filtra, sin procesamiento por lotes.
Devuelve una salida al cliente.

Administracin de Datos
La base de datos es mantenida por varios subsistemas independientes (y algunas
veces opcional) iniciadas por el Postmaster en la construccin, incluyendo:

23

El colector de Estadsticas.
El Auto-Vacuum.
El escritor Background.
El Sistema de Administracin de la memoria.

Control de las dependencias de la Base de Datos

Colector de Estadsticas
Registros de la tabla / ndice de accesos de la base de datos, el uso de
funciones definidas por el usuario y los comandos que se ejecutan por los
procesos del servidor.
La informacin se transmite desde el colector a travs de los archivos
temporales en los procesos solicitantes.
Procesos que envan informacin relevante al colector peridicamente para
mantenerlo al da.
24

Auto-Vacuum
El Auto-Vaccum es una coleccin de procesos para escanear las tablas de la
base(s) de datos con el fin de liberar la memoria no utilizada, actualizar las
estadsticas, y prevenir la prdida de datos.
El Auto-Vaccum se basa en los datos recibidos desde el recolector de
estadsticas para el anlisis de la tabla adecuada.

Background Writer
El Background Writer mantiene la informacin de los archivos logs (registro de
la actividad) y backups (copia de seguridad) actualizados.
El Background Writer mantiene actualizados los archivos logs con todos los
cambios realizados a la base de datos desde su ltimo backup a fin de que
todos los datos estn seguros.
La salida estndar de cada subsistema se pasa al Background Writer para
mantener estos archivos logs.

Almacenamiento de Datos
La base de datos es mantenida por varios subsistemas independientes (y algunas
veces opcional) iniciadas por el Postmaster en la construccin, incluyendo:

El Acceso.
El Almacenamiento.
La Rutina de Carga (Bootstrap).
La grabacin en Disco.

Acceso
El Subsistema de Acceso est a cargo de:

indexacin
exploracin
bsqueda
recopilacin y devolucin de datos

El Servidor de Procesos PostgreSQL Recupera los datos utilizando el


Subsistema de Acceso.

25

El Subsistema de Acceso utiliza diferentes mtodos de indexacin.

Almacenamiento
Los datos almacenados son accesados a travs del Subsistema de
Almacenamiento:
Encargada del mantenimiento de una serie de buffers compartidos.
Permite mltiples accesos a las mismas tablas utilizando un modelo de control
de concurrencia multiversin (MVCC - multiversion concurrency control model).
Mantiene bloqueos de tabla y asegura la concurrencia de datos.

Bootstrap (Rutina de Carga)


El subsistema Bootstrap permite a los usuarios iniciar la base de datos en modo
de arranque.
El Modo Bootstrap no permite consultas SQL.
Bootstrap permite a los catlogos del sistema ser creados y llenados desde
cero, mientras comandos normales SQL requieren que los catlogos ya existan.
Bootstrap es usado por el Instalador para crear la plantilla inicial de la Base de
Datos.

Caso de uso de creacin de una Base de Datos


26

Caso de uso de login y consulta compleja

Conclusin
La Arquitectura general de PostgreSQL es Orientada a Objetos / Repositorio.
EL Front-end es una arquitectura cliente-servidor desde la Biblioteca de Cliente a
los Procesos del Servidor Postgres y el Postmaster que utiliza invocacin implcita.
El Servidor Postgres emplea arquitectura de Tnel Hbrido y Filtro / Repositorio.
El Control de Bases de Datos utiliza una arquitectura Orientada a Objetos.
Adelante veremos el cdigo fuente para determinar las dependencias a nivel de
cdigo, lo que nos permite formar una arquitectura concreta.

27

Instalar y Configurar el PostgreSQL 9.x


1 Instalacin del Servidor de Bases de Datos PostgreSQL 9.x
en Centos 6.2/6.3 Fedora 18/17/16, Red Hat (RHEL),
Scientific Linux (SL) 6.4/6.3/6.2/6.1/6/5.9
Cubriremos la instalacin y configuracin bsica de PostgreSQL 9.x en CentOS.
Instalaremos PostgreSQL 9 utilizando el repositorio PostgreSQL y yum.
El mismo procedimiento se puede utilizar para instalar PostgreSQL 9 en Red
Hat, Fedora y Scientific Linux utilizando el rpm apropiado.
Como la estructura de directorios de PostgreSQL ha cambiado con el
lanzamiento de PostgreSQL 9, tambin veremos cmo podemos crear enlaces
simblicos para hacer la vida ms fcil cuando se instala software o mdulos
que an esperan la vieja estructura de directorios.
Tambin vamos a crear enlaces simblicos (si es necesario) de las nuevas
PostgreSQL 9 ubicaciones de los archivos de las PostgreSQL 8 ubicaciones de
los archivos anteriores.
Usaremos el mtodo ms sencillo de instalar, que es el repositorio rpms
postrgres.

1.1 Cambie al usuario root


su ## OR ##
sudo -i

1.2 Descargar e Instalar el Repositorio PostgreSQL


Descargue la ltima versin de produccin de su distribucin aqu:
http://yum.pgrpms.org/repopackages.php
Los repositorios rpms son especficamente de 32 and 64 bit.
Si instalamos en CentOS 6 x64, necesitamos:
http://yum.pgrpms.org/9.2/redhat/rhel-6-x86_64/pgdg-centos92-9.26.noarch.rpm
Si instalamos en CentOS 6 x32, necesitamos:
28

http://yum.pgrpms.org/9.2/redhat/rhel-6-i386/pgdg-centos92-9.2-6.noarch.rpm
Si instala en un Linux diferente utilice el rpm apropiado.
Usando wget:
[root@server1 ~]# wget http://yum.pgrpms.org/9.2/redhat/rhel-6-x86_64/pgdg-centos92-9.2-6.noarch.rpm
1.
2.

[root@server1 ~]# wget http://yum.pgrpms.org/9.2/redhat/rhel-6-x86_64/pgdgcentos92-9.2-6.noarch.rpm


--2011-11-01 00:11:50-http://yum.pgrpms.org/9.2/redhat/rhel-6-x86_64/pgdgcentos92-9.2-6.noarch.rpm
Resolving yum.pgrpms.org... 98.129.198.114
Connecting to yum.pgrpms.org|98.129.198.114|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 5124 (5.0K) [application/x-redhat-package-manager]
Saving to: pgdg-centos92-9.2-6.noarch.rpm

3.
4.
5.
6.
7.
8.
9. 100%[======================================>] 5,124 --.-K/s in 0s
10.
11. 2011-11-01 00:11:51 (310 MB/s) - pgdg-centos92-9.2-6.noarch.rpm
12.
13. [root@server1 ~]#

1.3 Excluir del CentOS, Fedora, Red Hat y Scientific Linux sus propios
paquetes PostgreSQL.
Este paso es importante para conseguir que el repositorio de PostgreSQL
funcione correctamente. Hay que excluir los paquetes PostgreSQL desde el
repositorio de la distribucin.
CentOS
Ahora tenemos que editar el archivo /etc/yum.repos.d/CentOS-Base.repo y
adicionarle la clausula 'exclude = postgresql*' en las secciones [base] y
[updates] para excluir postgreql.
1.
2.

[root@server1 ~]# cd /etc/yum.repos.d


[root@server1 ~]# vi CentOS-Base.repo

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.

[base]
....
....
exclude=postgresql*
# released updates
[updates]
....
....
exclude=postgresql*

29

Fedora
Adicionamos la clausula 'exclude = postgresql*' en la seccin [fedora] del
archivo /etc/yum.repos.d/fedora.repo:
1.
2.

[root@server1 ~]# cd /etc/yum.repos.d


[root@server1 yum.repos.d]# vi fedora.repo

1.
2.
3.
4.

[fedora]
....
....
exclude=postgresql*

Adicionamos la clausula 'exclude = postgresql*' en la seccin [updates] del


archivo /etc/yum.repos.d/fedora-updates.repo:
1.
1.
2.
3.
4.

[root@server1 yum.repos.d]# vi fedora-updates.repo


[updates]
....
....
exclude=postgresql*

Red Hat (RHEL)


Adicionamos la clausula 'exclude = postgresql*' en la seccin [main] del archivo
/etc/yum/pluginconf.d/rhnplugin.conf:
1.
2.

[root@server1 ~]# cd /etc/yum/pluginconf.d


[root@server1 yum.repos.d]# vi rhnplugin.conf

1.
2.
3.
4.

[main]
....
....
exclude=postgresql*

Scientific Linux (SL)


Adicionamos la clausula 'exclude = postgresql*' en las secciones [sl] y [slsecurity] del archivo /etc/yum.repos.d/sl.repo:
1.
2.
1.
2.
3.
4.
5.
6.
7.
8.
9.

[root@server1 ~]# cd /etc/yum.repos.d


[root@server1 yum.repos.d]# vi sl.repo
[sl]
....
....
exclude=postgresql*
# released sl-security
[sl-security]
....
....
30

10. exclude=postgresql*

1.4 Instalar el Repositorio PostgreSQL 9.2.


Ahora, instalamos el Repositorio
CentOS
1.

[root@server1 ~]# rpm -i pgdg-centos92-9.2-6.noarch.rpm

Fedora
1. [root@server1 ~]# rpm -i pgdg-fedora92-9.2-6.noarch.rpm

Red Hat (RHEL)


1. [root@server1 ~]# rpm -i pgdg-redhat92-9.2-7.noarch.rpm

Scientific Linux (SL)


1. [root@server1 ~]# rpm -i pgdg-sl92-9.2-8.noarch.rpm

1.5 Chequear los paquetes que estn instalados con YUM.


Este paso es opcional, pero nos permite verificar que los paquetes instalados
estn ahora disponibles:
1.
2.
3.
4.
5.

[root@server1 yum.repos.d]# rpm yum list postgres*


....
....
postgresql92.x86_64
....

1.6 Instalar el PostgreSQL 9.2 con YUM.


Ahora podemos instalar el PostgreSQL usando yum:
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.

[root@server1 ~]# yum install postgresql92 postgresql92-devel postgresql92server postgresql92-libs postgresql92-contrib


....
Installed:
postgresql92.x86_64 0:9.2.6-1PGDG.rhel6
postgresql92-devel.x86_64 0:9.2.6-1PGDG.rhel6
postgresql92-libs.x86_64 0:9.2.6-1PGDG.rhel6
postgresql92-server.x86_64 0:9.2.6-1PGDG.rhel6
Complete!
[root@server1 ~]#

31

2 Configurar el PostgreSQL 9.2


2.1 Inicializar el Cluster con el comando initdb
Hay mltiples alternativas de cmo hacer esto:
service postgresql-9.x initdb
/etc/init.d/postgresql-9.x initdb
postgresql-setup initdb
service postgresql-9.x initdb
As, que usaremos aqu el mtodo universal de Postgres initdb, que deber
trabajar con CentOS, Red Hat (RHEL), Fedora 18/17/16 y Scientific Linux (SL)
6.4/5.9:
1.

[root@server1 ~]# su - postgres -c /usr/pgsql-9.2/bin/initdb

Otra forma,
Inicializar el Postgres:
1.
2.
3.

[root@server1 ~]# service postgresql-9.2 initdb


Initializing database:
[ OK ]
[root@server1 ~]#

Arrancar el Servidor Postgres


1.
2.
3.

[root@server1 ~]# service postgresql-9.2 start


Starting postgresql-9.1 service:
[ OK ]
[root@server1 ~]#

Si encuentra errores de inicio, chequee el archivo /var/lib/pgsql/9.2/data/pg_log


en busca de pistas.
2.2 Establecer el entorno del PostgreSQL 9.x
El directorio home predeterminado para el usuario postgres es /var/lib/pgsql.
El bash_profile para el usuario postgres se parecer a:
1.
2.
3.

[ -f /etc/profile ] && source /etc/profile


PGDATA=/var/lib/pgsql/9.2/data
export PGDATA

Contiene el ruta para el directorio data, pero no la ruta para el directorio de los
binarios ejecutable. Para modificar esto, agregue la ruta de la siguiente manera:
1.
2.
3.
4.
5.

[ -f /etc/profile ] && source /etc/profile


PGDATA=/var/lib/pgsql/9.2/data
export PGDATA
PATH=$PATH:$HOME/bin:/usr/pgsql-9.2/bin
export PATH
32

Colocando el directorio de los ejecutables binarios en la ruta del usuario


postgres le permitir invocar todos comandos.
2.3 Establecer la contrasea PostgreSQL
El superusuario postgres no tiene contrasea predeterminada.
Para establecer la contrasea, cambie al usuario postgres:
1.

[root@server1 ~]# su - postgres

Conectar como postgres a la base de datos postgres y configurar la contrasea


para el usuario postgres utilizando alter usuario de la siguiente manera:
1.
2.
3.
4.
5.
6.
7.

bash-4.1$ psql postgres postgres


Psql (9.2.6)
Type "help" for help.
postgres=# alter user postgres with password 'postgres';
ALTER ROLE
postgres=#

2.4 Configurar los Permisos para PostgreSQL (Archivo pg_hba.conf)


Editar el archivo pg_hba.conf, donde se especifican las direcciones ip desde las
cuales aceptara conexiones entrantes. Localizar el archivo pg_hba.conf bajo el
directorio /var/lib/pgsql/9.2/data.
En la instalacin, el archivo pg_hba.conf se ver as:
1.
2.
3.
4.
5.
6.
7.
8.
9.

[root@server1 ~]# vi /var/lib/pgsql/9.2/data/pg_hba.conf


....
# TYPE DATABASE USER
ADDRESS
METHOD
local all
all
peer
# IPv4 local connections:
host
all
all
127.0.0.1/32
ident
# IPv6 local connections:
host
all
all
::1/128
ident
....

Para que acepte todas las conexiones, se agrega en la parte de IPv4 local
connections la lnea:
host all

all

0.0.0.0/0 md5

Cambiar METHOD a md5 para que solicite contrasea, ver cambios abajo:
1.
2.
3.
4.

....
# TYPE DATABASE USER
ADDRESS
local all
all
md5
# IPv4 local connections:

METHOD

33

5.
6.
7.
8.
9.

host
host
# IPv6
host
....

all
all
127.0.0.1/32 md5
all
all
0.0.0.0/0
md5
local connections:
all
all
::1/128
md5

Se puede restringir el acceso al servidor postgres como se desee, as:


host
host

all
test

all
10.20.4.0/24
md5
testuser
127.0.0.1/32 md5

Se pueden encontrar ms ejemplos en la gua completa del manual en:


http://www.postgresql.org/docs/9.2/static/auth-pg-hba-conf.html
Para que los cambios tomen efecto, se recarga el archivo pg_hba.conf. Hay
varias formas de hacerlo:
1.
2.
3.
4.

[root@server1 ~]# su - postgres


-bash-4.1$ pg_ctl reload
server signaled
-bash-4.1$

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.

-bash-4.1$ psql postgres postgres


psql (9.2.6)
Type "help" for help.

1.
2.
3.
4.
5.
6.
7.
8.

-bash-4.1$ psql postgres postgres -c "select pg_reload_conf();"


Password for user postgres:
pg_reload_conf
---------------t
(1 row)

postgres=# select pg_reload_conf();


pg_reload_conf
---------------t
(1 row)
postgres=#

-bash-4.1$

2.5 Configurar el Acceso Remoto para PostgreSQL (Archivo postgresql.conf)


Localizar el archivo postgresql.conf bajo el directorio /var/lib/pgsql/9.2/data.
Busque CONNECTIONS AND AUTHENTICATION. Se ver de la siguiente
manera:
1.
2.

#-----------------------------------------------------------------------------# CONNECTIONS AND AUTHENTICATION


34

3.
4.
5.
6.
7.
8.
9.
10.
11.

#-----------------------------------------------------------------------------# - Connection Settings #listen_addresses = 'localhost' # what IP address(es) to listen on;


# comma-separated list of addresses;
# defaults to 'localhost', '*' = all
# (change requires restart)
#port = 5432
# (change requires restart)

De forma predeterminada, el acceso est limitado a la mquina local (localhost).


Para habilitar las conexiones remotas, descomentar listen_addresses y cambiar
a "*" como se muestra a continuacin.
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.

#-----------------------------------------------------------------------------# CONNECTIONS AND AUTHENTICATION


#-----------------------------------------------------------------------------# - Connection Settings listen_addresses = '*' # what IP address(es) to listen on;
# comma-separated list of addresses;
# defaults to 'localhost', '*' = all
# (change requires restart)
port = 5432
# (change requires restart)

Tambin puede establecer el lmite a una IP especfica (o direcciones IP


utilizando una lista separada por comas).
Nota: Para mayor seguridad, es una buena idea cambiar el puerto
predeterminado. Para ello, cambie a un nuevo valor de puerto.
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.

#-----------------------------------------------------------------------------# CONNECTIONS AND AUTHENTICATION


#-----------------------------------------------------------------------------# - Connection Settings listen_addresses = '192.1.2.33' # what IP address(es) to listen on;
# comma-separated list of addresses;
# defaults to 'localhost', '*' = all
# (change requires restart)
port = 5432
# (change requires restart)

Si cambia el puerto, reinicie el servicio postgresql.


1.
2.
3.
4.

service postgresql-9.2 restart


Stopping postgresql-9.2 service:
Starting postgresql-9.2 service:
[root@server1 yum.repos.d]#

[ OK ]
[ OK ]

Si encuentra errores de inicio, chequee el archivo /var/lib/pgsql/9.2/data/pg_log


en busca de pistas.

35

Verifique si ha realizado cambios en listen_address o port:


1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.

-bash-4.1$ psql
Password:
psql (9.2.6)
Type "help" for help.
postgres=# show listen_addresses;
listen_addresses
-----------------*
(1 row)
postgres=# show port;
port
-----5432
(1 row)
postgres=#

2.6 Crear Usuario y Base de Datos para PostgreSQL 9.x


Para chequear la funcionalidad, conctese a la Base de Datos postgres como
usuario postgres.
1.
2.
3.
4.
5.
6.

[root@server1 yum.repos.d]# psql postgres postgres


Password for user postgres:
psql (9.2.6)
Type "help" for help.
postgres=#

Crear un usuario:
1.
2.

postgres=# create user testuser with password 'secreto';


CREATE ROLE

Crear una Base de datos y asignarle el usuario propietario:


1.
2.

postgres=# create database test owner=testuser;


CREATE DATABASE

Conectar a la Base de Datos como usuario:


1.
2.
3.

postgres=# \c test testuser


Password for user testuser:
You are now connected to database "test" as user "testuser".

Crear una Tabla e Insertar Filas:


1.
2.

test=> create table testtable (col1 varchar);


CREATE TABLE

36

3.
4.

test=> insert into testtable values('hello');


INSERT 0 1

Consultas en la Tabla
1.
2.
3.
4.
5.
6.
7.

test=> select * from testtable;


col1
------hello
(1 row)
test=>

Listar las Tablas de la Base de Datos test:


1.
2.
3.
4.
5.
6.

test=> \dt
List of relations
Schema |
Name
| Type | Owner
--------+-----------+-------+-------public | testtable | table | myuser
(1 row)

Note que public es el esquema predeterminado, deber crear un esquema


especifico para sus usuarios.
2.7 Iniciar / Auto-Iniciar (Arranque del Equipo) el servidor Postgres
Ahora, Iniciamos el Servidor:
CentOS, Red Hat (RHEL), Scientific Linux (SL) 6.4/5.9
De forma predeterminada, se agrega el servicio postgresql-9.2 a chkconifg, pero
todos los niveles de ejecucin se establecen en off.
Adicione los niveles de ejecucin 2,3 y 5 para el servicio postgresql-9.2
1.
2.
3.
4.
5.
6.
7.

## Iniciar PostgreSQL 9.2 ##


[root@server1 ~]# service postgresql-9.2 start
## OR ##
[root@server1 ~]# /etc/init.d/postgresql-9.2 start
## Iniciar PostgreSQL 9.2 en cada arranque del equipo ##
[root@server1 ~]# chkconfig --levels 235 postgresql-9.2 on

Fedora 18/17/16
1.
2.
3.
4.
5.

## Iniciar PostgreSQL 9.2 ##


[root@server1 ~]# systemctl start postgresql-9.2.service
## Iniciar PostgreSQL 9.2 en cada arranque del equipo ##
[root@server1 ~]# systemctl enable postgresql-9.2.service

37

3 Habilitar Conexiones Remotas al Servidor PostgreSQL 9.2


Abrir el Puerto 5432 del PostgreSQL en el Firewall Iptables.
3.1 Editar el archivo etc/sysconfig/iptables
Adicionar a iptables la excepcin para que acepte paquetes por el puerto 5432:
1.
2.
3.

[root@server1 ~]# vi /etc/sysconfig/iptables


-A INPUT -m state --state NEW -m tcp -p tcp --dport 5432 -j ACCEPT

3.2 Reiniciar el Firewall iptables


CentOS, Red Hat (RHEL), Scientific Linux (SL) 6.4/5.9
1.
2.
3.

[root@server1 ~]# service iptables restart


## OR ##
[root@server1 ~]# /etc/init.d/iptables restart

Fedora 18/17/16
1.

[root@server1 ~]# systemctl restart iptables.service

4 Optimizacin
4.1 Crear enlaces simblicos para compatibilidad con versiones de
anteriores a PostgreSQL 9.x
Mucho, si no la mayora de los mdulos y software de terceros buscan los
archivos de configuracin del Postgres y el directorio de datos en sus antiguas
ubicaciones (antes de la versin 9).
Se puede solucionar este inconveniente y hacer la vida ms fcil, creando
algunos enlaces simblicos de los nuevos lugares a los anteriores.
Enlace 1: Enlace simblico para el directorio binario. Esto es particularmente
til ya que es la ubicacin del archivo de pg_config.
1.

[root@server1 ~]# ln -s /usr/pgsql-9.2/bin/pg_config /usr/bin

Enlace 2: Enlace simblico de la anterior ubicacin del directorio de datos


/var/lib/pgsql
1.
2.

[root@server1 ~]# ln -s /var/lib/pgsql/9.2/data /var/lib/pgsql


[root@server1 ~]# ln -s /var/lib/pgsql/9.2/backups /var/lib/pgsql

38

4.2 Optimizar el rendimiento del Postgres usando el archivo postgresql.conf


Y cambiamos algunas opciones bsicas del archivo postgresql.conf:
1.

shared_buffers = 256MB

shared_buffers: Es la memoria de trabajo compartida para todo el servidor


postgreSQL, fjese que por defecto en Debian GNU/Linux la opcin es 24MB (y
el valor por defecto si comentamos es 32MB), sin embargo, como esta es la
memoria utilizada para trabajo de postgreSQL, es recomendable al menos el
25% de la RAM disponible (y jams > 40%).
2.

temp_buffers = 16MB

temp_buffers: La memoria temporal utilizada por cada sesin para las tablas
temporarias y para apertura de tablas en cada sesin de cada base de datos,
tome en cuenta que este valor depender obviamente de la cantidad de datos
que carga cada sesin y depender muchsimo del sistema que se utiliza.
3.

work_mem = 16MB

work_mem: uno de los valores ms importantes y ms despreciados,


work_mem se refiere a la memoria temporal utilizada por cada sesin, para las
operaciones de ordenamiento (ORDER BY) para las sesiones de diferenciacin
(GROUP HAVING y DISTINCT) y para la gestin de hash (uniones HASH,
indices HASH, hash_aggregations), si en nuestro sistema realizamos
muchsimas consultas ordenadas, agrupadas, diferenciadas por cadenas, etc se
crearn mucho de estos buffers de manera paralela, mientras ms memoria
asignemos, menos probabilidades hay que los ordenamientos y otras
operaciones se hagan con archivos temporales en disco (ms lentos que la
memoria RAM).
4.

max_stack_depth = 8MB

max_stack_depth: define el tamao del espacio utilizado para cmputo de


operaciones complejas, su valor est asociado al lmite mximo que un usuario
(en este caso, postgres) tiene derecho a reservar un stack, el valor soportado
por nuestra distribucin se determina con ulimit -s.
5.

shared_preload_libraries = '$libdir/plpython2.so'

shared_preload_libraries: Permite cargar una librera especfica cuando


arranca el sistema, si utilizamos muchos procedimientos almacenados en un
lenguaje especfico (ej: pgsql, python, perl, tcl, java, etc), es bueno pre-cargarla
para que est disponible cuando se utilice por primera vez. Nota: esta opcin
ralentiza un poco el reinicio del sistema.

39

6.

bgwriter_delay = 500ms

bgwriter_delay: El background-writer es un proceso del servidor que se


encarga de escribir a disco todos los shared_buffers modificados, este
proceso conlleva una carga de I/O sobre el disco, su modificacin permite o
reducir el valor para evitar en lo ms posible prdidas de datos en equipos que
pueden fallar, o su incremento permite reducir el I/O al disco duro en sistemas
perfectamente protegidos.
4.2 Optimizar el Linux para Postgres.
Una de las cosas que olvidamos optimizar (tunning) es nuestro sistema
operativo GNU/Linux, con grupo de valores en el sysctl ya que podemos ayudar
mucho a nuestro postgreSQL.
Cada vez que el sistema arranque, el programa init ejecuta el script
/etc/rc.d/rc.sysinit. Este script contiene un comando para ejecutar sysctl
mediante el uso de /etc/sysctl.conf para determinar los valores pasados al
kernel. Cualquier valor aadido a /etc/sysctl.conf surtir efecto cada vez que el
sistema arranque.
Agregamos al archivo /etc/sysctl.conf
1.
2.
3.
4.
5.
6.
7.

kernel.sem = 100 32000 100 128


kernel.shmall = 3279547
kernel.shmmax = 289128448
kernel.shmmni = 8192
fs.file-max = 287573
vm.dirty_bytes = 67108864
vm.dirty_background_bytes = 134217728

Nota: observe el valor de shmmax, la cantidad de memoria mxima reservada


para un shared_buffer que puede crear una aplicacin debe ser igual o mayor
al valor del shared_buffer de postgreSQL, este valor est en bytes y es ~
275MB.
La cantidad mxima de archivos que pueden abrirse en un sistema, depender
obviamente del nivel de trabajo de la DB, durante una operacin regular, la
gente puede ejecutar lsof | wc para obtener la cantidad de archivos abiertos.
Y luego, las aplicamos:
1.
2.
3.
4.
5.
6.
7.
8.

[root@server1 ~]# sysctl -p


-kernel.sem = 100 32000 100 128
kernel.shmall = 3279547
kernel.shmmax = 289128448
kernel.shmmni = 8192
fs.file-max = 287573
40

9. vm.dirty_bytes = 67108864
10. vm.dirty_background_bytes = 134217728

Ya, con estos sencillos cambios, podemos reiniciar el postresql:


1.
2.

[root@server1 ~]# /etc/init.d/postgresql restart


Restarting PostgreSQL 9.1 database server: main.

5 Instalar el PostgreSQL en un Directorio Diferente


Para instalar el PostgreSQL en un directorio distinto al por defecto, la diferencia
con el proceso anterior consiste en crear el directorio asignarle los permisos
correspondientes y ejecutar el comando initdb con los parmetros correctos
para inicializar el Cluster en otra posicin.
El directorio puede ser un disco entero que se debe montar previamente desde
el sistema operativo.
Vamos a crear un directorio data:
1. [root@server1 ~]# mkdir /srv/postgresql

Asignamos el directorio a sus propietarios. Debe ser un superusuario postgres:


2. [root@server1 ~]# chown postgres /srv/postgresql

Ahora entramos al usuario postgres


3. [root@server1 ~]# su - postgres

Al instalar la BD, cambiamos los parmetros del comando initdb para Inicializar
el Cluster en el directorio creado anteriormente:
4. -bash-4.1$ /usr/pgsql-9.2/bin/initdb -D /srv/postgresql

Ahora iniciamos la BD:


5. -bash-4.1$ /usr/pgsql-9.2/bin/postmaster -D /srv/postgresql

6 Instalar el PostgreSQL en un Directorio Diferente usando


tablespace
41

Se utiliza para ampliar el espacio que contiene las Bases de Datos o para tener
los ndices y las tablas en discos separados para mejorar los procesos de
acceso i/o.
Entramos al usuario postgres
1. [root@server1 ~]# su - postgres

Entramos al psql
2. -bash-4.1$ psql

En la consola, ejecutamos el comando para crear un espacio de tablas:


3. postgres=# CREATE TABLESPACE te_sistema OWNER postgres LOCATION '/srv/postgresql';

Y listo!, ya tenemos un espacio de tablas disponible para crear bases de datos:


Para crear una DB que no est asociada al espacio por defecto (pg_default)
ejecutamos:
4. postgres=# CREATE DATABASE db_sistema
TEMPLATE=template0 TABLESPACE=te_sistema;

WITH

ENCODING='UTF8'

OWNER=postgres

Y como vern, le pasamos el tablespace te_sistema que hemos creado


anteriormente

42

Directorios y Archivos de PostgreSQL


Ubicaciones de los directorios y archivos de PostgreSQL en
Linux
El siguiente paso, despus de instalar PostgreSQL es revisar lo que contiene los
ficheros generados con la instalacin.
En la mayora de distribuciones de Linux, los archivos de PostgreSQL se guardan
en las ubicaciones mostradas en la siguiente tabla:
tem

Ubicacin

Ejecutables

/usr/bin

Libreras

/usr/lib

Documentacin

/usr/share/doc/postgresql-x.y. z
/usr/share/doc/postgresql-x.y . z/contrib

Contrib

/usr/share/pgsql/Contrib

rea de Datos

/var/lib/pgsql/data

rea de Backup

/var/lib/pgsql/backup

Templates

/usr/share/pgsql

Lenguajes Procedurales

/usr/lib/pgsql

Development Headers

/usr/include/pqsql

Otros datos compartidos

/usr/share/ pqsql

Pruebas de Regresin

/usr/lib/pgsql/test/regress (en el paquete -test)

Documentacin SGML

/usr/share/doc/postgresql-docs-x.y.z

Ubicaciones de los directorios y archivos de Datos de


PostgreSQL en Linux
Es necesario ver los contenidos del directorio data, y entender como estn
organizados y que es lo que contiene cada uno de ellos.
En esta seccin se describe el formato de almacenamiento a nivel de archivos y
directorios del directorio de datos de PostgreSQL.
Todos los datos necesarios para que un clster de base de datos se almacenan
dentro del directorio de datos conocida como PGDATA (el nombre de la variable
43

de entorno que se puede utilizar para definir la misma). Un lugar comn


para PGDATA es /var/lib/pgsql/9.2/data. Diversos clsteres, gestionados por
diferentes instancias del servidor, pueden existir en la misma mquina.
El directorio contiene varios subdirectorios y archivos de control, como se muestra
en la Tabla . Adems de estos elementos necesarios, la configuracin de cluster
archivos postgresql.conf,
pg_hba.conf ,
y pg_ident.conf
se
almacenan
tradicionalmente en DATA (aunque a partir de PostgreSQL 8.0 es posible
mantenerlos en otro lugar).
Cada tabla o ndice est almacenado en un archivo independiente, los nombres de
archivos se pueden consultar en el catlogo.
tem

Descripcin

PG_VERSION

Archivo que contiene el nmero de versin de PostgreSQL.

base

Directorio con subdirectorios por cada base de datos.

global

Directorio con subdirectorios para todo el cluster, como


pg_database.

pg_clog

Directorio con datos de transacciones.

pg_multixact

Directorio que contiene la multitransaccin de los Datos (utilizado


para los bloqueos de fila compartidas).

pg_notify

Directorio que contiene el estado de los datos LISTEN/NOTIFY.

pg_serial

Directorio que contiene informacin sobre las transacciones


serializables committed

pg_snapshots

Directorio que contiene las instantneas (snapshots) exportadas

pg_stat_tmp

Directorio con archivos temporales para el subsistema de


estadsticas

pg_subtrans

Directorio con datos de subtransacciones.

pg_tblspc

Directorio con enlaces simblicos a tablespaces.

pg_twophase

Directorio con
preparadas.

pg_xlog

Directorio con archivos WAL (Write Ahead Log).

archivos

de

estado

para

transacciones

postmaster.opts Fichero con opciones de arranque de postmaster utilizadas.

postmaster.pid

Fichero de bloqueo con el PID actual del postmaster, La ruta del


directorio del cluster de datos, fecha y hora de inicio del
postmaster, nmero de puerto, ruta del directorio del dominio
Unix (vaco en Windows), primera direccin valida de
listen_address (direccin IP o * o vacia si no escuchando en
TCP), y el ID de memoria compartida (shared mem) ID segmento
44

tem

Descripcin
(este archivo no est presente despus que el servidor se
detiene).

Para cada base de datos en el clster hay un subdirectorio dentro PGDATA/base ,


el nombre de OID de la base de datos en pg_database . Este subdirectorio es la
ubicacin predeterminada para los archivos de la base de datos, en particular, sus
catlogos del sistema se almacenan all.
Cada tabla y el ndice se almacenan en un archivo independiente. Para las
relaciones normales, estos archivos tienen el nombre de la tabla o de ndice.

PostgreSQL Lmites de espacio en disco


En la tabla de abajo se describen algunos lmites en el espacio de disco que
maneja PostgreSQL:
Objeto

Limite

base de datos

Sin lmites (existen bases de datos de 32 TB) .

tabla

32 TB.

fila

400 GB.

campo

1 GB.

filas en una tabla

Sin lmites.

columnas en una tabla

250-1600 dependiendo el tipo de columna.

ndices en una tabla

Sin lmites.

Tabla: Lmites de espacio en disco que maneja PostgreSQL


Por supuesto, esto realmente no es ilimitado, pero est limitado por el espacio de
disco disponible y el espacio de memoria/swap. El rendimiento puede sufrir
cuando estos valores son inusualmente grandes.
El mximo tamao de una tabla de 32 TB no requiere el soporte de archivos de
gran tamao desde el sistema operativo. Las grandes tablas se almacenan como
mltiples archivos de 1GB, para el sistema de archivos los lmites de tamao no
son importantes.
El tamao mximo de una tabla, el tamao de la fila, y el nmero mximo de
columnas puede ser cuadruplicado por el aumento del tamao de bloque por
defecto a 32k. El tamao mximo de la tabla tambin puede incrementarse
45

utilizando la tabla de particionado. Una limitacin es que los ndices no pueden ser
creados en columnas ms largas que alrededor de 2.000 caracteres.
Afortunadamente, esos ndices son raramente necesarios. La Singularidad es la
mejor garanta por una funcin de un ndice hash MD5 el largo de la columna, y la
indexacin de texto completo permite la bsqueda de las palabras dentro de la
columna.

Dnde estn nuestros datos en el disco?


PostgreSQL tiene la informacin necesaria para funcionar grabada
en el disco duro y organiza los ficheros con nuestros datos
ubicndolos en el directorio que hayamos definido como directorio
de datos (data_directory).
Tener las cosas claras en lo que respecta a este tema nos puede
ayudar en momentos difciles como administradores de bases de datos, en el caso
que nuestros datos se corrompan por alguna causa.
1.
2.
3.
4.
5.
6.
7.

[root@server1 ~]# su - postgres


-bash-4.1$ psql
postgres=# SHOW data_directory;
data_directory
--------------------/var/lib/pgsql/9.2/data
(1 row)

Dentro del directorio de datos encontramos el directorio base donde se graban


todos los datos contenidos en nuestras bases de datos.
1.
2.
3.
4.
5.
6.
7.

-bash-4.1$
-bash-4.1$
-bash-4.1$
total 28
drwx-----drwx-----drwx------

cd /var/lib/pgsql/9.2/data/base
ls -l
ls l
2 postgres nogroup 12288 2011-10-04 17:53 1
2 postgres nogroup 4096 2011-10-04 17:53 11939
2 postgres nogroup 4096 2011-10-04 17:53 11947

En el directorio base existen otros con nombres numricos y cada uno es una
base de datos diferente. Para saber a qu base de datos corresponden se ejecuta:
1. postgres=# SELECT datid,datname from pg_stat_database;
2. datid | datname
3. -------+-------------4.
1 | template1
5. 11939 | template0
6. 11947 | postgres
7. (3 rows)

46

Los valores de datid se corresponden a los valores listados en el directorio base y


la columna datname es el nombre de la base de datos asociada al identificador
numrico.
Crear una base de datos y ver como esto afecta nuestro sistema:
1. postgres=# CREATE DATABASE test_interno;
2. CREATE DATABASE

Se crea un directorio con el nombre 16407 que corresponde a la base de datos


creada.
1.
2.
3.
4.
5.
6.

-bash-4.1$
total 24
drwx-----drwx-----drwx-----drwx------

ls -l /var/lib/pgsql/9.2/data/base/
2
2
2
2

postgres
postgres
postgres
postgres

nogroup
nogroup
nogroup
nogroup

12288 2011-10-04 17:53 1


4096 2011-10-04 17:53 11939
4096 2011-10-04 17:53 11947
4096 2011-10-05 11:31 16407

1. postgres=# SELECT datid,datname from pg_stat_database;


2. datid | datname
3. -------+----------------------4.
1 | template1
5. 11939 | template0
6. 11947 | postgres
7. 16407 | test_interno
8. (4 rows)

Si se lista el nuevo directorio, se ve que ya tiene una serie de ficheros aunque no


se haya creado ninguna tabla todava. Estos ficheros pertenecen al sistema y son
necesarios para que la base de datos funcione.
Crear una tabla en la base de datos con un par de columnas de tipo integer:
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.

postgres=# \c test_interno
You are now connected to database "test_interno" as user "postgres".
test_interno=# CREATE TABLE test001 (id INTEGER, code INTEGER, primary key(id));
NOTICE: CREATE TABLE/PRIMARY KEY will create implicit index "test001_pkey
CREATE TABLE
test_interno=# \d test001
Table "public.test001"
Column | Type
| Modifiers
--------+---------+----------id | integer | not null
code | integer |
Indexes:
"test001_pkey" PRIMARY KEY, btree (id)

El identificador de la tabla test001 y el fichero correspondiente lo podemos obtener


as:
1. test_interno=# SELECT

47

2. pg_relation_filenode('test001'),pg_relation_filepath('test001');
3.
4. pg_relation_filenode | pg_relation_filepath
5. ----------------------+-------------------------6.
16465 | base/16407/16465
7. (1 row)

S la tabla no est en el esquema public se debe preceder del nombre del


esquema. Y el del ndice test001_pkey creado para clave primaria de esta tabla
con:
1.
2.
3.
4.
5.
6.
7.

test_interno=# SELECT
pg_relation_filenode('test001_pkey'),pg_relation_filepath('test001_pkey');
pg_relation_filenode | pg_relation_filepath
----------------------+--------------------------16468 | base/16407/16468
(1 row)

Listando del contenido del directorio de la base de datos (base/16407) se observa


que se han creado dos ficheros con los nombres 16465 y 16468.
1. -bash-4.1$ ls -l /var/lib/pgsql/9.2/data/base/16407/16465
2. -rw------- 1 postgres nogroup 0 2011-10-06 12:09 base/16407/16465
1. -bash-4.1$ ls -l /var/lib/pgsql/9.2/data/base/16407/16468
2. -rw------- 1 postgres nogroup 8192 2011-10-06 12:09 base/16407/16468

Si la tabla o ndice llegan a ser mayores que 1GB, se dividirn a nivel del sistema
de ficheros en ficheros con un mximo de 1GB cada uno. Si por ejemplo, la tabla
llega a ser de 3,5GB, se ver algo similar a esto:
1.
2.
3.
4.
5.

-bash-4.1$
-rw-------rw-------rw-------rw-------

ls -l /var/lib/pgsql/9.2/data/base/16407/16465*
1 postgres pgdba 1073741824 Jul 5 15:11 base/16407/16465
1 postgres pgdba 1073741824 Jul 6 15:11 base/16407/16465.1
1 postgres pgdba 1073741824 Jul 7 15:11 base/16407/16465.2
1 postgres pgdba 536870912 Jul 8 15:11 base/16407/16465.3

Ms informacin sobre las funciones de Administracin del Sistema en:


http://www.postgresql.org/docs/9.2/static/functions-admin.html

Bloques de datos en el disco


Una vez visto como encontrar en el sistema de ficheros las bases de datos con
sus tablas e ndices, tenemos que saber cmo se graban los datos en estos
ficheros.

48

La unidad mnima de almacenamiento en PostgreSQL se denomina pgina (page)


o bloque (block). Un bloque en PostgreSQL ocupa siempre por defecto 8K si se
usa en su totalidad o solo parcialmente. El valor se puede cambiar durante la
compilacin.

El espacio en una pgina o bloque se compone de:


Page_header: Cabecera de bloque. Ocupa 24 bytes.
ItemId: Matriz de pares de valores ItemId (offset, length) con la informacin
necesaria para localizar los elementos (Items) grabados en el bloque. Cada
par ocupa 4 bytes.
Item (row/index): Cabecera de elemento ms los datos en s. Tamao
Variable.
Espacio especial: Usado cuando el bloque pertenece a un ndice. Tamao
variable.
El espacio usado por una cabecera de bloque (Page_header) se usa para guardar
diferentes parmetros que nos ayudarn a localizar diferentes partes del bloque y
guardar cierta informacin asociada al bloque.
En cada elemento (Item) se guardan una cabecera de datos con un tamao fijo
(23 bytes), una pequea cabecera opcional de datos con tamao variable y los
datos en s de nuestras tablas o ndices.

49

Para una completa descripcin de estas cabeceras y las estructuras usadas para
almacenar los datos en el disco se puede consultar la documentacin y el cdigo
fuente.

PostgreSQL: Espacio en Disco


Una base de datos PostgreSQL puede requerir hasta cinco veces el espacio en
disco para almacenar datos de un archivo de texto.
Como ejemplo, considere un archivo de 100.000 lneas con un entero y
descripcin de texto en cada lnea. Supongamos que la cadena de texto mide en
promedio veinte bytes de longitud. El archivo plano sera de 2.8 MB. El tamao del
Archivo de base de datos PostgreSQL que contenga estos datos se puede estimar
en 5.2 MB:
24 bytes: cada fila de cabecera (aproximado)
24 bytes: un campo int y un campo de texto
+ 4 bytes: punteros en la pgina de tupla
-------------------------------------------52 bytes por fila

El tamao de pgina de datos en PostgreSQL es 8192 bytes (8 KB), por lo que:


8192 bytes por pgina
--------------------- = 158 filas por pgina de base de datos (redondeado)
52 bytes por fila
100000 filas de datos
--------------------- = 633 pginas de base de datos (redondeado hacia arriba)
158 filas por pgina
633 pginas bases de datos * 8192 bytes por pagina = 5,185,536 bytes (5.2 MB)

Los ndices no requieren tanta sobrecarga, pero contienen los datos que se estn
indexando, por lo que pueden ser muy grandes tambin.
Los valores NULL se almacenan como mapas de bits, por lo que usan muy poco
espacio.

Tipos de Tablas
En Linux, PostgreSQL almacena las bases de datos en el directorio
/var/lib/pgsql/data/base y a partir de ah un directorio para cada base. En
Windows PostgreSQL almacena los archivos de las bases de datos en el directorio
C:\Archivos de Programa\PostgreSQL\9.2\data\Base.

50

Cada tabla es considerada un archivo, as como los ndices. Los nombres de las
tablas pertenecientes al sistema llevan el prefijo pg_. Por ejemplo, el archivo
PG_VERSION (presente en cada base de datos) contiene la versin mayor con la
que fue creada la base y al cambiar de versin de PostgreSQL es importante
respaldar este archivo.
A continuacin se muestra el contenido de las tablas que PostgreSQL utiliza
como catlogos para mantener el sistema. Cada base de datos que se crea, tiene
estas mismas tablas, salvo la primera (pg_database) que es nica para todas las
bases de datos:
Nombre tabla

Descripcin (que almacena)

pg_database

Bases de datos

pg_class

Clases o tablas

pg_attribute

Atributos o campos de la clase o tabla

pg_index

ndices secundarios

pg_proc

Procedimientos

pg_type

Tipos de datos (del sistema y definidos por el usuario)

pg_user

Usuarios de PostgreSQL

pg_operator

Operadores (del sistema y definidos por el usuario)

Tabla: Contenido de las tablas que se usan como catlogos del sistema
Por ejemplo, para saber que bases de datos hay en el sistema se ejecuta la
consulta:
1. postgres=# SELECT * FROM pg_database;

Para saber que tablas tengo en la base de datos actual:


2. postgres=# SELECT * FROM pg_class;

Si slo queremos saber cuntos registros tiene una tabla, consultamos:


3. postgres=# SELECT relname,reltuples FROM pg_class WHERE relname='mitabla';

Tipos de Datos
Como todos los manejadores de bases de datos, PostgreSQL implementa los
tipos de datos definidos para los estndares SQL/92 y SQL3 (SQL/99) y aumenta
algunos otros.

51

Algunos de estos tipos de datos se muestran en las tablas que estn a


continuacin:
Tipo en
Postgres

Correspondiente en
SQL3

Descripcin

Bool

boolean

valor lgico o booleano


(true/false)

Char(n)

character(n)

cadena de caracteres de tamao


fijo

Date

date

fecha (sin hora)

Float8

real, double
precision

nmero de punto flotante de doble


precisin

int2

smallint

entero de dos bytes con signo

int4

int, integer

entero de cuatro bytes con signo

money

decimal(9,2)

cantidad monetaria

Time

time

Hora en horas, minutos, segundos


y centsimas

timespan

interval

intervalo de tiempo

timestamp

timestamp with time


zone

fecha y hora con zonificacin

varchar(n)

character varying(n)

cadena de caracteres de tamao


variable

Tabla: Tipos de datos del Estndar SQL3 en PostgreSQL


Tipos de datos extendidos en PostgreSQL
Tipo

Descripcin

Box

caja rectangular en el plano

Cidr

direccin de red o de host en IP versin 4

circle

crculo en el plano

Inet

direccin de red o de host en IP versin 4

int8

entero de ocho bytes con signo

Line

lnea infinita en el plano

Lseg

segmento de lnea en el plano

Path

trayectoria geomtrica, abierta o cerrada, en el plano

52

point

punto geomtrico en el plano

polygon

trayectoria geomtrica cerrada en el plano

serial

identificador numrico nico con autoincremento


Tabla: Tipos de datos Extendidos en PostgreSQL

53

Gestin de Bases de Datos PostgreSQL


Para la administracin de un servidor de bases de datos PostgreSQL existen
herramientas libres y gratuitas con interfaces grficas e intuitivas para la
administracin completa de bases de datos PostgreSQL, entre estas herramientas
estn PhpPgAdmin o el PgAdmin y herramientas comerciales como PostgreSQL
Manager. Tambin hay una variedad de herramientas para la administracin de
bases de datos PostgreSQL en modo consola, como el terminal de cliente
interactivo de postgreSQL psql, o las aplicaciones pg_dump y pg_restore para
realizar copias de seguridad y restauracin de bases de datos, o las herramientas
para crear y eliminar bases de datos como createdb, dropdb, y otras ms,
generalmente ubicadas en el directorio /bin dentro del directorio donde se instal
PostgreSQL.

PSQL: La pequea gran herramienta de PostgreSQL


Asumiendo que PostgreSQL ya ha sido instalado e iniciado exitosamente, la
herramienta principal para trabajar en modo lnea de comandos con PostgreSQL
es psql. Con psql tenemos una herramienta completa para poder manipular las
bases de datos PostgreSQL mediante comandos DML (Lenguaje de Manipulacin
de datos) y DDL (Lenguaje de definicin de datos). Psql viene incorporado en la
instalacin del paquete PostgreSQL para Windows o Linux con el mismo tipo de
licencia que el paquete PostgreSQL, es decir BSD (Berkeley Software Distribution)
y se instala en el directorio /bin dentro del directorio de instalacin de
PosgreSQL.
PostgreSQL usa un modelo de comunicacin cliente/servidor. Esto significa que el
servidor est esperando las solicitudes de los clientes, las procesa y regresa el
resultado.
La interface psql permite interactuar con PostgreSQL, por lo que psql es el cliente
interactivo de lnea de comandos de PostgreSQL.
Este programa nos permite realizar las tareas ms comunes como ingresar,
ejecutar un query y ver los resultados obtenidos, pero adems incluye una serie de
caractersticas muy completas en cuanto a la integracin con scripts, que nos ser
de mucha utilidad para automatizar tareas repetitivas o peridicas.
Esta es una breve introduccin para su utilizacin, con la descripcin de las
funciones ms usadas. Antes veamos las sentencias y datos ms usados:

54

Sentencias bsicas en SQL


Comando

Descripcin

CREATE TABLE

Crear una tabla.

INSERT INTO

Insertar datos en una tabla.

SELECT

Desplegar datos.

WHERE

Filas especficas.

DELETE

Remover datos.

UPDATE

Reemplazar actualizar datos.

ORDER BY

Ordenar el resultado.

DROP

Destruir.

Tipos ms comunes de datos


Categora

Tipo

Cadena de
caracteres

CHAR(long)

Long. fija de almacenamiento.

VARCHAR(long)

Long. variable de almacenamiento.

INTEGER

Entero, +/- 2 billones.

FLOAT

Punto decimal, 15 dgitos.

NUMERIC
(precisin, decimal)

Nmero usando una definicin de


precisin y de nmero de decimales.

DATE

Fecha.

TIME

Hora.

TIMESTAMP

Fecha y hora.

Nmero

Fecha/hora

Descripcin

Ejecutando psql desde el sistema operativo


La aplicacin psql se invoca desde la lnea de comandos del sistema operativo
con una serie de opciones (flags) muy abundante con la siguiente sintaxis.
psql [OPCIONES] [BASE DE DATOS [USUARIO]]
55

Algunas de Las opciones ms utilizadas y tiles al momento de invocar la


aplicacin son:

Opcin (flag)

Descripcin

--help

Muestra todas las opciones de psql y sale.

-U USUARIO

Especifica con que usuario se conectar a la base de datos. Si


esta opcin no es utilizada intentar conectarse el usuario que
ejecute psql.

-d [BASE DE
DATOS]

Especifica a que base de datos conectarse inicialmente. (Si esta


opcin no es utilizada intentar conectarse a una base de datos
con el mismo nombre del usuario utilizado para conectarse.)

-h EQUIPO

Especifica en que equipo se encuentra el servidor de base de


datos .Puede indicarse el nombre o la direccin IP del servidor.
Si no se especifica este parmetro, intentar conectarse al
equipo en donde se ejecuta psql.

-p PUERTO

Especifica en que puerto se encuentra ejecutando el servicio de


base de datos en el servidor .Si no se especifica este parmetro,
intentar conectarse al puerto por defecto (5432).

-c [COMANDO] Ejecuta solo el comando indicado como parmetro y luego sale.


-f [ARCHIVO]

Ejecuta los comandos SQL contenidos en archivo indicado como


parmetro y luego sale.

-l

Lista las bases de datos disponibles y luego sale.

-o [ARCHIVO]

Enva los resultados de las consultas al archivo indicado como


parmetro.

-L [ARCHIVO]

Enva el registro de toda la sesin a un archivo indicado como


parmetro. Es muy til para mostrar una serie de comandos
ejecutados y sus resultados.

-H

Genera el resultado de las consultas en formato HTML.(La


combinacin de este comando con la opcin -o nos permite
realizar un script que genere reportes de manera muy sencilla.

-A

Genera el resultado de las consultas sin formatear el resultado.


Es muy til para pasar datos a otros formatos (por ejemplo, para
importar un archivo de texto a Excel)

-t

Muestra solo las filas sin cabeceras y sin contadores.

-e

Hace eco de la consulta enviada al servidor.


56

-E

Hace eco de todas las consultas enviadas al servidor.

-x

Activa el formato expandido para mostrar los resultados. Este


formato muestra cada fila como una especie de ficha,
encabezada por el nmero de fila y con una lnea por cada
columna.

-F [CADENA]

Utiliza la cadena indicada como separador entre columnas.


Utilizando esta opcin en conjunto con -a se pueden generar
archivos tipo CSV (delimitados por comas). Por defecto es '|'.

-t

Imprime solo las filas seleccionadas (sin encabezados).

Algunos ejemplos de la utilizacin de estas opciones:


Invocando psql especificando usuario, equipo, puerto y base de datos.
3.
4.
5.
6.
7.

-bash-4.1$ psql -U testuser -h 192.168.0.10 -p 5432 -d test


psql (8.4.13)
Type "help" for help.
test=#

Generar un archivo tipo CSV (delimitado por comas) con el resultado de una
consulta. Este archivo se puede abrir desde Excel.
1.
2.
3.
4.
5.
6.
7.
8.
9.

-bash-4.1$ psql -U testuser -d test -F ";" -A -c "select * from table" -o table.csv


-bash-4.1$ cat testtable.csv
Id;col1;col2
100;hola;mundo
101;ciao;mondo
102;hello;world
103;bonjour;monde
(4 filas)
-bash-4.1$

57

Generar un reporte HTML a partir de una consulta.


1.
2.

-bash-4.1$ psql -U testuser -d test -H -c "select * from table" -o table.html


-bash-4.1$ firefox table.html

Ejecutando psql en modo interactivo


Una vez dentro de psql, entramos en modo interactivo, es decir, ejecutamos un
comando SQL y psql nos muestra el resultado del mismo.
En este modo tenemos tambin una gran cantidad de posibilidades, gracias a los
comandos propios de psql.
Estos comandos se ejecutan directamente desde la lnea de entrada (prompt) de
pql y tienen la caracterstica de estar siempre precedidos por la barra invertida \.
Algunos de los comandos internos ms utilizados son:
Comando

Descripcin

\c BASE DE
Permite reconectarse. Recibe como parmetros la base de
DATOS USUARIO
datos, usuario, equipo y puerto.
EQUIPO PUERTO
\q

Sale de psql.

\timing

Habilita en reporte de tiempos de ejecucin. Es muy til para


registrar cunto tarda un SQL en ejecutarse.

\! COMANDO

Ejecuta el parmetro ingresado en el sistema operativo. Si no


se especifican parmetros sale temporalmente (hasta que se
cierra con exit) a la lnea de comandos del sistema operativo.

\e ARCHIVO

Invoca al editor de textos predeterminado. Si no se especifica


el parmetro ARCHIVO, edita el ltimo comando SQL (del
58

bfer interno). Si se especifica un archivo lo abre con el mismo


editor. (Para definir el editor preferido, usa la variable
EDITOR del sistema operativo.).
Comando

Descripcin

\g ARCHIVO

Ejecuta los comandos SQL almacenados en el bfer. Si se


especifica el parmetro ARCHIVO, el resultado es enviado al
archivo indicado, si no se muestra por pantalla.

\p

Imprime el contenido el bfer de SQL.

\w ARCHIVO

Guarda el contenido del bfer de SQL en un Archivo


(parmetro obligatorio).

\s ARCHIVO

Muestra la historia (ltimos comandos SQL ejecutados). Si se


especifica el parmetro ARCHIVO, el resultado es enviado al
archivo indicado, si no se muestra por pantalla..

\i ARCHIVO

Ejecuta los comandos SQL que estn almacenados en el


archivo.

\o ARCHIVO

Enva los resultados de las consultas al archivo indicado como


parmetro.

\dt

Lista todas las tablas.

\d TABLA

Lista las columnas de la tabla indicada como parmetro.


(Describe la tabla)

Algunos ejemplos de los comandos internos:


1.
2.
3.

-bash-4.1$ psql
psql (8.4.13)
Type "help" for help.

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.

postgres=# \l
List of databases
Name
| Owner
|Encoding| Collation |
Ctype
|
Acces
------------+----------+--------+-------------+-------------+----------------Pruebas
| pruebas | UTF8
| en_US.UTF-8 | en_US.UTF-8 |
dbadmision | postgres | UTF8
| en_US.UTF-8 | en_US.UTF-8 |
fiscal
| fiscal
| UTF8
| en_US.UTF-8 | en_US.UTF-8 |
postgres
| postgres | UTF8
| en_US.UTF-8 | en_US.UTF-8 |
template0 | postgres | UTF8
| en_US.UTF-8 | en_US.UTF-8 | =c/postgres
: postgres=CTc/postgres
template1 | postgres | UTF8
| en_US.UTF-8 | en_US.UTF-8 | =c/postgres
: postgres=CTc/postgres
test
| testuser | UTF8
| en_US.UTF-8 | en_US.UTF-8 | =CTc/testuser
: testuser=CTc/testuser
7 (rows)
postgres=#\c test
You are now connected to database "test".
59

19. test=#

Listado de bases de datos, conexin a una base de datos en particular.


1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.

test=# \! vi cp.sql
select * from testtable;
select col2,col1 from testtable;
~
~
:wq
test=# \i cp.sql
id | col1
| col2
-----+---------+------100 | hola
| mundo
101 | ciao
| mondo
102 | hello
| world
103 | bonjour | monde
(4 rows)

-- Crea el archivo cp.sql con vi

-- Graba cp.sql en shell


-- Ejecuta cp.scl

col2 | col1
-------+--------mundo | hola
mondo | ciao
world | hello
monde | bonjour
(4 rows)
test=#

Ejecutar un comando del Sistema Operativo. Ejecutar SQLs desde un archivo.


1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.

test=# \dt
List of relations
Eschem |
Name
| Type | Owner
---------+--------------+-------+---------public | amigos
| tabla | testuser
public | clientes
| tabla | testuser
public | cuentas
| tabla | testuser
public | invitaciones | tabla | testuser
public | testtable
| tabla | testuser
public | usuarios
| tabla | postgres
(6 rows)
test=#\d testable
Table public.testtable
Column |
Type
| Modifiers
---------+-------------------+-----------id
| integer
|
col1
| character varying |
col2
| character varying |

Listado de tablas, lista de columnas de una tabla (describe).

Controlando una Sesin en psql en modo interactivo


Para crear una base de datos:

60

1.
2.

postgres=# create database test;


postgres=# \q
-- para salir de PostgreSQL

Para conectarse a una base de datos hay que teclear:


3.

-bash-4.1$ psql d test U testusr

En este caso test es el nombre de la base de datos, pero puede ser cualquier otro.
Hay que diferenciar entre maysculas y minsculas
Una vez conectados al servidor PostgreSQL, teclear lo siguiente:
4.
5.
6.
7.
8.
9.
10.

test=>SELECT CURRENT_USER;
current_user
-------------testuser
(1 row)
test=>

Esto debe mostrar el login name bajo la lnea punteada.


La lnea test=> indica que el servidor est esperando el siguiente query, Teclear:
11.
12.
13.
14.
15.
16.
17.

test=>SELECT CURRENT_TIMESTAMP;;
now
---------------------------2013-05-31 23:03:15.578-05
(1 row)
test=>

Esto debe mostrar la fecha y la hora actual.

Query multi-lnea en modo interactivo


En psql los comandos se completan cuando digitamos ; \g. Por ejemplo:
18.
19.
20.
21.
22.
23.
24.
25.
26.

test=# SELECT
test-# 1 + 3
test -#;
column
--------4
(1 row)

-- el prompt cambia de =# a -# para indicar


-- que la sentencia SQL an no finaliza
-- Esto debe responder con un 4

test=#

En PostgreSQL las ordenes SQL pueden escribirse en maysculas o en


minsculas. Por claridad se recomienda escribir palabras especiales en
maysculas.

61

Con las teclas de las flechas derecha e izquierda se puede recorrer lo que se
escribe, con las flechas arriba y abajo se recuperan las lneas previamente
escritas.

Query buffer y help


Se puede teclear indefinidamente, hasta que se use el punto y coma (;) o la
diagonal invertida-g (\g). Todo esto se ir guardando en el query buffer.
Si se teclea \p, se puede ver todo lo acumulado en el query buffer.
Para borrar el buffer se teclea \r.
\? Muestra todos los comandos que inician con diagonal invertida
Para salir de una sesin usar \q.
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.

test =# CREATE TABLE alltypes(


test -# estado CHAR(3),
test -# nombre char (20),
test -# hijo INTEGER,
test -# distancia FLOAT,
test -# presupuesto NUMERIC(16,2),
test -# nacimiento DATE,
test -# llegada TIME,
test -# inicio TIMESTAMP);
CREATE TABLE
test =#

12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.

test =# INSERT INTO alltypes


test -# VALUES(
test -# 'MEX',
test -# 'Mauricio',
test -# 0,
test -# 10.7,
test -# 6289.08,
test -# '14/08/1984',
test -# '7:45',
test -# '25/03/2007 10:30:00');
INSERT 0 1
test =#

Usando valores NULL y BLANK


NULL es un valor especial que es vlido en cualquier columna. Lo usamos cuando
se desconoce el valor o cuando no aplica.
1. test =# INSERT INTO alltypes (estado, nombre)
2. test -# VALUES ('AGS', 'Gabriel');
3. test =# select * from alltypes;

En algunas columnas no se insert valor, Qu contienen?

62

4. test =# SELECT * FROM alltypes WHERE hijo IS NULL;

Hay diferencia entre cero y NULL (hijo->Mauricio y Gabriel)


5. test =# SELECT * FROM alltypes WHERE hijo <> 100;

Los que tienen NULL en la columna hijos no aparecen


6.
7.
8.
9.
10.
11.

test =# INSERT INTO alltypes (estado, nombre)


test -# VALUES ('', 'Arturo'); -- ES UNA CADENA BLANK, LOS CAMPOS
-- NUMERICOS NO PUEDEN SER BLANK
test -# VALUES (NULL, 'Jos');
test =# SELECT * FROM alltypes WHERE estado IS NULL;
test =# SELECT * FROM alltypes WHERE estado = '';

NULL vs BLANK
Una columna tipo cadena de caracteres adems de ser NULL, tambin puede ser
blank.
Un campo numrico no puede ser blank, solo NULL.
12.
13.
14.
15.
16.

test
test
test
test
test

=#
-#
-#
=#
=#

INSERT
VALUES
VALUES
SELECT
SELECT

INTO alltypes (estado, nombre)


('', 'Arturo');
(NULL, 'Jos');
* FROM alltypes WHERE estado IS NULL;
* FROM alltypes WHERE estado = '';

Valores DEFAULT
Cuando no se da un valor a la columna se le asigna un NULL.
Cuando creamos una tabla, con la palabra clave DEFAULT en la columna,
podemos dar un valor cuando no se asigne alguno.
Por ejemplo, para la columna timestamp el valor de default puede ser una
variable interna de PostgrSQL que regresa la fecha y la hora actual.
1.
2.
3.
4.
5.
6.
7.
8.
9.

test=#
test-#
test-#
test-#
test-#
test=#
test=#
test-#
test=#

CREATE TABLE cuenta (


nombre VARCHAR(20),
balance NUMERIC(16,2) DEFAULT 0,
activa CHAR(2) DEFAULT 'SI',
creada TIMESTAMP DEFAULT CURRENT_TIMESTAMP);
\d cuenta
INSERT INTO cuenta (nombre)
VALUES ('Palacio de Hierro');
SELECT * FROM cuenta;

Ejemplos
63

1.
2.
3.
4.
5.
6.
7.

test=# ALTER TABLE alltypes ALTER inicio


test-# SET DEFAULT CURRENT_TIMESTAMP;
ALTER TABLE
test=# INSERT INTO alltypes (estado, nombre)
test-# VALUES ('MEX', 'Melissa');
INSERT 0 1
test=# SELECT * FROM alltypes;

pg_dump y pg_dumpall
Las herramientas clientes pg_dump y pg_dumpall nos ayudan tanto para respaldar
las tablas o bases de datos o para migrarlas de un sistema a otro en un formato
transportable. Estas utilidades vienen incluidas en el paquete de instalacin
PostgreSQL para Windows o Linux y tienen el mismo tipo de licencia que el
paquete PostgreSQL, es decir BSD (Berkeley Software Distribution). Se instalan
en el directorio "\bin" dentro del directorio de instalacin de PosgreSQL.
La utilidad pg_dump apareci en la versin "release 0.02" de Postgres95, pero se
mejor desde la versin de PostgreSQL "release 7.1".
En algunos casos al actualizar la versin de PostgreSQL ser necesario primero
respaldar las tablas con estas herramientas para posteriormente volverlas a
cargar; pg_dump se emplea para respaldar una base de datos o una tabla en
particular, mientras que pg_dumpall respalda todas las bases de datos del
sistema. Su sintaxis es la siguiente:
pg_dump [opciones.] [nombre_base_datos]
A continuacin se muestran algunas de sus opciones ms tiles:
-a: Respalda solo los datos en un archivo de texto plano, no las definiciones
(esquema).
-f formato: Selecciona el formato de salida para el archivo que puede ser:
p: Es el formato predeterminado; el archivo se genera en un archivo plano de
texto de tipo "SQL script".
t: La salida se genera en un archivo ".tar"; este formato puede ser modificado
en la entrada del programa que recupera respaldos pg_restore. Usando este
formato de archivo se permite excluir objetos de la base de datos en el
momento en que se restaura.
c: El archivo de salida se genera en un formato modificable para la entrada
en el programa pg_restore. Este es el formato ms flexible para reordenar la
64

carga de datos con las definiciones de los objetos (esquema). Este formato
se comprime por defecto.
-s: Solamente respalda el esquema de la base de datos (definiciones de
objetos), no los datos.
-t tabla: Respalda los datos y el esquema de la tabla especificada.
La forma ms general de emplear pg_dump para respaldar slo una tabla, es la
siguiente:
pg_dump -t mitabla mibase > mibase.mitabla.dump
Con lo cual en el archivo "mibase.mitabla.dump" tenemos un archivo con los datos
y el esquema de la tabla 'mitabla' para poder recuperar toda la informacin de la
misma.
Al respaldar una tabla de esta manera, lo primero que hace pg_dump es tratar de
identificar al usuario creador de la tabla, luego crea la tabla, fija los permisos
existentes, copia los datos y finalmente crea el ndice si es que la tabla tiene un
ndice asociado.
Es mejor comprimir los archivos para ocupar el mnimo espacio posible. Por
ejemplo, podemos hacerlo as:
pg_dump -t mitabla mibase | gzip -9c > mibase.mitabla.dump.gz
pg_dump -t mitabla mibase | bzip2 -c > mibase.mitabla.dump.bz
Ambos programas de compresin (gzip y bzip2) pueden ser consultados con el
sistema man (de manual) en Linux. Para recuperar la informacin en la base de
datos, podemos emplear la siguiente instruccin en la lnea de comandos:
gunzip -c mibase.mitabla.dump.gz
bunzip2 -c mibase.mitabla.dump.bz

pg_restore
Esta herramienta restaura o recupera una base de datos PostgreSQL desde un
archivo creado con la herramienta pg_dump. Pg_restore apareci por primera vez
en la versin 7.1 de PostgreSQL. Al igual que las anteriores, esta utilidad se
instala en el directorio "\bin" dentro del directorio de instalacin de PosgreSQL y
tiene el mismo tipo de licencia (BSD) que el paquete PostgreSQL.

65

Esta utilidad restaura una base de datos de PostgreSQL desde un archivo


especificado, este archivo guarda los comandos SQL necesarios para reconstruir
la base de datos al estado en el cual fue guardada o respaldada y su sintaxis es:
pg_restore [opciones] [nombre_archivo_a_restaurar]
Algunas opciones que tiene pg_restore son las siguientes:
-a: Recupera solamente los datos, no el esquema o definicin de objetos.
-d nombre_db: Se conecta a la base de datos especificada y recupera
directamente los datos en la misma.
-e: Termina la operacin si ocurre un error mientras se envan los comandos
SQL para restaurar la base de datos. Por defecto, si se encuentra un error en
la operacin, contina la recuperacin y al final se muestra un contador y una
descripcin de los errores ocurridos.
-f formato: Especifica el formato del archivo, esta opcin no es necesaria ya
que pg_restore determina el formato de manera automtica. El formato del
archivo puede ser uno de los siguientes:
t: El archivo es un archivo ".tar". Usando este formato de archivo se permite
excluir objetos de la base de datos en el momento en que se restaura.
c: El formato de archivo se puede modificar en pg_restore. Este es el formato
ms flexible para reordenar la carga de datos con las definiciones de los
objetos (esquema).
Este formato se comprime por defecto.
-s: Solamente recupera el esquema de la base de datos (definiciones de
objetos), no los datos.
-t tabla: Recupera la definicin y/o los datos de la tabla especificada.
A continuacin se muestra un ejemplo respaldando una base de datos llamada
mydb con pg_dump y luego la restauro con pg_restore en una nueva base de
datos llamada newdb:
pg_dump -ft mydb > db.tar
pg_restore -d newdb db.tar

createdb y dropdb
66

Una de las primeras operaciones para probar la conexin y correcta instalacin del
servidor de bases de datos PostgreSQL es crear una base de datos. Para crear
una base de datos se puede utilizar la aplicacin createdb y para eliminarla del
servidor se utiliza dropdb.
Estas aplicaciones se instalan en el directorio "\bin" dentro del directorio de
instalacin de PosgreSQL y su sintaxis es la siguiente:
createdb nombre_base_datos
dropdb nombre_base_datos
Un ejemplo de cmo crear una base de datos (mydb) mediante la aplicacin
createdb se muestra a continuacin:
createdb mydb
Createdb es una aplicacin alternativa al comando SQL "CREATE DATABASE" y
luego de ejecutarse esta aplicacin se muestra la respuesta "CREATE
DATABASE".
Si se recibe un mensaje similar a "createdb: command not found" puede ser
porque PostgreSQL no fue instalado apropiadamente o porque no se encuentra la
ruta de la aplicacin en el directorio "\bin" del directorio de instalacin de
PostgreSQL, entonces se debe probar escribiendo la ruta completa en donde se
encuentra la aplicacin y ejecutarla.
En Linux por ejemplo, la aplicacin createdb se encuentra en "/usr/bin/createdb"
mientras que en Windows se encuentra en "C:\Archivos de programa\PostgreSQL\
8.1\bin\createdb".
Otra respuesta de error al ejecutar createdb puede ser la siguiente:
psql: could not connect to server: Connection refused
Is the server running on host "nombre_server" and accepting
TCP/IP connections on port 5432?
En cuyo caso deberemos revisar los archivos de configuracin de PostgreSQL
(pg_hba.conf, pg_ident.conf y postgresql.conf) ubicados en el directorio "/Data"
donde se instal el servidor PostgreSQL o debemos reinstalar el servidor
PostgreSQL porque no se puede establecer una conexin al servidor.
Para eliminar una base de datos fsicamente del servidor se utiliza la aplicacin
dropdb, la misma que es una aplicacin alternativa al comando SQL "DROP
DATABASE".

67

Al eliminar una base de datos se eliminan tambin todos los objetos que contiene
la base de datos, adems se debe tener cuidado porque no se puede recuperar
una base de datos una vez que esta se elimine.

Postmaster y pg_ctl
Luego de instalar PostgreSQL y antes de acceder a cualquier base de datos se
debe arrancar el servidor PostgreSQL. Esta operacin se la puede realizar
mediante el programa llamado postmaster, indicndole al mismo donde se
encuentra el directorio "\Data" de PostgreSQL mediante la opcin -D. Este
programa se encuentra en el directorio "bin" donde se instal PostgreSQL
(/usr/bin/postmaster) y la manera ms comn de arrancar el servidor mediante la
aplicacin postmaster es:
postmaster -D /var/lib/pgsql/data
Pg_ctl es una aplicacin incluida tambin en el directorio "bin" donde se instala
PostgreSQL, y se proporciona para simplificar algunas tareas como iniciar y
detener al servidor PostgreSQL. Por ejemplo:
pg_ctl start -l logfile
Esta operacin arranca el servidor y coloca las transacciones en el archivo
especificado (logfile). La opcin de -D le indica al servidor PostgreSQL donde se
encuentra el directorio "\Data" que es donde normalmente se guardan las bases
de datos.

PgAdmin
PgAdmin es una aplicacin con interfaz grfica comprensible para el diseo y
administracin total de bases de datos PostgreSQL; esta aplicacin est diseada
para ejecutarse en sistemas operativos como GNU/Linux y Windows. PgAdmin
versin 3 se ejecuta desde la versin de la base de datos PostgreSQL 7.3 y
superiores. Para versiones anteriores de la base de datos, se debe usar la versin
de PgAdmin2.

68

PgAdmin se distribuye libremente bajo licencia de tipo GNU separadamente de


PostgreSQL y se puede descargar su ltima versin (PgAdmin3-1.4.3) desde el
sitio web "http://www.pgadmin.org/download/" en las versiones para Linux o
Windows.
La versin de PgAdmin III tiene las siguientes caractersticas:
Esquema de navegacin de todos los objetos de PostgreSQL.
Dilogos de creacin y propiedades de objetos (usuarios, tablas, bases de
datos, disparadores, etc.).
Herramienta de edicin/visualizacin de tablas.
Habilidad para navegar y conectarse a mltiples servidores a la vez.
Interfaz de usuario intuitiva y traducida a ms de 20 idiomas.
La ventana principal muestra la estructura de la base de datos y todos los
detalles de los objetos contenidos en la misma.
Se puede controlar o administrar los usuarios de las bases de datos,
manejando los privilegios, usuarios, grupos y contraseas.
Permite llevar un control sobre el estado del servidor de bases de datos,
permitiendo iniciarlo o detenerlo.
Posee una herramienta avanzada para consultas, permitiendo ejecutar
cualquier sentencia SQL.
69

Permite exportar datos en distintos formatos a partir de una consulta SQL


generada. Permite ver y editar los datos de una consulta a una tabla o vista.
Tiene una herramienta de Mantenimiento que ejecuta tareas como
reconstruir las estadsticas de las bases de datos y tablas, limpiar o eliminar
los datos sin usar y reorganizar los ndices.
Permite sacar copias o respaldos de las bases de datos y restaurarlas
haciendo uso de las herramientas pg_dump y pg_restore de PostgreSQL.
La ventana del "estado del servidor" muestra los usuarios actualmente
conectados, los bloqueos y caractersticas del servidor seleccionado.

70

Administracin de Sesiones
Inicio y Tipos de sesiones:
Los usuarios pueden iniciar sesiones al acceder a una base de datos PostgreSQL
utilizando diversos tipos de procesos frontend:
Ejecutando el programa de terminal interactiva psql, que permite introducir,
editar y ejecutar sentencias SQL sobre una base de datos.
Utilizando una herramienta grfica como PgAdmin III para crear y manipular
bases de datos.
Mediante un programa de aplicacin hecho a medida que incorpore
sentencias SQL para acceder a la base de datos.
En nuestras prcticas utilizaremos la terminal interactiva psql y PgAdmin III para
conectarnos a una base de datos y practicar sobre ella el lenguaje SQL.

Control de sesiones:
Proceso:
En primer lugar, nos conectamos a nuestro servidor de bases de datos
PostgreSQL.
1.
2.
3.
4.
5.

$ psql -h servidor -U postgres -d postgresql


(9.2.6, server 8.4.11)
Type "help" for help.
postgres=#

Cantidad de sesiones y actividad de los usuarios


Saber cuntas sesiones o cuantos usuarios estn conectados a mi servicio
postgres
6.

postgres=# select count(*) from pg_stat_activity;

Retorna:

71

Obtener el registro completo de la actividad de los usuarios y determinar los


campos de la tabla de sesiones:
7.

postgres=# select * from pg_stat_activity;

Retorna:

Cerrar sesiones de usuarios conectados a Postgresql (conexiones activas


de otros usuarios)
Muchas veces hay usuarios que han dejado su conexin abierta y est
bloqueando la base de datos impidiendo hacer algunas tareas de administracin,
vacuums, renames, etc o en ciertas ocasiones deseamos eliminar una Base de
Datos y no se deja porque conservan conexiones sin actividad (IDLE). En
PostgreSQL podemos solventarlo desde el cliente psql con la funcin
pg_terminate_backend. Cada conexin a la base de datos en PostgreSQL tiene
asociado un proceso PID (process id) y esta informacin se almacena en la
tabla pg_stat_activity. La funcin pg_terminate_backend nos permite enviar una
seal a dicho proceso para que finalice una sesin especfica de un usuario.
Proceso:
En primer lugar, nos conectamos a nuestro servidor de bases de datos
PostgreSQL
1.
2.
3.
4.
5.

$ psql -h servidor -U postgres -d postgres


sql (9.1.2, server 8.4.11)
Type "help" for help.
postgres=#

Ejecutamos la consulta que nos proporcionar el listado de todas las conexiones


establecidas a nuestra base de datos.
Este paso es opcional, pero realizarlo siempre nos dar una idea de
las conexiones existentes, y si estn activas, o solo permanece la conexin
(IDLE).
Obtener los procesos de postgres activos. Dentro del "psql" ejecuto el comando:
72

6.

postgres=#
select datname, pid, usename, application_name, client_addr, query from
pg_stat_activity;

Que regresa:

Como vemos existen 4 registros en la tabla pg_stat_activity, que se corresponden


con 4 conexiones establecidas pero 3 sin actividad (IDLE). Para cada conexin se
almacena adems del PID del proceso pid, IP y puerto, usuario de conexin, query
lanzada, estado,
Una vez obtenida la lista con los procesos, solo queda utilizar la funcin
pg_terminate_backend(pid).
Su uso es sencillo, si deseamos eliminar una determinada conexin le pasamos a
la funcin, el pid de dicha conexin:
Si se quiere matar al proceso 1108 (que est como IDLE en este ejemplo), se
puede ejecutar el comando:
7.

postgres=# select pg_terminate_backend(pid) from pg_stat_activity where pid = 1108;

8.

postgres=#
select datname, pid, usename, application_name, client_addr, query from
pg_stat_activity;

73

Que regresa:

Por supuesto, cuidado al matar procesos de Postgresql, se tiene que saber


realmente lo que se est haciendo!!!!!
Para eliminar todas las conexiones sin actividad, con una nica instruccin:
9.

select pg_terminate_backend(pid) from pg_stat_activity where query = '<IDLE>';

Para eliminar todas las conexiones de una determinada base de datos, con una
nica instruccin:
10. postgres=#
'test';

select pg_terminate_backend(pid) from pg_stat_activity where datname =

Ms informacin al respecto en:

http://www.postgresql.org/docs/8.2/interactive/functions-admin.html#FUNCTIONSADMIN-SIGNAL-TABLE

74

Caso de Estudio
El diagrama siguiente es un modelo pequeo, pero servir para las
demostraciones de la administracin de la estructura de los objetos con el uso de
Sentencias DDL, manipulacin de la informacin con el uso de Sentencias DML,
administracin de los procesos transaccionales con el uso de Sentencias TCL y
administracin de privilegios en los objetos con el uso de Sentencias DCL en
PostgreSQL.
Descripcin: Una universidad realiza el registro de contactos, que son las
personas que podran ser potenciales postulantes a diferentes carreras. Los
postulantes debern pertenecer a un periodo acadmico y debern elegir una
modalidad as como la carrera a la que quieren postular. Por lo general en un ao
solo existen dos periodos acadmicos, por ejemplo los periodos acadmicos del
ao 2008 fueron: 2008-1 y 2008-2. El contacto debe tener los datos personales del
sujeto as como la fecha de creacin. El postulante debe tener registrado si asisti
a su examen de admisin, y si ingres o no, debe tener tambin establecido el
puntaje que alcanz en el examen.
Con esos datos podemos comenzar a elaborar la estructura de nuestro sistema de
informacin y las relaciones que existen entre todos sus objetos: DBAdmision,
Admisin, Persona, carrera, peracad (perodo acadmico), modalidad, postulante
y contacto

75

Sentencias DDL
El Lenguaje de Definicin de Datos (Data Definition Language - DDL) sirve para
modificar la estructura de los objetos en una base de datos.
El DDL se utiliza para describir todas las estructuras de informacin y los
programas que se usan para construir, actualizar e introducir la informacin que
contiene una base de datos. El DDL permite al administrador de la base
especificar los elementos de datos que la integran , su estructura y las relaciones
que existen entre ellos, las reglas de integridad, los controles a efectuar antes de
autorizar el acceso a la base.
Estas sentencias bsicamente son: CREATE, ALTER, DROP y TRUNCATE.

--0) CREACION DE TABLESPACE


CREATE TABLESPACE tablespace_name [ OWNER user_name ]
LOCATION directory
CREATE TABLESPACE registra un nuevo espacio de tabla en todo el clster. El
nombre del espacio de tabla debe ser distinto del nombre de un espacio de tabla
existente en la base de datos del clster.
Un espacio de tablas permite a los superusuarios definir una ubicacin alternativa
del sistema donde los archivos de datos contienen los objetos de las Bases de
Datos (como tablas e ndices).
Un usuario con privilegios adecuados puede pasar el tablespace_name para
CREAR BASES DE DATOS, CREAR TABLAS, CREAR INDIXES o Agregar
RESTRICCIONES para tener los archivos de datos para estos objetos
almacenados en el espacio de tablas especificado.
Parmetros de Entrada
Nombre del Espacio de Datos, no debe comenzar con pg_,
tablespace_name
porque son nombres reservados para los sistemas.
Nombre del propietario del tablespace, default - usuario que
user_name
crea el tablespace. Solo los superusuarios pueden crear
tablespaces, pero se les puede asignar a no superusuarios
Directorio usado por el tablespace. El directorio debe estar
directory
vacio, debe ser de propiedad del usuario del sistema
PostgrSQL y especificado por una ruta absoluta.
Salidas ms usuales
CREATE TABLESPACE
Mensaje devuelto si la orden se completa satisfactoriamente.
76

ERROR: user username is not allowed to create/drop tablespaces.


Ha de tener el privilegio especial CREATEDB para crear bases de datos.
Los tablespaces son nicamente soportados por sistemas que soportan links
simblicos y la instruccin no puede ser ejecutada desde una transaccin.
Ejemplos:
Crear el tablespace dbspace en /data/dbs:
1.

CREATE TABLESPACE dbspace LOCATION '/data/dbs';

Crear el tablespace indexspace en /data/indexes de propiedad del usuario


indexuser:
2.

CREATE TABLESPACE indexspace OWNER indexuser LOCATION '/data/indexes';

--1) CREACIN DE BASE DE DATOS (DATABASE):


CREATE DATABASE name
[ [ WITH ] [ OWNER [=] user_name ]
[ TEMPLATE [=] template ]
[ ENCODING [=] encoding ]
[ LC_COLLATE [=] lc_collate ]
[ LC_CTYPE [=] lc_ctype ]
[ TABLESPACE [=] tablespace_name ]
[ CONNECTION LIMIT [=] connlimit ] ]
Para crear una base de datos, debe ser un superusuario o tener el privilegio
especial CREATEDB.
Normalmente, el creador se convierte en el propietario de la nueva base de datos.
Los Superusuarios pueden crear bases de datos de propiedad de otros usuarios
mediante el uso de la clusula OWNER. Incluso pueden crear bases de datos
pertenecientes a usuarios sin privilegios especiales. Los no superusuarios con
privilegio CREATEDB slo pueden crear bases de datos de su propiedad. De
forma predeterminada, la nueva base de datos se crea clonando el sistema
estndar de base de datos template1.

name
user_name
template

Parmetros de Entrada
Nombre de la Base de Datos
Nombre del propietario de la Base de Datos, default usuario que crea la base de datos
template1: default - con locales adicionados.
template0: base de datos virgen con los objetos estndar
77

encoding

Set de caracteres. 'UTF8', 'SQL_ASCII'..


Orden de comparacin. 'Spanish, Colombia' Afecta el
lc_collate
orden y los ndices aplicados a los strings (order by)
Clasificacin de caracteres. 'Spanish, Colombia'..Afecta a
lc_ctype
la clasificacin de los caracteres: maysculas, minsculas y
dgitos.
Nombre del tablespace donde se ubica Base de Datos. Si
tablespace_name
no se especifica queda en el tablespace pg_default.
Nmero de conexiones simultneas a la Base de Datos.
connlimit
-1 (default) significa que no hay lmite.
Salidas ms usuales
CREATE DATABASE
Mensaje devuelto si la orden se completa satisfactoriamente.
ERROR: user username is not allowed to create/drop databases
Ha de tener el privilegio especial CREATEDB para crear bases de datos.
Ejemplos:
Crear la Base de Datos DBAdmision:
1.

CREATE DATABASE DBAdmision;

Crear la Base de Datos test de propietario testuser con el tablespace


predeterminado testspace:
2.

CREATE DATABASE test OWNER testuser TABLESPACE testspace;

Crear la Base de Datos musica que soporte el set de caracteres ISO-8859-1:


3.

CREATE DATABASE musica ENCODING 'LATIN1' TEMPLATE template0;

En este ejemplo, la clausula TEMPLATE template0 debera ir nicamente s


el cdigo de template1 no es ISO-8859-1, note que cambiarlo requiere
seleccionar los nuevos LC_COLLATE y LC_CTYPE.
Para el propsito de la prctica:
4.

CREATE DATABASE DBAdmision TEMPLATE template0;

Con la lnea CREATE DATABASE DBAdmision TEMPLATE template0, se crea


una tabla a partir de una plantilla que trae postgres llamada template0, la que nos
crea la base de datos totalmente vaca.

78

--2) CREACIN DE ESQUEMAS (SCHEMAS):


CREATE SCHEMA schema_name [AUTHORIZATION user_name]
[schema_element [ ... ] ]
CREATE SCHEMA AUTHORIZATION user_name [schema_element [ .. ] ]
Los esquemas son importantes para agrupar objetos segn especificaciones, y al
mantener organizado la base de datos permite un mejor desempeo al momento
de la administracin.
Un esquema es esencialmente un NAMESPACE: contiene objetos (tablas, tipos
de datos, funciones y operadores), cuyos nombres pueden estar duplicados en
otros esquemas. Los objetos se acceden por su nombre con el prefijo del
esquema donde residen.
Si no se le asigna un esquema al objeto, postgres lo asignar implcitamente al
esquema public. Para definir que un objeto pertenezca a un esquema se pone el
nombre del esquema seguido por un punto <.> y el nombre del objeto, que puede
ser una tabla, una secuencia, etc
Parmetros de Entrada
Nombre del Esquema. Si se omite, el nombre de usuario se
usa como el nombre del Esquema.
schema_name
El nombre no puede empezar con pg_, porque estn
reservados para esquemas del sistema.
Nombre del usuario propietario del Esquema. Si se omite, el
propietario ser quien ejecute el comando
user_name
Slo los superusuarios pueden crear esquemas de
propiedad para otros usuarios.
Una sentencia de SQL que define un objeto que se crea en
el esquema. Actualmente, slo CREATE TABLE, CREATE
VIEW, CREATE INDEX, CREATE SEQUENCE, CREATE
schema_element
TRIGGER y GRANT se aceptan como clusulas de CREATE
SCHEMA. Otros tipos de objetos pueden ser creados en
comandos separados despus de que se cre el esquema.
Salidas ms usuales
CREATE SCHEMA
Mensaje devuelto si la orden se completa satisfactoriamente.
ERROR: user username is not allowed to create/drop schemas.
Ha de tener el privilegio especial CREATE en la Base de Datos.
Ejemplos:
Crear un esquema:
79

1.

CREATE SCHEMA esquema;

Crear un esquema joe para el usuario joe:


2.

CREATE SCHEMA AUTHORIZATION joe;

Crear el esquema cine que contenga la tabla films y la vista ganadores:


3.
4.
5.
6.

CREATE
CREATE
CREATE
SELECT

SCHEMA cine
TABLE films (titulo text, fecha date, premios text[])
VIEW ganadores AS
titulo, fecha FROM films WHERE premios IS NOT NULL;

Note que los subcomandos individuales no terminan en punto y coma.


La siguiente es una forma equivalente para obtener el mismo resultado:
7.
8.
9.
10.

CREATE
CREATE
CREATE
SELECT

SCHEMA cine;
TABLE films (titulo text, fecha date, premios text[]);
VIEW ganadores AS
titulo, fecha FROM films WHERE premios IS NOT NULL;

Para el propsito de la prctica:


11. CREATE SCHEMA Persona;
12. CREATE SCHEMA Admision;

Con las lneas CREATE SCHEMA Persona y CREATE SCHEMA Admision


separamos la informacin relacionada.

--3) CREACIN DE SECUENCIAS (SEQUENCE):


CREATE [ TEMP ] SEQUENCE name [ INCREMENT increment ]
[ MINVALUE minvalue ] [ MAXVALUE maxvalue ]
[ START start ] [ CACHE cache ] [ CYCLE ]
[ OWNED BY { table_name.column_name | NONE } ]
Crea una nueva secuencia de generador de nmeros. Esto involucra crear e
inicializar una tabla especial de una sola fila con el nombre name. El generador
ser de propiedad del usuario que ejecuta el comando.
La secuencia se crea de forma predeterminada en el esquema actual, de lo
contrario debe precederla el nombre del esquema. Las secuencias temporales no
se deben preceder del nombre de esquema porque se crean en un esquema
especial. El nombre de la secuencia debe ser distinto de otros objetos que residan
en el mismo esquema.
80

Para operar la secuencia se usan las funciones nextval, currval y setval.

TEMP
name
increment

minvalue

maxvalue

start

cache

CYCLE

Parmetros de Entrada
Si se especifica, la secuencia se crea solo para esta sesin y
se elimina al salir.
Nombre de la Secuencia.
Especifica el incremento. Un valor positivo har una
secuencia ascendente, uno negativo har una secuencia
descendente. El valor por omisin es uno (1).
Valor mnimo que una secuencia puede generar. El valor por
omisin es 1 y -2147483647 para secuencias ascendentes y
descendentes, respectivamente.
Valor mximo para una secuencia. Por omisin son
2147483647 y -1 para secuencias ascendentes y
descendentes, respectivamente.
Habilita la secuencia para que comience en cualquier lugar. El
valor de inicio por omisin es minvalue para secuencias
ascendentes y maxvalue para las descendentes.
Permite que los nmeros de la secuencia sean alojados
(preallocated) y almacenados en memoria para un acceso
mas rpido. El valor mnimo es 1 (solo se puede generar un
valor cada vez, i.e. sin cache) y es tambin el valor por
omisin.
Permite a la secuencia continuar cuando el valor de maxvalue
o el de minvalue ha sido alcanzado por una secuencia
ascendente o descendente respectivamente. Si el lmite es
alcanzado, el siguiente numero generado ser cualquiera que
para minvalue o maxvalue sea tomado como apropiado
Salidas ms usuales

CREATE SEQUENCE
Mensaje devuelto si la orden se completa satisfactoriamente.
ERROR: user username is not allowed to create/drop sequences.
Ha de tener el privilegio especial CREATE en la Base de Datos.
Uso:
Crea una secuencia ascendente llamada serial, comenzando en 101:
1. CREATE SEQUENCE serial START 101;

Seleccione el siguiente nmero de esta secuencia


2. SELECT NEXTVAL ('serial');
3. nextval
4. ----81

5. 101

Utilice esta secuencia en una INSERT:


6. ALTER TABLE testtable ADD id int;
7. INSERT INTO testtable VALUES ('BUEN', 'DIA',NEXTVAL('serial'));
8. SELECT * FOM testtable;

En nuestro caso, podemos obviar el paso 3, si definimos el tipo de datos de


secuencia 'SERIAL', en los campos establecidos en la creacin de tablas en el
paso 4, deberan las lneas en cuestin ser de la siguiente forma:
9. IDContacto int default nextval('Persona.seq_idcontacto'),

Cambiar por:
10. IDContacto SERIAL,

Tambin
11. IDModalidad int default nextval('Admision.seq_idmodalidad'),

Cambiar por:
12. IDModalidad SERIAL,

Con estos cambios, no ser necesario realizar el paso 3, pero en realidad postgres
si realiza implcitamente la creacin de secuencias.
Para el propsito de la prctica:
13. CREATE SEQUENCE Persona.seq_idcontacto START 1;
--empieza desde 1
14. CREATE SEQUENCE Admision.seq_idmodalidad START 1; --empieza desde 1

--4) CREACIN DE TABLAS (TABLES):


CREATE [ TEMPORARY | TEMP ] TABLE table (
column type
[ NULL | NOT NULL ] [ UNIQUE ] [ DEFAULT value ]
[column_constraint_clause | PRIMARY KEY } [ ... ] ]
[, ... ]
[, PRIMARY KEY ( column [, ...] ) ]
[, CHECK ( condition ) ]
[, table_constraint_clause ]
) [ INHERITS ( inherited_table [, ...] ) ]

82

CREATE TABLE introducir una nueva clase o tabla en la base de datos actual.
El propietario de la tabla ser del usuario que ejecuta el comando.
Cada type puede ser un tipo simple, un tipo complejo (set) o un tipo array. Cada
atributo puede ser especificado para ser no nulo, y puede tener un valor por
defecto, especificado por la Clusula DEFAULT.
Una tabla no puede tener ms de 1600 campos (realmente, esto viene limitado por
el hecho que el mximo tamao de una tupla debe ser menor que 8192 bytes)
Parmetros de Entrada
Si se especifica, la tabla se crea solo para esta sesin
y es eliminada al salir. Si existen tablas con el mismo
TEMP
nombre, no son visibles mientras exista la tabla
temporal
table
Nombre de la clase o tabla.
El tipo del campo. Puede incluir especificadores de
column
array..
Valor por defecto para el campo:
un literal
una funcin de usuario
DEFAULT value
CURRENT_USER
CURRENT_DATE
CURRENT_TIME
CURRENT_TIMESTAMP
La clusula opcional CONSTRAINT especifica una
lista de restricciones de integridad que las nuevas
inserciones o las actualizaciones debern satisfacer
para que una sentencia insert o update tenga xito.
Cada restriccin debe ser evaluada a una expresin
table_constraint_clause booleana. Se pueden referenciar mltiples campos
con una nica restriccin. Slo se puede definir una
nica clusula PRIMARY KEY por tabla; PRIMARY
KEY column(una restriccin de tabla) and PRIMARY
KEY (una restriccin de campo) son mutuamente
excluyentes.
La clusula opcional INHERITS especifica una
coleccin de nombres de tabla de las cuales esta tabla
hereda todos los campos. Si algn campo heredado
INHERITS
aparece ms de una vez, Postgres informa de un
inherited_table
error. Postgres permite automticamente a la tabla
creada heredar funciones de las tablas superiores a
ella en la jerarqua de herencia.

83

Salidas ms usuales
CREATE TABLE
Mensaje devuelto si la orden se completa satisfactoriamente.
ERROR:
Mensaje devuelto si la creacin de la tabla falla. Este mensaje viene
normalmente acompaado por algn texto explicativo, como:
ERROR: user username is not allowed to create/drop tables.
Ha de tener el privilegio especial CREATE en la Base de Datos.
ERROR: DEFAULT: type mismatched
Si el tipo de datos o el valor por defecto no corresponde al tipo de datos de
la definicin del campo.
Para nuestro caso prctico::
Con FechaCreacion date not null default now(), asignaremos la fecha actual por
defecto al campo FechaCreacion por medio de la funcin now().
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.

create table Persona.Contacto


(
IDContacto int default nextval('Persona.seq_idcontacto'),
Nombres varchar(30) not null,
Paterno varchar(30) not null,
Materno varchar(30) not null,
Genero char(1) default('0') not null,
DNI varchar(10) null,
FechaNac date null,
FechaCreacion date not null default now()
);

12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.

create table Persona.Postulante


(
IDPostulante char(10) not null ,
IDContacto int not null,
IDCarrera char(3) not null,
IDPerAcad char(6) not null,
IDModalidad int not null,
Puntaje int not null default(0),
AsistioExamen char(1) not null default('0'),
Ingreso char(1) not null default('0')
);

23.
24.
25.
26.
27.
28.

Create Table Admision.PerAcad


(
IDPerAcad char(6) not null ,
Periodo char(4),
Ano char(1)
);

29.
30.
31.
32.
33.

create table Admision.Carrera


(
IDCarrera char(3) not null,
Nombre varchar(150) not null
);

84

34.
35.
36.
37.
38.

create table Admision.Modalidad


(
IDModalidad int default nextval('Admision.seq_idmodalidad'),
Modalidad varchar(100) not null
);

--5) CREACIN DE RESTRICCIONES (CHECK):


[ CONSTRAINT name ] CHECK ( condition [, ...] )
La restriccin CHECK especifica una restriccin sobre los valores permitidos en un
Campo y solamente pueden referirse a un campo.

name
condition

Parmetros de Entrada
Nombre de la Restriccin.
Cualquier expresin condicional vlida que se evalu a un
resultado booleano.

Salidas ms usuales
ALTER TABLE
Mensaje devuelto si la orden se completa satisfactoriamente.
ERROR:
Mensaje devuelto si la creacin de la restriccin falla. Este mensaje viene
normalmente acompaado por algn texto explicativo, como:
ERROR: user username is not allowed to create/drop constraints.
Ha de tener el privilegio especial CREATE en la Base de Datos.
ERROR: the constraint check is violated for some row.
Si algunas filas que existen violan la regla que se impone.
Para nuestro caso prctico:
Los valores dentro de CHECK, por ejemplo CHECK (Genero in (0,1)), son los
nicos que sern permitidos insertar en el campo establecido, en este caso se le
asigna esa restriccin al campo Genero.
1. ALTER TABLE Persona.Contacto
2. ADD CONSTRAINT ck_Genero
3. CHECK (Genero in ('0','1'));
4. ALTER TABLE Persona.Postulante
5. ADD CONSTRAINT ck_asistioexamen
6. CHECK (asistioexamen in ('0','1'));
7. ALTER TABLE Persona.Postulante
8. ADD CONSTRAINT ck_ingreso
9. CHECK (ingreso in ('0','1'));

85

10.
11.
12.
13.
14.
15.
16.

ALTER TABLE Persona.Postulante


add CONSTRAINT ck_puntaje
CHECK (
(asistioexamen = '1' and puntaje >=0)
or
(asistioexamen = '0' and puntaje =0)
);

--6) CREACIN DE RESTRICCIONES (UNIQUE):


[ CONSTRAINT name ] UNIQUE ( column [, ...] )
La restriccin UNIQUE especifica una regla que obliga a un grupo de uno o ms
campos de una tabla a contener valores nicos.
Las definiciones de campo de las columnas especificadas no tienen porqu incluir
una restriccin NOT NULL para ser incluidos en una restriccin UNIQUE. Tener
ms de un valor nulo en un campo sin la restriccin NOT NULL, no viola la
restriccin UNIQUE.
Cada restriccin de campo UNIQUE debe nombrar un campo que es distinto del
conjunto de campos nombrados por cualquier otra restriccin UNIQUE o
PRIMARY KEY definidas por la tabla.
Nota: Postgres crea automticamente un ndice nico por cada restriccin
UNIQUE, para asegurar la integridad de los datos.

name
( column [, ...] )

Parmetros de Entrada
Nombre de la Restriccin.
Columnas a las que se aplica la restriccin.

Salidas ms usuales
ALTER TABLE
Mensaje devuelto si la orden se completa satisfactoriamente.
ERROR:
Mensaje devuelto si la creacin de la restriccin falla. Este mensaje viene
normalmente acompaado por algn texto explicativo, como:
ERROR: user username is not allowed to create/drop constraints.
Ha de tener el privilegio especial CREATE en la Base de Datos.
ERROR: the relationship already exists.
Si ya existe la restriccin.
Las restricciones UNIQUE, por ejemplo UNIQUE(Modalidad) , aseguran que en
los datos en la misma columna, en este caso en el campo Modalidad, no sean
repetidas, ya que no puede haber registradas 2 modalidades con el mismo
nombre. Otro ejemplo se da en las tablas usuario, donde no permiten asignar el
mismo login o nick a ms de una persona.
86

1. ALTER TABLE Admision.Carrera


2. ADD CONSTRAINT uq_nombrecarrera
3. UNIQUE(Nombre);
4. ALTER TABLE Persona.Contacto
5. ADD CONSTRAINT uq_ContactoDNI
6. UNIQUE(DNI);
7. ALTER TABLE Admision.Modalidad
8. ADD CONSTRAINT uq_Modalidad
9. UNIQUE(Modalidad);

--7) CREACIN DE CLAVES PRIMARIAS (PRIMARY KEYS):


[ CONSTRAINT name ] PRIMARY KEY ( column [, ...] )
Las claves primarias, aparte de prevenir la duplicidad de datos, evitar los nulo y
servir como nexo para relacionarse con otras tablas, tiene otro fin tambin
importante, que es agilizar el proceso de bsqueda, no por el hecho de ser primary
key, sino que al momento de la creacin de una clave primaria se crea
implcitamente un ndice (index).
Slo se puede especificar una nica clave primaria (PRIMARY KEY) por tabla.

name
( column [, ...] )

Parmetros de Entrada
Nombre de la Restriccin.
Columnas a las que se aplica la restriccin.

Salidas ms usuales
ALTER TABLE
Mensaje devuelto si la orden se completa satisfactoriamente.
ERROR:
Mensaje devuelto si la creacin de la restriccin falla. Este mensaje viene
normalmente acompaado por algn texto explicativo, como:
ERROR: user username is not allowed to create/drop constraints.
Ha de tener el privilegio especial CREATE en la Base de Datos.
ERROR: the relationship already exists.
Si ya existe la restriccin.
Para nuestro caso:
1. ALTER TABLE Admision.PerAcad
2. ADD CONSTRAINT pk_IDPerAcad
3. PRIMARY KEY(IDPerAcad);

87

4. ALTER TABLE Admision.Carrera


5. ADD CONSTRAINT pk_IDCarrera
6. PRIMARY KEY(IDCarrera);
7. ALTER TABLE Persona.Contacto
8. ADD CONSTRAINT pk_IDContacto
9. PRIMARY KEY(IDContacto);
10. ALTER TABLE Persona.Postulante
11. ADD CONSTRAINT pk_IDPostulante
12. PRIMARY KEY(IDPostulante);
13. ALTER TABLE Admision.Modalidad
14. ADD CONSTRAINT pk_IDModalidad
15. PRIMARY KEY(IDModalidad);

--8) CREACIN DE CLAVES FORNEAS (FOREIGN KEYS):


CONSTRAINT fkey_name FOREIGN KEY ( column_name [, ... ] )
REFERENCES reftable [ ( refcolumn [, ... ] ) ] [ MATCH FULL | MATCH
PARTIAL | MATCH SIMPLE ] [ ON DELETE action ] [ ON UPDATE action ]
Una restriccin de clave fornea especifica que valor en una columna (o grupo de
columnas) debe coincidir con los valores en alguna de las filas de otra tabla.
Mantiene la integridad referencial entre dos tablas.
Las claves forneas son campos que servirn de nexo para la relacin entre 2
tablas, la clave primaria de otra tabla se relacionar con la clave fornea de sta.

fkey_name
column_name
reftable
refcolumn
MATCH FULL
MATCH
PARTIAL
MATCH SIMPLE

action

Parmetros de Entrada
Nombre de la Restriccin.
Nombre de la columna afectada por la restriccin.
Tabla de referencia desde la cual se aplica se aplica la
restriccin.
Si se omite, se usa la primary key de reftable
No permite columnas null .
No implementada.
Permite columnas null. Opcin predeterminada.
NO ACTION RESTRICT: Produce un error que indica que
DELETE o UPDATE creara una violacin de restriccin.
CASCADE: Actualiza el valor de la columna referenciada.
SET NULL: Ajusta la columna(s) de referenciad a null.
SET DEFAULT: Ajuste la columna(s) de referencia a sus
valores predeterminados.
88

Salidas ms usuales
ALTER TABLE
Mensaje devuelto si la orden se completa satisfactoriamente.
ERROR:
Mensaje devuelto si la creacin de la restriccin falla. Este mensaje viene
normalmente acompaado por algn texto explicativo, como:
ERROR: user username is not allowed to create/drop constraints.
Ha de tener el privilegio especial CREATE en la Base de Datos.
ERROR: the relationship already exists.
Si ya existe la restriccin.
1.
2.
3.
4.

ALTER TABLE Persona.Postulante


ADD CONSTRAINT fk_IDCarrera
FOREIGN KEY(idcarrera)
references Admision.Carrera(IDCarrera);

5.
6.
7.
8.

ALTER TABLE Persona.Postulante


ADD CONSTRAINT fk_IDPerAcad
FOREIGN KEY(IDPerAcad)
references Admision.PerAcad(IDPerAcad);

9.
10.
11.
12.

ALTER TABLE Persona.Postulante


ADD CONSTRAINT fk_IDModalidad
FOREIGN KEY(IDModalidad)
references Admision.Modalidad(IDModalidad);

13.
14.
15.
16.

ALTER TABLE Persona.Postulante


ADD CONSTRAINT fk_IDContacto
FOREIGN KEY(IDContacto)
references Persona.Contacto(IDContacto);;

El Lenguaje de Definicin de Datos (Data Definition Language -DDL) sirve para


modificar la estructura de los objetos en una base de datos y permite al
administrador de la base especificar los elementos de datos que la integran, su
estructura y las relaciones que existen entre ellos, las reglas de integridad, los
controles a efectuar antes de autorizar el acceso a la base.
En esta parte veremos cmo realizar la eliminacin de los objetos de la base de
datos creada anteriormente, pero con fines prcticos lo haremos paso a paso, ya
que la eliminacin podra ser tan sencilla como eliminar la base de datos
directamente, o los componentes que lo componen en cascada si fuese necesario.

ELIMINACIN DE RESTRICCIONES
ALTER TABLE [ IF EXISTS ] [ ONLY ] name [ * ]
DROP CONSTRAINT [ IF EXISTS ] constraint_name
[ RESTRICT | CASCADE ]
89

Se utiliza para eliminar las restricciones de la tabla y de sus descendientes.


Parmetros de Entrada
name

Nombre de la Tabla.

constraint_name

Nombre de la Restriccin.

IF EXIST

Si se incluye y el objeto no existe, no se produce error.


Altera solo esta tabla. Si no aparece, se altera la tabla y
todas sus descendientes (si las hay).
Explcitamente indica que se incluyen las tablas
descendientes.
Predeterminado - No elimina la restriccin si tiene objetos
dependientes.
Elimina la restriccin y los objetos que dependen de ella.

ONLY
*
RESTRICT
CASCADE

--1) ELIMINACIN DE CLAVES FORNEAS (FOREIGN KEYS):


1. ALTER TABLE Persona.Postulante
2. DROP CONSTRAINT fk_IDCarrera;
3. ALTER TABLE Persona.Postulante
4. DROP CONSTRAINT fk_IDPerAcad;
5. ALTER TABLE Persona.Postulante
6. DROP CONSTRAINT fk_IDModalidad;
7. ALTER TABLE Persona.Postulante
8. DROP CONSTRAINT fk_IDContacto;

--2) ELIMINACIN DE CLAVES PRIMARIAS (PRIMARY KEYS):


1. ALTER TABLE Admision.PerAcad
2. DROP CONSTRAINT pk_IDPerAcad;
3. ALTER TABLE Admision.Carrera
4. DROP CONSTRAINT pk_IDCarrera;
5. ALTER TABLE Persona.Contacto
6. DROP CONSTRAINT pk_IDContacto;
7. ALTER TABLE Persona.Postulante
8. DROP CONSTRAINT pk_IDPostulante;
9. ALTER TABLE Admision.Modalidad
10. DROP CONSTRAINT pk_IDModalidad;

90

--3) ELIMINACIN DE RESTRICCIONES (UNIQUE):


1. ALTER TABLE Admision.Carrera
2. DROP CONSTRAINT uq_nombrecarrera;
3. ALTER TABLE Persona.Contacto
4. DROP CONSTRAINT uq_ContactoDNI;
5. ALTER TABLE Admision.Modalidad
6. DROP CONSTRAINT uq_Modalidad;

--4) ELIMINACIN DE RESTRICCIONES (CHECK):


1. ALTER TABLE Persona.Contacto
2. DROP CONSTRAINT ck_Genero;
3. ALTER TABLE Persona.Postulante
4. DROP CONSTRAINT ck_asistioexamen;
5. ALTER TABLE Persona.Postulante
6. DROP CONSTRAINT ck_ingreso;
7. ALTER TABLE Persona.Postulante
8. DROP CONSTRAINT ck_puntaje;

--5) ELIMINACIN DE COLUMNAS (COLUMNS):


ALTER TABLE [ IF EXISTS ] [ ONLY ] name [ * ]
DROP [ COLUMN ] [ IF EXISTS ] column_name
[ RESTRICT | CASCADE ]
Se utiliza para eliminar las columnas de la tabla y de sus descendientes.
Parmetros de Entrada
name

Nombre de la Tabla.

column_name Nombre de la Columna.


IF EXIST
ONLY
*
RESTRICT
CASCADE

Si se incluye y el objeto no existe, no se produce ningn error.


Altera solo esta tabla. Si no aparece, se altera la tabla y todas
sus descendientes (si las hay).
Explicitamente indica que se incluyen las tablas descendientes.
Predeterminado - No elimina la restriccin si tiene objetos
dependientes.
Elimina la restriccin y todos los objetos que dependen de ella.

91

1. ALTER TABLE Admision.Carrera


2. DROP COLUMN IDCarrera,
3. DROP COLUMN Nombre;

--6) ELIMINACIN DE TABLAS (TABLES):


DROP TABLE [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ]
DROP TABLE elimina tablas de una base de datos. Solo su propietario (owner), el
propietario del esquema o el superusuario pueden destruir una tabla o vista. En
una tabla se pueden eliminar sus filas sin destruirla, usando DELETE o
TRUNCATE.
DROP TABLE siempre remueve algunos ndices, las reglas, los disparadores, y
las restricciones que existan para la tabla. Sin embargo para eliminar una tabla
que es referenciada por una vista o un ndice secundario (foreign-key) de otra
tabla, estas deben ser removidas primero o especificar la clausula CASCADE.
CASCADE remover la vista dependiente enteramente, pero en el caso del ndice
secundario (foreign-key) nicamente remover la restriccin pero no afecta el
contenido de la tabla subyacente.
Parmetros de Entrada
name

Nombre de la Tabla (opcionalmente esquema-tabla).

IF EXIST

Si se incluye y el objeto no existe, no se produce ningn error.


Predeterminado - No elimina la restriccin si tiene objetos
dependientes.
Elimina la restriccin y todos los objetos que dependen de la
tabla.

RESTRICT
CASCADE

Salidas ms usuales
DROPTABLE
Mensaje devuelto si la orden se completa satisfactoriamente.
ERROR:
Mensaje devuelto si la creacin de la restriccin falla. Este mensaje viene
normalmente acompaado por algn texto explicativo, como:
ERROR: user username is not allowed to create/drop constraints.
Ha de tener el privilegio especial CREATE en la Base de Datos.
1.
2.
3.
4.
5.

DROP
DROP
DROP
DROP
DROP

TABLE
table
table
Table
TABLE

Admision.Carrera;
Persona.Contacto;
Persona.Postulante;
Admision.PerAcad;
Admision.Modalidad;

92

--7) ELIMINACIN DE SECUENCIAS (SEQUENCE):


DROP SEQUENCE [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ]
DROP SEQUENCE elimina una secuencia generadora de nmeros de la base de
datos. Una secuencia nicamente puede ser removida por su propio usuario o por
el superusuario.
Parmetros de Entrada
name

Nombre de la Secuencia (opcionalmente esquema-secuencia).

IF EXIST

Si se incluye y el objeto no existe, no se produce ningn error.


Predeterminado - No elimina la secuencia si tiene objetos
dependientes.
Elimina la restriccin y todos los objetos que dependen de la
tabla.

RESTRICT
CASCADE

1. DROP SEQUENCE Persona.seq_idcontacto;


2. DROP SEQUENCE Admision.seq_idmodalidad;

--8) ELIMINACIN DE ESQUEMAS (SCHEMAS):


DROP SCHEMA [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ]
DROP SCHEMA remueve esquemas de la Base de Datos. Un esquema puede ser
eliminado nicamente por su propio usuario o por el superusuario.
Tenga en cuenta que el propietario puede eliminar el esquema (y por lo tanto
todos los objetos que contiene), incluso si l no es el propietario de algunos de los
objetos dentro del esquema.
Parmetros de Entrada
name

Nombre del Esquema.

IF EXIST

Si se incluye y el objeto no existe, no se produce ningn error.


Predeterminado - No elimina la esquema si tiene objetos
dependientes.
Elimina la restriccin y todos los objetos que dependen del
esquema.

RESTRICT
CASCADE

1. DROP SCHEMA Persona;


2. DROP SCHEMA Admision;

93

--9) ELIMINACIN DE BASE DE DATOS (DATABASE):


DROP DATABASE [ IF EXISTS ] name
DROP DATABASE elimina las entradas de catlogo de una base de datos
existente y borra el directorio que contiene los datos. Solamente puede ser
ejecutado por el propietario de la base de datos (normalmente quien la cre).
Esta orden no puede ser ejecutada mientras se est conectado a la base de datos
objetivo. Conctese otra base de datos para ejecutar el comando. Por lo tanto,
puede ser ms conveniente usar el shell script dropdb, que emplea este comando.
Parmetros de Entrada
name

Nombre del Esquema.

IF EXIST

Si se incluye y el objeto no existe, no se produce ningn error.

1. DROP DATABASE DBAdmision;

Como explicaba en un inicio, podramos utilizar mtodos ms directos si queremos


eliminar un objeto, por ejemplo:

ELIMINACION DE OBJETOS:
--1) Eliminar la base de datos con todos sus objetos:
1. DROP DATABASE DBAdmision; --en modo desconectados

--2) Eliminar una secuencia que est siendo utilizada por una tabla:
1. DROP SEQUENCE Persona.seq_idcontacto CASCADE;
2. DROP SEQUENCE Admision.seq_idmodalidad CASCADE;

--3) Eliminar una tabla con todos los constraints que posea:
1.
2.
3.
4.
5.

DROP
DROP
DROP
DROP
DROP

TABLE
Table
TABLE
table
table

Admision.Carrera CASCADE;
Admision.PerAcad CASCADE;
Admision.Modalidad CASCADE;
Persona.Contacto CASCADE;
Persona.Postulante CASCADE;

--4) Eliminar un esquema con todos sus objetos


1. DROP SCHEMA Persona CASCADE;
2. DROP SCHEMA Admision CASCADE;

94

TRUNCATE
TRUNCATE [ TABLA ] name
TRUNCATE remueve rpidamente todas las filas de una tabla. Tiene el mismo
efecto que el DELETE pero al no recorrer la tabla resulta ms rpido. Es ms
efectivo en tablas grandes.

name

Parmetros de Entrada
Nombre de la tabla a truncar.

Salidas ms usuales
TRUNCATE
Mensaje devuelto si la orden se completa satisfactoriamente.
ERROR:
Mensaje devuelto si la orden TRUNCATE falla. Este mensaje viene
normalmente acompaado por algn texto explicativo, como:
ERROR: user username is not allowed to truncate constraints.
Ha de tener el privilegio especial CREATE en la Base de Datos..
Uso:
Truncar la tabla tablagrande:
1. TRUNCATE TABLE tablagrande;

95

Sentencias DML
El lenguaje de Manipulacin de Datos (Data Manipulation Language DML) sirve
para llevar a cabo las transacciones en las base de datos, entindase por
transacciones los procesos de insercin, actualizacin, eliminacin, seleccin.
Es utilizado para escribir programas que crean, actualizan y extraen informacin
de las bases de datos. Siempre de acuerdo con las especificaciones y las
normas de seguridad dictadas por al administrador.
Un lenguaje de manipulacin de datos es un lenguaje que permite a los
usuarios acceder o manipular los datos organizados mediante el modelo de datos
apropiado.
Hay dos tipos bsicamente:
DMLs procedimentales. Requieren que el usuario especifique qu datos se
necesitan y cmo obtener esos datos.
DMLs declarativos (o no procedimentales). Requiere que el
usuario especifique qu datos se necesitan sin especificar cmo obtener
esos datos.
Una consulta es una instruccin de solicitud para recuperar informacin. La parte
de un DML se llama lenguaje de consultas.
Ejemplo:
1. Select nombre, direccion
2. from cliente
3. where id_cliente = 2;

La secuencia conceptual de operaciones que ocurren para acceder cierta


informacin que contiene una base de datos es la siguiente:
El usuario solicita cierta informacin contenida en la base de datos.
El DBMS intercepta este requerimiento y lo interpreta.
El DBMS realiza las operaciones necesarias para acceder
actualizar la informacin solicitada.

y/o

Podemos clasificar a estas sentencias como: INSERT, UPDATE, DELETE,


SELECT.
Usaremos la base de datos DBAdmision estructurado en el post de Sentencias
DDL para realizar las operaciones antes mencionadas.

96

En este ejemplo insertaremos, actualizaremos y eliminaremos datos


de Admision.Modalidad, de la base de datos generada en la parte de Sentencias
DDL.

--1) LISTAR DATOS : SELECT


SELECT [ ALL | DISTINCT [ ON ( expression [, ...] ) ] ]
expression [ AS name ] [, ...]
[ INTO [ TEMPORARY | TEMP ] [ TABLE ] new_table ]
[ FROM table [ alias ] [, ...] ]
[ WHERE condition ]
[ GROUP BY column [, ...] ]
[ HAVING condition [, ...] ]
[ { UNION [ ALL ] | INTERSECT | EXCEPT } select ]
[ ORDER BY column [ ASC | DESC | USING operator ] [, ...] ]
[ FOR UPDATE [ OF class_name [, ...] ] ]
LIMIT { count | ALL } [ { OFFSET | , } start ]

expression

name

TEMPORARY
TEMP

new_table

table
condition
column
select

Parmetros de Entrada
El nombre de una columna de la tabla o una expresin..
Especifica otro nombre para una columna o una expresin que
utilice la clusula AS. Este nombre se utiliza principalmente
como etiqueta para la columna de salida.
El nombre no puede ser utilizado en las clusulas WHERE,
GROUP BY o HAVING. Sin embargo, puede ser referenciado
en clusulas ORDER BY
La tabla se crea solamente para esta sesin, y es
automticamente descartada al finalizar la misma.
Si se utiliza la clusula INTO TABLE, el resultado de la
consulta se almacenar en otra tabla con el nombre indicado.
La tabla objetivo (new_table) ser creada automticamente y
no deber existir previamente a la utilizacin de este comando.
Consulte el comando SELECT INTO para ms informacin.
Nota: La declaracin CREATE TABLE AS tambin crear una
nueva tabla a partir de la consulta.
Un nombre alternativo para la tabla precedente table. Se utiliza
para abreviar o eliminar ambigedades en uniones dentro de
una misma tabla.
Una expresin booleana que da como resultado verdadero o
falso (true or false). Consulte la clusula WHERE.
El nombre de una columna de la tabla.
Una declaracin de seleccin (select) exceptuando la clusula
ORDER BY.

97

Salidas ms usuales
Registros
El conjunto completo de registros (filas) que resultan de la especificacin
de la consulta..
count:
La cantidad de registros (filas) devueltos por la consulta.
SELECT devuelve registros de una o ms tablas. Los candidatos a ser
seleccionados son aquellos registros que cumplen la condicin especificada con
WHERE; si se omite WHERE, se retornan todos los registros. (Consulte Clusula
WHERE.)
DISTINCT elimina registros duplicados del resultado. ALL (predeterminado)
devolver todos los registros, que cumplan con la consulta, incluyendo los
duplicados.
DISTINCT ON elimina los registros que cumplen con todas las expresiones
especificadas, manteniendo solamente el primer registro de cada conjunto de
duplicados. Note que no se puede predecir cul ser "el primer registro" a menos
que se utilice ORDER BY para asegurar que el registro eseado es el que
efectivamente aparece primero. Por ejemplo:
1. SELECT DISTINCT ON (location) location, time, report
2. FROM weatherReports
3. ORDER BY location, time DESC;

recupera el reporte de tiempo (weather report) ms reciente para cada locacin


(location). Pero si no se hubiera utilizado ORDER BY para forzar el orden
descendente de los valores de fecha para cada locacin, se hubiesen recuperado
reportes de una fecha impredecible para cada locacin.
La clusula GROUP BY permite al usuario dividir una tabla conceptualmente en
grupos. (Consulte Clusula GROUP BY.)
La clusula HAVING especifica una tabla con grupos derivada de la eliminacin de
grupos del resultado de la clusula previamente especificada. (Consulte Clusula
HAVING.)
La clusula ORDER BY permite al usuario especificar si quiere los registros
ordenados de manera ascendente o descendente utilizando los operadores de
modo ASC y DESC. (Consulte Clusula ORDER BY.)
El operador UNION permite permite que el resultado sea una coleccin de
registros devueltos por las consultas involucradas. (Consulte Clusula UNION.)
El operador INTERSECT le da los registros comunes a ambas consultas.
(Consulte Clusula INTERSECT.)
98

El operador EXCEPT le da los registros devueltos por la primera consulta que no


se encuentran en la segunda consulta. (Consulte Clusula EXCEPT.)
La clusula FOR UPDATE permite a SELECT realizar un bloqueo exclusivo de los
registros seleccionados.
La clusula LIMIT permite devolver al usuario un subconjunto de los registros
producidos por la consulta. (Consulte Clusula LIMIT.)
Usted debe tener permiso de realizar SELECT sobre una tabla para poder leer sus
valores. (Consulte las declaraciones GRANT/REVOKE).
Clusula WHERE
La condicin opcional WHERE tiene la forma general:
WHERE boolean_expr
boolean_expr puede consistir de cualquier expresin cuyo resultado sea un valor
booleano. En muchos casos, esta expresin ser:
expr cond_op expr
o
log_op expr
donde cond_op puede ser uno de: =, <, <=, >, >= or <>, un operador condicional
como ALL, ANY, IN, LIKE o operador definido localmente, y log_op puede ser uno
de: AND, OR, NOT. La comparacin devuelve TRUE (verdadero) o FALSE (falso)
y todas las instancias sern descartadas si la expresin resulta falsa.
Clusula GROUP BY
GROUP BY especifica una tabla con grupos derivada de la aplicacin de esta
clusula:
GROUP BY column [, ...]
GROUP BY condensar en una sola fila todos aquellos registros que compartan
los mismos valores para las columnas agrupadas. Las funciones de agregacin, si
las hubiera, son computadas a travs de todas las filas que conforman cada
grupo, produciendo un valor separado por cada uno de los grupos (mientras que
sin GROUP BY, una funcin de agregacin produce un solo valor computado a
travs de todas las filas seleccionadas). Cuando GROUP BY est presente, no es
vlido hacer referencia a columnas no agrupadas excepto dentro de funciones de
99

agregacin, ya que habra ms de un posible valor de retorno para una columna


no agrupada.
Clusula HAVING
La condicin opcional HAVING tiene la forma general:
HAVING cond_expr
donde cond_expr cumple las mismas condiciones que las especificadas para
WHERE.
HAVING especifica una tabla con grupos derivada de la eliminacin de grupos, del
resultado de la clusula previamente especificada, que no cumplen con
cond_expr. Cada columna referenciada en cond_expr debe referirse precisamente
(sin ambigedades) a una columna de grupo, a menos que la referencia aparezca
dentro de una funcin de agregacin.
Clusula ORDER BY
ORDER BY column [ ASC | DESC ] [, ...]
column puede ser tanto el nombre de una columna como un nmero ordinal. Los
nmeros ordinales hacen referencia a la posicin (de izquierda a derecha) de la
columna. Esta caracterstica hace posible definir un orden basado en una columna
que no tiene un nombre adecuado. Esto nunca es absolutamente necesario ya
que siempre es posible asignar un nombre a una columna calculada utilizando la
clusula AS, por ej.:
SELECT title, date_prod + 1 AS newlen FROM films ORDER BY newlen;
A partir de la versin 6.4 de PostgreSQL, es tambin posible ordenar, con ORDER
BY, segn expresiones arbitrarias, incluyendo campos que no aparecen en el
resultado de SELECT. Por lo tanto, la siguiente declaracin es legal:
SELECT name FROM distributors ORDER BY code;
Opcionalmente una puede agregar la palabra clave DESC (descendente) o ASC
(ascendente) luego del nombre de cada columna en la clusula ORDER BY. Si no
se especifica, se asume ASC de forma predeterminada. Alternativamente, puede
indicarse un nombre de operador de orden especfico. ASC es equivalente a
USING < y DESC es equivalente a USING >.
Clusula UNION
table_query UNION [ ALL ] table_query
[ ORDER BY column [ ASC | DESC ] [, ...] ]
100

donde table_query especifica cualquier declaracin SELECT sin la clusula


ORDER BY.
El operador UNION permite que el resultado sea una coleccin de registros
devueltos por las consultas involucradas. Los dos SELECTs que representan los
dos operandos directos de la UNION deben producir el mismo nmero de
columnas, y las columnas correspondientes deben ser de tipos de datos
compatibles.
De forma predeterminada, el resultado de UNION no contiene registros duplicados
a menos que se especifique la clusula ALL. Si se utilizan varios operadores
UNION en la misma declaracin SELECT se evalan de izquierda a derecha. Note
que la palabra clave ALL no es global, siendo aplicada solamente al par de tablas
de resultado actual.
Clusula EXCEPT
table_query EXCEPT table_query
[ ORDER BY column [ ASC | DESC ] [, ...] ]
donde table_query especifica cualquier expresin SELECT sin la clusula ORDER
BY.
El operador EXCEPT le da los registros devueltos por la primera consulta pero no
por la segunda. Los dos SELECTs que representan los operandos directos de la
interseccin deben producir el mismo nmero de columnas, y las columnas
correspondientes deben ser de tipos de datos compatibles.
Si se utilizan varios operadores INTERSECT en la misma declaracin SELECT se
evalan de izquierda a derecha, a menos que se utilicen parntesis para modificar
esto.
Clusula LIMIT
LIMIT { count | ALL } [ { OFFSET | , } start ] OFFSET start
donde count especifica el mximo nmero de registros a devolver y start
especifica el nmero de registros a saltear antes de empezar a devolver registros.
LIMIT le permite recuperar slo una porcin de los registros que se generan por el
resto de la consulta. Si se especifica un nmero lmite, no se devolvern ms
registros que esa cantidad. Si se da un valor de desplazamiento, esa cantidad de
registros ser salteada antes de comenzar a devolver registros.
Cuando se utiliza LIMIT es una buena idea utilizar la clusula ORDER BY para
colocar los registros del resultado en un orden nico. De otra forma obtendr un
subconjunto impredecible de los registros de la consulta tal vez est buscando
101

los registros del dcimo al vigsimo, pero del dcimo al vigsimo en qu orden?
Usted no conoce el orden a menos que utilice ORDER BY.
Ya en Postgres 7.0, el optimizador de consultas toma en cuenta a LIMIT cuando
genera un plan de consulta, as que es muy factible que usted obtenga diferentes
planes (abarcando diferentes criterios de ordenamiento de registros) dependiendo
de los valores dados a LIMIT y OFFSET. Por lo tanto, utilizar diferentes valores
para LIMIT/OFFSET para seleccionar diferentes subconjuntos del resultado de
una consulta, provocar resultados inconsistentes a menos que usted se asegura
un resultado predecible ordenando con ORDER BY. Esto no es un bug; es una
consecuencia inherente al hecho de que SQL no establece ningn compromiso de
entregar los resultados de una consulta en un orden en particular a menos que se
utilice ORDER BY para especificar un criterio de orden explcitamente.
Uso
Para unir la tabla films con la tabla distributors:
1. SELECT f.title, f.did, d.name, f.date_prod, f.kind
2. FROM distributors d, films f
3. WHERE f.did = d.did

Para sumar la columna len (duracin) de todos los filmes y agrupar los resultados
segn la columna kind (tipo):
1. SELECT kind, SUM(len) AS total FROM films GROUP BY kind;

Para sumar la columna len de todos los filmes, agrupar los resultados segn la
columna kind y mostrar los totales de esos grupos que sean menores a 5 horas:
1.
2.
3.
4.

SELECT kind, SUM(len) AS total


FROM films
GROUP BY kind
HAVING SUM(len) < INTERVAL '5 hour';

Los siguientes dos ejemplos muestran maneras idnticas de ordenar los


resultados individuales de acuerdo con los contenidos de la segunda columna
(name):
1. SELECT * FROM distributors ORDER BY name;
2. SELECT * FROM distributors ORDER BY 2;

Este ejemplo muestra cmo obtener la unin de las tablas distributors y actors,
restringiendo los resultados a aquellos que comienzan con la letra W en cada
tabla. No se quieren duplicados, as que la palabra clave ALL se omite.
1. - distributors: actors:
2. - did|
name id
|name
3. - ---+--------------+--------------102

4.
5.
6.
7.

108|Westward 1
|Woody Allen
111|Walt Disney 2 |Warren Beatty
112|Warner Bros. 3|Walter Matthau
... ...

Muestra el contenido de Admision.Modalidad:


1. SELECT IDModalidad, Modalidad FROM Admision.Modalidad;

--2) INSERTAR DATOS: INSERT


INSERT INTO table_name [ ( column_name [, ...] ) ] { DEFAULT VALUES |
VALUES ( { expression | DEFAULT } [, ...] ) [, ...] | query }
[RETURNING * | output_expression [ [AS] output_name ] [, ..] ]
INSERT permite la insercin de nuevas filas en una clase o una tabla. Se puede
insertar una fila a la vez o varias como el resultado de una consulta. Las columnas
en el resultado pueden ser listadas en cualquier orden.
Cada columna que no est presente en la lista de origen ser insertada usando el
valor por defecto, que puede ser tanto un valor por defecto declarado DEFAULT o
bien NULL. Postgres rechazar la nueva columna si se inserta un NULL en una
columna declarada como NOT NULL.
Si la expresin para cada columna no es del tipo de datos correcto, se intentar
una correccin de tipos automticamente.
Debe tener privilegios de insercin en la tabla para aadir en ella, as como
privilegios de seleccin en cualquier tabla especificadas en una clausula WHERE.
La clusula INSERT se usa para calcular y devolver el valor (s) en funcin de cada
fila insertada en realidad. Esto es principalmente til para la obtencin de los
valores que fueron suministrados por defecto, como por ejemplo un nmero de
secuencia en serie. Sin embargo, se permite cualquier expresin mediante
columnas de la tabla. La sintaxis de la lista RETURNING es idntica a la de la lista
de salida de SELECT.
Debe tener el privilegio INSERT en una tabla con el fin de insertar en ella. Si se
especifica una lista de columnas, slo tiene privilegio INSERT en las columnas de
la lista. El uso de la clusula RETURNING requiere permiso SELECT en todas las
columnas mencionadas en RETURNING. Si utiliza la clusula de consulta para
insertar filas de una consulta, por supuesto, necesita tener privilegio SELECT
todas las tablas o columna que se utiliza en la consulta.
Parmetros de Entrada
table_name

El nombre de una la tabla.


103

column_name

El nombre de una columna en table_name.


Una expresin o un valor vlidos a asignar en
expression
column_name.
Una consulta vlida. Vea la instruccin SELECT para una
query
mejor descripcin de argumentos vlidos.
DEFAULT
Todas las columnas sern llenadas con sus valores
VALUES
predeterminados.
Una expresin que se calcula y devuelve el comando
INSERT despus de cada fila. La expresin puede usar los
output_expression nombres de las columnas de la tabla nombrada por
table_name. Escriba * para devolver todas las columnas de
la fila insertada (s).
output_name
Un nombre a usar para una columna retornada.
Salidas ms usuales
INSERT oid 1
Si solo se ha insertado una fila. oid es el nmero OID de la fila insertada.
INSERT 0 #
Si se ha insertado ms de una fila. # es el nmero de filas insertadas.
Si el comando INSERT tiene RETURNING el resultado ser similar a la
sentencia SELECT que contenga las columnas y valores definidos en la lista
RETURNING, calculadas sobre la fila (s) que se inserta por el comando.
Uso
Inserta una fila en la tabla films:
1. INSERT INTO films VALUES
2. ('UA502','Bananas',105,'1971-07-13','Comedy',INTERVAL '82 minute');

En este segundo ejemplo la columna date_prod se omite y entonces tendr el


valor por defecto de NULL:
1. INSERT INTO films (code, title, did, date_prod, kind)
2. VALUES ('T_601','Yojimbo',106,DATE '1961-06-16','Drama');

Inserta varias filas en la tabla films desde la tabla tmp:


1. INSERT INTO films SELECT * FROM tmp;

INSERTAR DATOS EN Admision.Modalidad


1. INSERT INTO Admision.Modalidad(Modalidad)VALUES('Exmen Ordinario');
2. --El campo IDModalidad es secuencial
3. SELECT * FROM Admision.Modalidad; --Comprobar Insercin

104

--3) ACTUALIZAR DATOS: UPDATE


UPDATE [ ONLY ] table_name [ * ] [ [ AS ] alias ]
SET { column_name = { expression | DEFAULT } |
( column_name [, ...] ) = ( { expression | DEFAULT } [, ...] ) } [, ...]
[ FROM from_list ]
[ WHERE condition]
[ RETURNING * | output_expression [ [ AS ] output_name ] [, ...] ]
UPDATE cambia el valor de la columnas especificadas por todas las filas que
satisfacen la condicin dada. Solamente necesita indicar las columnas que sern
modificadas.
Para referencias a listas se usa la misma sintaxis de SELECT. O sea, puede
substituir un nico elemento de una lista, un rango de elementos o una lista
completa con una nica peticin.
Debe tener permiso de escribir en la tabla para poder modificarla, as como
permiso de lectura de cualquier tabla cuyos valores sean mencionados en la
condicin WHERE.
Si la expresin para cada columna no es del tipo de datos correcto, se intentar
una correccin de tipos automticamente.
La clusula UPDATE se usa para calcular y devolver el valor (s) en funcin de
cada fila actualizada en realidad. Esto es principalmente til para la obtencin de
los valores que fueron suministrados por defecto, como por ejemplo un nmero de
secuencia en serie. Sin embargo, se permite cualquier expresin mediante
columnas de la tabla. La sintaxis de la lista RETURNING es idntica a la de la lista
de salida de SELECT.
Debe tener el privilegio UPDATE en una tabla con el fin de insertar en ella. Si se
especifica una lista de columnas, slo tiene privilegio UPDATE en las columnas de
la lista. El uso de la clusula RETURNING requiere permiso SELECT en todas las
columnas mencionadas en RETURNING. Si utiliza la clusula de consulta para
insertar filas de una consulta, por supuesto, necesita tener privilegio SELECT
todas las tablas o columna que se utiliza en la consulta.
Parmetros de Entrada
table_name

El nombre de una la tabla.

column_name

El nombre de una columna en table_name.

expression

Una expresin o un valor vlidos a asignar en column_name.


Es una extensin no estndar de Postgres que permite la
aparicin de columnas de otras tablas en la condicin
WHERE.

from_lista

105

La columnas ser llenada con su valore predeterminado (sera


NULL si no se especifica).
Una expresin que se calcula y devuelve el comando
IUPDATE despus de cada fila actualizada. La expresin
output_expression puede usar los nombres de las columnas de la tabla nombrada
por table_name. Escriba * para devolver todas las columnas
de la fila actualizadas (s).
output_name
Un nombre a usar para una columna retornada.
DEFAULT

Salidas ms usuales
UPDATE #
Mensaje obtenido si ha habido xito. El smbolo # representa el nmero de
filas que han sido actualizadas. Si # es igual a 0, ninguna fila fue actualizada.
Si el comando UPDATE tiene RETURNING el resultado ser similar a la sentencia
SELECT que contenga las columnas y valores definidos en la lista RETURNING,
calculadas sobre la fila (s) que se inserta por el comando.
Uso:
Para cambiar la palabra "Drama" por "Dramatica" en la columna categora:
1.
2.
3.
4.
5.

UPDATE peliculas 355


SET categoria = 'Dramatica'
WHERE categoria = 'Drama ';
SELECT * FROM peliculas WHERE categoria = 'Dramatico' OR categoria = 'Drama';

ACTUALIZAR DATOS EN Admision.Modalidad:


1. UPDATE Admision.Modalidad SET Modalidad='Ordinario'
2. WHERE IDModalidad='1';
3.
4. SELECT * FROM Admision.Modalidad; --Comprobar Actualizacin

--4) ELIMINAR DATOS: DELETE


DELETE FROM [ ONLY ] table_name [ * ] [ [ AS ] alias ]
[ USING using_list ]
[ WHERE condition]
[ RETURNING * | output_expression [ [ AS ] output_name ] [, ...] ]
DELETE borra las filas que satisfacen la clausula WHERE de la tabla
especificada. Si la condicin (clausula WHERE) est ausente, el efecto es borrar
todas las filas de la tabla. El resultado es una tabla valida, pero vaca.

106

Sugerencia: TRUNCATE es una extensin de Postgres el cual provee un


mecanismo ms rpido para borrar todas las filas de una tabla.
Para modificar la tabla usted debe poseer acceso de escritura a la misma, as
como acceso de lectura a cualquier tabla cuyos valores son ledos en la condicin.
La clusula DELETE se usa para calcular y devolver el valor (s) en funcin de
cada fila eliminada. Esto es principalmente til para la obtencin de los valores
que fueron suministrados por defecto, como por ejemplo un nmero de secuencia
en serie. Sin embargo, se permite cualquier expresin mediante columnas de la
tabla. La sintaxis de la lista RETURNING es idntica a la de la lista de salida de
SELECT.
Debe tener el privilegio DELETE en una tabla con el fin de eliminar en ella. Si se
especifica una lista de columnas, El uso de la clusula RETURNING requiere
permiso SELECT en todas las columnas mencionadas en RETURNING. Si utiliza
la clusula de consulta para eliminar filas de una consulta, por supuesto, necesita
tener privilegio SELECT todas las tablas o columna que se utiliza en la consulta.
Parmetros de Entrada
table_name

El nombre de una la tabla.

alias

Un nombre sustituto para la tabla.


Una lista de expresiones de tabla, permitiendo columnas de
otras tablas que aparecer en la condicin WHERE. Esto es
using_list
similar a la lista de tablas que se pueden especificar en la
clusula FROM de una sentencia SELECT, por ejemplo, un
alias para el nombre de la tabla se pueden especificar
Consulta SQL de seleccin la cual devuelve las filas a ser
condition
borradas.
Una expresin que se calcula y devuelve el comando DELETE
despus de cada fila borrada. La expresin puede usar los
output_expression nombres de las columnas de la tabla nombrada por
table_name. Escriba * para devolver todas las columnas de la
filas borradas (s).
output_name
Nombre para la columna retornada.
Salidas ms usuales
DELETE count
Mensaje devuelto si los items son borrados exitosamente. El valor count es la
cantidad de filas borradas.
Si count es 0, ninguna fila fue borrada.
Si el comando DELETE tiene RETURNING el resultado ser similar a la sentencia
SELECT que contenga las columnas y valores definidos en la lista RETURNING,
calculadas sobre la fila (s) que se inserta por el comando.
107

Uso:
Borra todos los films excepto los musicales:
1. DELETE FROM films WHERE kind <> 'Musical';
2. SELECT * FROM films;

Borra completamente la tabla films:


1. DELETE FROM films;
2. SELECT * FROM films;

ELIMINAR DATOS EN Admision.Modalidad:


1. DELETE FROM Admision.Modalidad
2. WHERE IDModalidad='1';
3.
4. SELECT * FROM Admision.Modalidad; --Comprobar Eliminacin

108

Sentencias TCL
El Lenguaje de Control Transacciones (Transaction Control Language - TCL) se
utiliza para administrar los procesos transaccionales en una base de datos en
relacin a los requerimientos de atomicidad, consistencia, aislamiento y
durabilidad.
Las clusulas TCL que se utilizan en PostgreSQL para este fin son: COMMIT,
SAVEPOINT, RELEASE SAVEPOINT, ROLLBACK.

COMMIT
COMMIT [ WORK | TRANSACTION ]
COMMIT realiza la transaccin actual. Todos los cambios realizados por la
transaccin son visibles a las otras transacciones, y se garantiza que se
conservan si se produce una cada de la mquina.
Notas:
Las palabras clave WORK y TRANSACTION son informativas, y pueden ser
omitidas.
Use ROLLBACK para abortar una transaccin.
Uso:
COMMIT;

-- Para hacer todos los cambios permanentes.

SAVEPOINT
SAVEPOINT savepoint
SAVEPOINT establece un nuevo punto de salvaguarda dentro de la transaccin
actual.
Un punto de salvaguarda es una marca especial dentro de una transaccin que
permite a todos los comandos que se ejecutan despus revertirse, restaurando el
estado de la transaccin a lo que era en el momento que se estableci el punto de
salvaguarda.
Notas
Utilice ROLLBACK TO SAVEPOINT para revertir a un punto de salvaguarda.
Utilice RELEASE SAVEPOINT para destruir un punto de salvaguarda.

109

Los puntos de salvaguarda slo se pueden establecer al interior de un bloque


de transacciones. Puede haber varios puntos de salvaguarda definidos
dentro de un bloque transacciones.
Ejemplo:
Establecer un punto de salvaguarda y luego deshacer los efectos de todos los
comandos ejecutados despus de su creacin. La transaccin siguiente inserta los
valores 1 y 3, pero no el 2:
BEGIN;
INSERT INTO table1 VALUES (1);
SAVEPOINT mi_savepoint;
INSERT INTO table1 VALUES (2);
ROLLBACK TO SAVEPOINT mi_savepoint;
INSERT INTO table1 VALUES (3);
COMMIT;

RELEASE SAVEPOINT
RELEASE [ SAVEPOINT ] savepoint
RELEASE SAVEPOINT destruye todos los puntos de salvaguarda (savepoints)
que se establecieron en el intervalo de creacin y liberacin, manteniendo el
efecto de los comandos ejecutados en este intervalo.

La destruccin de un punto de salvaguarda hace que no aparezca como un punto


de reversin y permite que el sistema recoja los recursos que le asigno antes de
finalizar la transaccin.
Notas:
Usar el nombre de un punto de salvaguarda (savepoint) que no se ha creado

genera un error.
No es posible liberar un punto de retorno cuando la transaccin se ha revertido.
Si varios puntos de salvaguarda tienen el mismo nombre, slo el que se ha definido
ms recientemente se libera.

Ejemplo:
Establecer y posteriormente destruir un punto de salvaguarda. La transaccin
siguiente inserta los valores 4 y 5:

110

BEGIN;
INSERT INTO table1 VALUES (4);
SAVEPOINT mi_savepoint;
INSERT INTO table1 VALUES (5);
RELEASE SAVEPOINT mi_savepoint;
COMMIT;

ROLLBACK
ROLLBACK [ WORK | TRANSACTION ] [ TO SAVEPOINT savepoint ]
ROLLBACK deshace la transaccin actual y provoca que todas las modificaciones
originadas por la misma sean descartadas.
ROLLBACK TO SAVEPOINT Deshace todas las transacciones que se han
ejecutado despus del establecimiento del punto de salvaguarda (savepoint). El
punto de retorno permanece y si se necesita, ms adelante se puede revertir de
nuevo.
ROLLBACK TO SAVEPOINT destruye implcitamente a todos los puntos de
salvaguarda que se establecieron despus de que el punto utilizado.
Notas:

Utilice COMMIT para terminar una transaccin de forma exitosa.


ABORT es un sinnimo de ROLLBACK.
Utilice RELEASE SAVEPOINT para destruir un punto de salvaguarda.
Cualquier cursor que se abre dentro de un punto de salvaguarda se cerrar
cuando se revierte. Si un cursor abierto previamente se ve afectado por una
sentencia FETCH o MOVE dentro de un punto de salvaguarda que luego se
revierte, el cursor permanece en la posicin que FETCH dej apuntando (es
decir, el movimiento del cursor causado por FETCH no se deshace). La
transaccin puede ser restaurada usando ROLLBACK TO SAVEPOINT pero
el cursor ya no se puede utilizar.

Uso:
ROLLBACK; -- Cancelar todos los cambios.
ROLLBACK TO SAVEPOINT my_savepoint; -- Cancela los cambios
posteriores a my_savepoint

111

CASO PRCTICO:
Transaccin para transferir 50 desde una cuenta A a una cuenta B:
1- CREACIN DE TABLA Y CHECK:
1.
2.
3.
4.
5.
6.

--DROP TABLE tblCuenta;


CREATE TABLE tblCuenta(NumCuenta char,Monto numeric(10,3));
INSERT INTO tblCuenta VALUES('A',100);
INSERT INTO tblCuenta VALUES('B',100);
ALTER TABLE tblCuenta
ADD CONSTRAINT ck_monto CHECK (Monto >=0); --No Negativos

2- SECUENCIA DE EJECUCIN:
1. leer(A)
2. A = A - 50
3. escribir(A)
4. leer(B)
5. B = B + 50
6. escribir(B)
3- CREACIN DE LA FUNCIN:
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.

CREATE OR REPLACE FUNCTION transaccion1() RETURNS VOID AS


$body$
DECLARE
A numeric;
B numeric;
BEGIN
/*1*/ A := (SELECT monto from tblCuenta where NumCuenta = 'A');
/*2*/ A := A - 50;
/*3*/ update tblCuenta set Monto = A where NumCuenta = 'A';
/*4*/ B := (SELECT monto from tblCuenta where NumCuenta = 'B');
/*5*/ B := B + 50;
/*6*/ update tblCuenta set Monto = B where NumCuenta = 'B';
RAISE NOTICE 'Guardado';
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
END;
$body$
LANGUAGE 'plpgsql';

4- COMPROBANDO:
1. SELECT * FROM transaccion1();
2. SELECT * FROM tblCuenta;

EL hecho de transferir dinero de una cuenta a otra requiere que toda la operacin
sea ejecutado como un todo, HACE TODO O NADA, de esa manera

112

garantizamos la integridad de la transaccin, por ejemplo si se presenta un error


en medio de la transferencia todo el procesos queda invalidado.
Queda claro que Postgres realiza las transacciones implcitamente
Es importante nombrar los 4 requisitos que deben de cumplirse en una
transferencia:
Requisito de atomicidad: Se realiza todo o nada
Requisito de consistencia: A+B (INICIAL) = A+B (FINAL)
Requisito de aislamiento: Durante la operacin se bloquea otros accesos.
Requisito de durabilidad: Una vez actualizado debe quedar permanentemente.

113

Instalar Script
Instalar Script dbadmin_insert.sql desde pgAdminIII en
Windows
Si an no tienes preparada la base de datos, utilizar el script dbadmin_insert.sql
que es la unin de las sentencias DDL y DML creadas y poblada con datos. El
script crear el entorno en el que se realizarn las demostraciones.
Copiar el archivo dbadmin_insert.sql al directorio del usuario en Mis
documentos.
Ejecutar pgAdminIII.
Crear la Base de Datos desde el cono Database:

Seleccionar el cono dbadmision creado en Databases.


Abrir las consultas SQL.
Abrir el archivo dbadmin_insert.sql desde directorio del usuario Mis
documentos.
114

Ejecutar el Script

115

Instalar el Script dbadmin.sql desde psql en Linux


Si an no tienes preparada la base de datos, utilizar el script dbadmin.sql que es la
unin de las sentencias DDL y DML creadas y poblada con datos. El script crear
el entorno en el que se realizarn las demostraciones.
Copiar el archivo dbadmin.sql, por facilidad, al directorio del usuario postgres
/var/lib/pgsql/9.2
Crear la Base de Datos:
1.
2.
8.
3.
4.
5.
6.
7.

[root@servidor ~]# su postgres


-bash-4.1$ psql
(9.2.6, server 8.4.11)
Type "help" for help.
postgres=# CREATE DATABASE dbadmision WITH TEMPLATE = template0 ENCODING = 'UTF8';
CREATE DATABASE
postgres=#

Asignar el propietario a la Base de Datos


8. postgres=# ALTER DATABASE dbadmision OWNER TO postgres;
9. ALTER DATABASE
10. postgres=# \q

Ejecutar el script dbadmin.sql en psql desde El Shell del usurio postgres


11. -bash-4.1$

psql -U postgres -d dbadmision

-f dbadmin.sql

116

Caso de Estudio - Continuacin


Despus de los estudios realizados sobre las necesidades de la oficina de
Admisin de la Universidad y una vez se ha construido la base de datos
dbadmision con todos sus objetos y las relaciones entre estos.
Las oficinas que trabajan con esta base de datos son:
Oficina

Admisin

Marketing

Empleado

Inicio de
Sesin

Cecilia Caldern

Ccaldero
n

Patito

Jefe

Carmen Peralta

Cperalta

Perrito

Jefe

Yovana Vargas

Yvargas

Muchachita

Operador

Liz Castro

Lcastro

Michimichi

Operador

Katty Suarez

Ksuarez

Loquita

Jefe

Martha Carrion

Mcarrion

Love

Operador

Contrasea

Tipo de
Usuario

Se tiene desarrollada una aplicacin que acceda a la base de datos con el usuario
y contrasea concedidos a cada uno de los usuarios (Autenticacin SQL). Con
respecto a la aplicacin la oficina de Admisin est solicitando que se implemente:

Un reporte que dado un determinado periodo acadmico (IDPerAcad] liste:


apellidos y nombres, carrera y modalidad de todos los postulantes de ese
periodo.
Un reporte que dada un determinado periodo acadmico (IDPerAcad) liste:
apellidos y nombres, carrera y modalidad de todos los ingresantes de ese
periodo.
Un reporte que dada un determinado periodo acadmico (IDPerAcad) liste:
apellidos y nombres, carrera y modalidad de todos los postulantes que no
asistieron al examen de ese periodo.
Los 10 mejores puestos por periodo (IDPerAcad).
As mismo los de la oficina de Marketing necesitan que se implemente lo siguiente:

Un reporte que muestre la cantidad de postulantes por cada periodo


(IDPerAcad)
Un reporte que muestre la cantidad de postulantes por cada periodo
(IDPerAcad), este reporte debe de mostrar las columnas: Periodo, varn,
mujer y total.
Un reporte que liste los apellidos y Nombres de todos aquellos que cumplan
aos, este reporte debe de funcionar en funcin a la fecha actual.
Listado de aquellos contactos que nunca ingresaron.
117

Los usuarios operadores de la oficina de Admisin solo pueden:

Seleccionar, Actualizar e Insertar Contactos y Postulante.


De los postulantes solo pueden tener acceso de seleccin en los campos
Puntaje, AsistioExamen e Ingreso.
Acceso a los requerimientos previamente solicitados.
Los Usuarios jefes de la oficina de Admisin pueden:

Seleccionar y Eliminar Postulantes.


Actualizar los campos Puntaje, AsistioExamen e Ingreso de los postulantes.
Seleccionar Contactos
Seleccionar, Insertar, Eliminar y Actualizar Carreras, Modalidades y Periodos.
Acceso a los requerimientos previamente solicitados.

Los usuarios operadores y jefes de Marketing:

Acceso a los requerimientos recientemente solicitados.

Tenga en cuenta que en cualquier momento el jefe u operadores de las oficinas


pueden cambiar, as que las soluciones planteadas deben de ser lo ms flexible
posible.

118

Sentencias DCL
El Lenguaje de Control de Datos (Data Control Language DCL) es utilizado
para llevar a cabo la administracin de privilegios en los objetos de la base de
datos el cual ayuda a garantizar la accesibilidad y seguridad dentro de los objetos
de la base de datos.
Las clusulas DCL que se usan para el control de accesos en PostgreSQL son:
GRANT, REVOKE.

GRANT
GRANT privilegio [, ...] ON objeto [, ...]
TO { PUBLIC | GROUP grupo | usuario }
GRANT permite al creador de un objeto asignarle permisos especficos a todos los
usuarios (PUBLIC), a un cierto usuario o grupo. Usuarios distintos al creador
pueden no tener permisos de acceso a menos que el creador se los conceda, una
vez que el objeto ha sido creado.
Una vez que un usuario tiene privilegios sobre un objeto, tiene la posibilidad de
ejecutar ese privilegio. No hay necesidad de conceder privilegios al creador de un
objeto; el creador obtiene automticamente TODOS los privilegios, y puede
tambin eliminar el objeto.
Parmetros de Entrada
SELECT Acceder a todas las columnas de una tabla o vista.
INSERT
privilegio

Insertar datos en todas las columnas de una tabla.

UPDATE Actualizar todas las columnas de tabla.


DELETE Eliminar filas de una tabla
RULE

Definir reglas en una tabla o vista.

usuario

ALL
Otorgar todos los privilegios.
El nombre de un objeto al que se quiere conceder el acceso. Los
posibles objetos son: tabla, vista, secuencia, ndice.
El nombre de un grupo al cual se otorga privilegios. El grupo debe
haber sido creado explcitamente.
El nombre de un usuario al que se quiere conceder privilegios.

PUBLIC

Una abreviacin para representar a todos los usuarios.

objeto
grupo

Salidas ms usuales

119

CHANGE
Mensaje devuelto si la orden se completa satisfactoriamente.
ERROR: ChangeAcl: class "object" not found
Mensaje que se devuelve si el objeto no est disponible o si es imposible
dar los privilegios al grupo o a los usuarios.
Uso:
Concede privilegios de insercin a todos los usuarios de la tabla testtable:
GRANT INSERT ON testtable TO PUBLIC;
Concede todos los privilegios al usuario testuser sobre la vista clases:
GRANT ALL ON clases TO testuser;
Consulte el comando psql \z para obtener ms informacin sobre permisos en
objetos existentes:
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.

-bash-4.1$ psql U testuser d test


test=# \z
Privilegios
Esquema|
Nombre
|
Tipo
| Privileg |Privilegios de acceso a columnas
-------+--------------------+-----------+----------+--------------------------Public | amigos
| tabla
|
|
Public | clientes
| tabla
|
|
public | clientes_id_seq
| secuencia|
|
public | cuentas
| tabla
|
|
public | cuentas_id_seq
| secuencia|
|
public | invitaciones
| tabla
|
|
public | invitaciones_id_seq| secuencia|
|
public | testtable
| tabla
|
|
public | usuarios
| tabla
|
|
public | usuarios_id_seq
| secuencia|
|
(10 filas)

REVOKE
REVOKE privilegio [, ...]
ON objeto [, ...]
FROM { PUBLIC | GROUP grupo | usuario }
REVOKE permite al creador de un objeto revocar permisos asignados anteriormente a todos los usuarios (mediante PUBLIC), a un usuario o a un grupo.
Parmetros de Entrada
privilegio SELECT Acceder a todas las columnas de una tabla o vista.

120

INSERT

Insertar datos en todas las columnas de una tabla.

UPDATE Actualizar todas las columnas de tabla.


DELETE Borrar filas de una tabla
RULE

Definir reglas en una tabla o vista.

grupo

ALL
Rescindir todos los privilegios.
El nombre de un objeto sobre el que revocar el acceso. Los posibles
objetos son: tabla, vista, secuencia, ndice.
El nombre de un grupo al cual se revocan privilegios.

usuario

El nombre de un usuario al cual se revocan privilegios.

PUBLIC

Rescinde el/los privilegio(s) especificados(s) a todos los usuarios.

objeto

Salidas ms usuales
CHANGE
Mensaje devuelto si la orden se completa satisfactoriamente.
ERROR:
Mensaje que se devuelve si el objeto no est disponible o si es imposible
revocarprivilegios al grupo o a los usuarios.
Uso:
Revoca el privilegio de insercin a todos los usuarios de la tabla testtable:
REVOKE INSERT ON testtable TO PUBLIC;
Revoca todos los privilegios al usuario testuser sobre la vista clases:
REVOKE ALL ON clases TO testuser;
Usamos la base de datos dbadmision y nos enfocamos en un caso real de
implementacin para asignar los privilegios en los objetos para garantizar la
accesibilidad y seguridad del sistema para una Universidad usando las sentencias
GRANT y REVOKE de acuerdo a los requerimientos establecidos en la seccin
anterior.
SUGERENCIA:
Si has utilizado la base de datos dbadmision en ejercicios previos es mejor volver
a crearla.
Utilizar el Script: dbadmin.sql

121

DESARROLLO
PARTE 1: CREACIN DE ROLES Y USUARIOS DE LOGIN
CREANDO ROLES
1.
2.
3.
4.

CREATE
CREATE
CREATE
CREATE

ROLE
ROLE
ROLE
ROLE

JefeADM;
OpeADM;
JefeMKT;
OpeMKT;

CREANDO LOGINS
1.
2.
3.
4.

CREATE ROLE Ccalderon


WITH LOGIN PASSWORD 'Patito'
VALID UNTIL '2012-01-01'
IN ROLE JefeADM;

5.
6.
7.
8.

CREATE ROLE Cperalta


WITH LOGIN PASSWORD 'Perrito'
VALID UNTIL '2012-01-01'
IN ROLE JefeADM;

9.
10.
11.
12.

CREATE ROLE Yvargas


WITH LOGIN PASSWORD 'Muchachita'
VALID UNTIL '2012-01-01'
IN ROLE OpeADM;

13.
14.
15.
16.

CREATE ROLE Lcastro


WITH LOGIN PASSWORD 'Michimichi'
VALID UNTIL '2012-01-01'
IN ROLE OpeADM;

17.
18.
19.
20.

CREATE ROLE Ksuarez


WITH LOGIN PASSWORD 'Loquita'
VALID UNTIL '2012-01-01'
IN ROLE JefeMKT;

21.
22.
23.
24.

CREATE ROLE Mcarrion


WITH LOGIN PASSWORD 'Love'
VALID UNTIL '2012-01-01'
IN ROLE OpeMKT;

PARTE 2: CREACIN DE REQUERIMIENTOS


CREANDO ESQUEMAS
1. CREATE SCHEMA REQ_ADM;
2. CREATE SCHEMA REQ_MKT;

122

CREANDO FUNCIONES REQUERIDAS


Las siguientes funciones fueron creadas segn los requerimientos realizados en el
escenario mostrado inicialmente de las oficinas de Admision (ADM) y Marketing
(MKT), que sern almacenados en los esquemas anteriormente definidos para
organizarlo adecuadamente y tambin para facilitar la asignacin de permisos por
esquemas.
PARTE 3: ASIGNACIN DE DERECHOS
(A LOS OPERADORES DE ADM)
(Derecho 1) : Seleccionar, Actualiza e Insertar Contactos y Postulantes
1. GRANT SELECT ON Persona.Contacto TO OpeADM;
2. GRANT INSERT ON Persona.Contacto TO OpeADM;
3. GRANT UPDATE ON Persona.Contacto TO OpeADM;
4. GRANT SELECT ON Persona.Postulante TO OpeADM;
5. GRANT INSERT ON Persona.Postulante TO OpeADM;
6. GRANT UPDATE ON Persona.Postulante TO OpeADM;
7. GRANT USAGE ON SCHEMA Persona TO OpeADM;

(Derecho 2) : De los postulantes solo debe tener acceso de seleccion sobre


Puntaje, AsistioExamen e Ingreso
1. REVOKE SELECT ON Persona.Postulante FROM OpeADM; --Quitamos permiso de SELECT
sobre Postulante
2. GRANT SELECT (AsistioExamen) ON Persona.Postulante TO OpeADM;
3. GRANT SELECT (Ingreso) ON Persona.Postulante TO OpeADM;

(Derecho 3) : Acceso a los requerimientos previamente solicitados


1. GRANT USAGE ON SCHEMA REQ_ADM TO OpeADM;

(A LOS JEFES DE ADM)


(Derecho 1) : Seleccionar y Eliminar Postulantes.
1. GRANT SELECT ON Persona.Postulante TO JefeADM;
2. GRANT DELETE ON Persona.Postulante TO JefeADM;
3. GRANT USAGE ON SCHEMA Persona TO JefeADM;

(Derecho 2) : Actualizar los campos Puntaje, AsistioExamen e Ingreso de


Postulante
1. GRANT UPDATE (Puntaje) ON Persona.Postulante TO JefeADM;
2. GRANT UPDATE (AsistioExamen) ON Persona.Postulante TO JefeADM;

123

3. GRANT UPDATE (Ingreso) ON Persona.Postulante TO JefeADM;

(Derecho 3) : Seleccionar Contactos


1. GRANT SELECT ON Persona.Contacto to JefeADM;

(Derecho 4) : Seleccionar, Insertar, Eliminar y Actuzalizar Carreras, Modalidades


y Periodos
1. GRANT SELECT,INSERT,DELETE, UPDATE ON Admision.Carrera TO JefeADM;
2. GRANT SELECT,INSERT,DELETE, UPDATE ON Admision.Modalidad TO JefeADM;
3. GRANT SELECT,INSERT,DELETE, UPDATE ON Admision.PerAcad TO JefeADM;
4. GRANT USAGE ON SCHEMA Admision to JefeADM;

(Derecho 5) : Acceso a los requerimientos previamente solicitados


1. GRANT USAGE ON SCHEMA REQ_ADM TO JefeADM;

(A LOS JEFES Y OPERADORES DE mkt)


1. GRANT USAGE ON SCHEMA REQ_MKT TO JefeMkt,OpeMKt;

PARTE 4: VERIFICACIN DE DERECHOS ASIGNADOS


La siguiente parte es verificar que los permisos hayan sido otorgados
correctamente, tambin es posible ir verificando estos a medida se vayan
asignando los privilegios.

VERIFICANDO USUARIO ACTUAL


1. SELECT SESSION_USER, CURRENT_USER;

COMPROBANDO DERECHOS
(DE LOS OPERADORES DE ADM)
1. SET SESSION AUTHORIZATION OpeADM;

(Derecho 1) : Seleccionar, Actualiza e Insertar Contactos y Postulantes


1. SELECT * FROM Persona.Contacto;
2.
3.
4.
5.

INSERT INTO Persona.Contacto VALUES(


176
,'Anonymous'
,'Anonymous'

124

6.
7.
8.
9.
10.

,'Anonymous'
,0
,00000000
,'10/11/2000'
,now());

11.
12.
13.
14.
15.

UPDATE Persona.Contacto SET


nombres='Anonimo'
,paterno='Anonimo'
,materno='Anonimo'
WHERE IDCOntacto='176';

16. DELETE FROM Persona.Contacto WHERE IDCOntacto='176';


17. --El rol OpeADM no tiene permiso para eliminar.

(Derecho 2) De los postulantes solo debe tener acceso de seleccin sobre


Puntaje, AsistioExamen e Ingreso
1. SELECT IDPostulante,IDContacto,IDCarrera,IDModalidad
2. FROM Persona.Postulante;
3. SELECT Puntaje,AsistioExamen,Ingreso FROM Persona.Postulante;

(Derecho 3) : Acceso a los requerimientos previamente solicitados


1.
2.
3.
4.

SELECT
SELECT
SELECT
SELECT

*
*
*
*

FROM
FROM
FROM
FROM

REQ_ADM.pa_r1()
REQ_ADM.pa_r2()
REQ_ADM.pa_r3()
REQ_ADM.pa_r4()

AS
AS
AS
AS

(column1
(column1
(column1
(column1

unknown);
unknown);
unknown);
unknown);

(DE LOS JEFES DE ADM)


1. SET SESSION AUTHORIZATION JefeADM;

(Derecho 1) : Seleccionar y Eliminar Postulantes.


1. SELECT * FROM Persona.Postulante;
2. DELETE FROM Persona.Postulante WHERE IDContacto='175';

(Derecho 2) : Actualizar los campos Puntaje, AsistioExamen e Ingreso de


Postulante
1. UPDATE Persona.Postulante SET
2. Puntaje=20, AsistioExamen='1', Ingreso='1' WHERE IDContacto='174';
3. UPDATE Persona.Postulante SET IDModalidad='0';--No tiene persmiso

(Derecho 3) : Seleccionar Contactos


1. SELECT * FROM Persona.Contacto;

125

(Derecho 4) : Seleccionar, Insertar, Eliminar y Actualizar Carreras, Modalidades y


Periodos
1. SELECT * FROM Admision.Carrera;
2. SELECT * FROM Admision.Modalidad;
3. SELECT * FROM Admision.PerAcad;

(Derecho 5) : Acceso a los requerimientos previamente solicitados


1.
2.
3.
4.

SELECT
SELECT
SELECT
SELECT

*
*
*
*

FROM
FROM
FROM
FROM

REQ_ADM.pa_r1()
REQ_ADM.pa_r2()
REQ_ADM.pa_r3()
REQ_ADM.pa_r4()

AS
AS
AS
AS

(column1
(column1
(column1
(column1

unknown);
unknown);
unknown);
unknown);

(DE LOS JEFES DE MKT)


1. SET SESSION AUTHORIZATION OpeMKT;

(Derecho 1) : Acceso a los requerimientos previamente solicitados


1.
2.
3.
4.

SELECT
SELECT
SELECT
SELECT

*
*
*
*

FROM
FROM
FROM
FROM

REQ_MKT.pa_r1()
REQ_MKT.pa_r2()
REQ_MKT.pa_r3()
REQ_MKT.pa_r4()

AS
AS
AS
AS

(column1
(column1
(column1
(column1

unknown);
unknown);
unknown);
unknown);

(DE LOS OPERADORES DE MKT)


1. SET SESSION AUTHORIZATION JefeMKT;

(Derecho 1) : Acceso a los requerimientos previamente solicitados


1.
2.
3.
4.

SELECT
SELECT
SELECT
SELECT

*
*
*
*

FROM
FROM
FROM
FROM

REQ_MKT.pa_r1()
REQ_MKT.pa_r2()
REQ_MKT.pa_r3()
REQ_MKT.pa_r4()

AS
AS
AS
AS

(column1
(column1
(column1
(column1

unknown);
unknown);
unknown);
unknown);

Es importante sealar que las verificaciones se han realizado nicamente por


medio de roles de grupo, lo ideal y correcto ser realizar las operaciones como
usuarios (roles de login) por ejemplo:
5. SET SESSION AUTHORIZATION OpeADM;

cambiarlo por:
6. SET SESSION AUTHORIZATION Yvargas;

El resultado deber ser el mismo ya que Yvargas pertenece al grupo OpeADM.

126

PARTE 5: REESTABLECIMIENTO Y/O ELIMINACIN DE OBJETOS


Si queremos eliminar algunos objetos o incluso la base de datos no debe existir
ningn rol asociado a ste
1. RESET SESSION AUTHORIZATION;
2. --Regresamos al usuario principal por defecto.
3. SELECT SESSION_USER, CURRENT_USER;
4. DROP DATABASE dbadmision;
5. --ERROR: database "dbadmision" is being accessed by other users
6. REVOKE ALL ON SCHEMA REQ_MKT,REQ_ADM,Persona,Admision
7. FROM JefeADM,OpeADM,JefeMKT,OpeMKT;
8.
9.
10.
11.
12.
13.

REVOKE ALL ON TABLE Persona.Contacto


,Persona.Postulante
,Admision.Carrera
,Admision.PerAcad
,Admision.Modalidad
FROM JefeADM,OpeADM,JefeMKT,OpeMKT;

14. DROP USER CCalderon,CPeralta,Yvargas,LCastro,Ksuarez,Mcarrion;


15. DROP ROLE JefeADM,OpeADM,JefeMKT,OpeMKT;
16. DROP DATABASE dbadmision;

Para la eliminacin de la base de datos habr que confirmar adems de que no


exista ninguna conexin abierta de la base de datos por algn usuario.
17. SELECT * FROM pg_stat_activity;

127

Sentencias XML
La tecnologa XML nos ha facilitado constantemente en lograr compatibilidad entre
diversos formatos y permitir compartirlos entre distintas aplicaciones y sin duda en
bases de datos su funcionalidad tambin es muy til.
Veremos el uso del tipo de dato XML, el uso de las funciones XML y la exportacin
de consultas hacia XML con PostgreSQL.
El esquema que habr que respetar en el entorno de bases de datos, y en el caso
especfico de postgres es el siguiente:
1. <catalogname>
2.
<schemaname>
3.
<tablename>
4.
<row>
5.
<colname1>value</colname1>
6.
<colname2 xsi:nil=true/>
7.
...
8.
</row>
9.
...
10.
</tablename>
11.
...
12. </schemaname>
13. ...
14. </catalogname>

No voy a entrar al detalle de lo que es XML, tampoco de todas las funciones


habidas y por haber sobre el, sin embargo desarrollaremos una parte importante
que nos sacar de apuros en algn momento o situacin. Algunas de las
funciones brindadas por postgres sobre XML que usaremos son:

XMLCOMMENT
XMLCONCAT
XMLELEMENT
XMLFOREST
XMLAGG
QUERY_TO_XML
TABLE_TO_XML

Para comprender la funcionalidad de cada uno de ellos, usamos la base de datos


dbadmision y nos enfocamos en un caso real de ejecucin usando las sentencias
anteriores.
SUGERENCIA:
Si has utilizado la base de datos dbadmision en ejercicios previos es mejor volver
a crearla.
Utilizar el Script: dbadmin.sql
128

1- Comprobando algunas funciones XML:


1. SELECT xmlelement(name Contacto, IDContacto)
2. FROM Persona.Contacto;
3. SELECT xmlelement(name Paterno, Paterno),xmlelement(name Materno, Materno)
4. FROM Persona.Contacto;
5. SELECT xmlforest(Paterno, Materno)
6. FROM Persona.Contacto;
7. SELECT xmlelement(name Contacto, xmlforest(Paterno, Materno))
8. FROM Persona.Contacto;
9. SELECT XMLAgg(XMLForest(Paterno, Materno))
10. FROM Persona.Contacto;
11. SELECT XMLElement(name Contacto, XMLAgg(XMLForest(Paterno, Materno)))
12. FROM Persona.Contacto;

2- Creamos una secuencia para usarla como numeracin de la estructura


resultante:
1.
2.
3.
4.
5.
6.

--DROP SEQUENCE seq_contacto;


CREATE TEMP SEQUENCE seq_contacto;
SELECT xmlelement(name Contacto
,xmlattributes(nextval('seq_contacto') AS "row")
,xmlforest(Paterno, Materno) )
FROM Persona.Contacto;

7. SELECT xmlelement(name Contacto, xmlforest(Paterno, Materno, Nombres) )


8. FROM Persona.Contacto;
9.
10.
11.
12.
13.
14.
15.
16.

SELECT xmlelement(name Persona


,xmlelement(name Contacto
,xmlattributes(IDContacto)
,Paterno
,Materno
,Nombres)
)
FROM Persona.Contacto;

3- Usando xmlcomment para comentar sobre XML


1.
2.
3.
4.

SELECT xmlelement(name Persona


,xmlcomment('Comentario')
,xmlforest(Paterno, Materno,Nombres))
FROM Persona.Contacto;

5. SELECT xmlelement(name Paterno, Materno)


6. ,xmlelement(name Materno, Materno)
7. FROM Persona.Contacto;

129

8. SELECT xmlconcat(xmlelement(name Paterno, Materno)


9. ,xmlelement(name Nombres, Nombres))
10. FROM Persona.Contacto;
11. SELECT xmlelement(name Contacto, xmlconcat( xmlelement(name Paterno, Paterno)
12. ,xmlelement(name Materbo, Materno)))
13. FROM Persona.Contacto;

4- Creamos una tabla que contenga un campo de tipo XML, veremos luego
una manera especial de manipularlas.
1.
2.
3.
4.
5.
6.

--DROP TABLE Persona.ContactoXML;


CREATE TABLE Persona.ContactoXML (col1 XML);
INSERT INTO Persona.ContactoXML(SELECT xmlelement(name Contacto
,xmlconcat( xmlelement(name Paterno, Paterno)
,xmlelement(name Materno, Materno) ) )
FROM Persona.Contacto);

7. SELECT col1 FROM Persona.ContactoXML;

5- XPATH nos facilitar en la seleccion de campos dentro de una estructura


de datos XML:
1. SELECT xpath('/contacto/materno/text()', col1)
2. FROM Persona.ContactoXML ;
3. SELECT xpath('/contacto/paterno/text()', col1)
4. FROM Persona.ContactoXML ;
5. SELECT columna[1]
6. FROM ( SELECT xpath('/contacto/materno/text()', col1) AS columna
7. FROM Persona.ContactoXML ) AS xmlsource;

6- En estas dos ltimas funciones, su poder radica en que puede generar


una completa estructura XML a nivel de consulta o de una tabla completa:
1. SELECT query_to_xml('SELECT Nombres,Paterno,Materno FROM Persona.Contacto'
2. ,FALSE,FALSE,'Contactos')
3. SELECT table_to_xml('Persona.Contacto',FALSE,FALSE,'Contactos')

Recursos Utilizados:
SQLXML-For-Postgres-Developers
XML Document Support
XML and Databases
XML Type

130

PL/pgSQL
Introduccin
Ya hemos visto que SQL (DML) es un lenguaje simple y poderoso para manipular
datos en una base de datos. PL/pgSQL es un lenguaje procedimental que permite
crear funciones, procedimientos y triggers con el fin de realizar operaciones y
computaciones ms complejas dentro de la base de datos. Realizar dichas
operaciones dentro de la base de datos, y no en las aplicaciones, puede mejorar el
rendimiento del sistema puesto que se disminuye la comunicacin entre la
aplicacin y el SGBD.

Antes de iniciar
Para los ejemplos descritos en este taller se requieren las siguientes tablas y
datos:
CREATE TABLE CLIENTES (ID SERIAL PRIMARY KEY,
CC VARCHAR(10) NOT NULL,
NOMBRE VARCHAR(50) NOT NULL);
CREATE TABLE CUENTAS (ID SERIAL PRIMARY KEY,
SALDO REAL DEFAULT 0,
CLI_ID INT NOT NULL REFERENCES CLIENTES(ID),
FECHA_SOBREGIRO DATE,
INTERESES REAL DEFAULT 0);
INSERT
INSERT
INSERT
INSERT
INSERT
INSERT

INTO
INTO
INTO
INTO
INTO
INTO

CLIENTES (CC,NOMBRE) VALUES ('11111','CLIENTE 1');


CLIENTES (CC,NOMBRE) VALUES ('22222','CLIENTE 2');
CLIENTES (CC,NOMBRE) VALUES ('33333','CLIENTE 3');
CUENTAS (SALDO, CLI_ID) VALUES ( 5000,1);
CUENTAS (SALDO, CLI_ID) VALUES ( -2000,2);
CUENTAS (SALDO, CLI_ID) VALUES ( 3000,3);

Estructura
La estructura general de un bloque PL/PgSQL es la siguiente:
[ <<label>> ]
[ DECLARE
declarations ]
BEGIN
statements
END [ label ];

131

Utilizacin mediante SELECT


Por ejemplo, la siguiente funcin retorna su argumento multiplicado por 3:
/* Funcin que multiplica su argumento por 3 */
CREATE OR REPLACE FUNCTION MULT_3(x int)
returns INT as $$
begin
RETURN x*3;
end; $$
LANGUAGE plpgsql;

La funcin puede ser utilizada en una clusula SELECT:


select mult_3(4);
mult_3
-------12
(1 row)

DECLARE:
Las variables, en caso de ser necesarias, deben ser declaradas en la clusula
DECLARE:
/* Concatenando el nombre y el apellido y adicionando mayusculas */
CREATE OR REPLACE FUNCTION CONCAT_NOMBRE(NOMBRE VARCHAR, APELLIDO VARCHAR)
RETURNS VARCHAR AS $$
DECLARE
TEMP VARCHAR;
BEGIN
TEMP:= NOMBRE || ' ' || APELLIDO;
RETURN INITCAP(TEMP);
END;
$$
LANGUAGE plpgsql;

Un ejemplo de uso:
select concat_nombre('carlos','olarte');
concat_nombre
--------------Carlos Olarte

Insertar Datos en una Tabla


Esta funcin inserta un registro en la tabla CLIENTES:
CREATE FUNCTION INS_CLIENTES(VARCHAR, VARCHAR)

132

RETURNS VOID AS $$
INSERT INTO CLIENTES (CC,NOMBRE) VALUES ($1,$2);
$$
LANGUAGE SQL;

Un ejemplo de uso:
SELECT INS_CLIENTES('44444','CLIENTE 4');

Note que en este caso, los argumentos de la funcin no tienen nombre y se


refieren a ellos como $1 y $2 dentro del cuerpo de la funcin. Adems, como
solo lanzamos sentencias SQL, el lenguaje de la funcin es SQL.

Actualizar Datos en una Tabla (Transferir Dinero entre dos


Cuentas)
/* Funcin que transfiere dinero de una cuenta a otra */
CREATE FUNCTION TRANSFER
(CTA1 CUENTAS.ID%TYPE , CTA2 CUENTAS.ID%TYPE , MONTO CUENTAS.SALDO%TYPE)
RETURNS CUENTAS.SALDO%TYPE AS $$
DECLARE
NUEVO_SALDO CUENTAS.SALDO%TYPE;
BEGIN
UPDATE CUENTAS SET SALDO = SALDO - MONTO WHERE ID=CTA1;
UPDATE CUENTAS SET SALDO = SALDO + MONTO WHERE ID=CTA2;
SELECT SALDO INTO NUEVO_SALDO FROM CUENTAS WHERE ID=CTA2;
RETURN NUEVO_SALDO;
END
$$
LANGUAGE PLPGSQL;

Ejemplo de uso:
postgres=# select transfer(3,2,1000);
transfer
----------1000
(1 row)

En este ejemplo hemos introducido algunas caractersticas interesantes del


lenguaje:
Los tipos de las variables se pueden declarar de acuerdo con los tipos de
datos en las tablas como en CTA1 CUENTAS.ID%TYPE (es decir, CT1 es
una variable del tipo del campo ID en la tablas CUENTAS).
Hemos lanzado sentencias del DML como parte del procedimiento (UPDATE)
Utilizamos SELECT INTO VAR. Cuando un SELECT retorna una UNICA
fila, esta se puede almacenar en una variable local.

133

Es posible realizar algunas validaciones. Por ejemplo, se debe verificar que las
dos cuentas existan y que el monto de la segunda sea suficiente para realizar la
transferencia.
/* Funcin que transfiere dinero de una cuenta a otra */
/* Versin2: Validacion de los datos de entrada */
CREATE FUNCTION TRANSFER2
(CTA1 CUENTAS.ID%TYPE, CTA2 CUENTAS.ID%TYPE, MONTO CUENTAS.SALDO%TYPE)
RETURNS CUENTAS.SALDO%TYPE AS $$
DECLARE
NUEVO_SALDO CUENTAS.SALDO%TYPE;
SALDO_DISPONIBLE CUENTAS.SALDO%TYPE;
TEST_EXISTS INT;
BEGIN
SELECT COUNT(*) INTO TEST_EXISTS FROM CUENTAS WHERE ID=CTA1;
IF TEST_EXISTS <> 1 THEN
RAISE EXCEPTION 'La cuenta de origen % no existe', CTA1;
ELSE
SELECT COUNT(*) INTO TEST_EXISTS FROM CUENTAS WHERE ID=CTA2;
IF TEST_EXISTS <> 1 THEN
RAISE EXCEPTION 'La cuenta destino % no existe', CTA2;
ELSE
SELECT SALDO INTO SALDO_DISPONIBLE FROM CUENTAS WHERE ID = CTA1;
IF SALDO_DISPONIBLE < MONTO THEN
RAISE EXCEPTION 'No hay fondos suficientes para la transferencia';
ELSE
/* realizando la transferencia */
UPDATE CUENTAS SET SALDO = SALDO - MONTO WHERE ID=CTA1;
UPDATE CUENTAS SET SALDO = SALDO + MONTO WHERE ID=CTA2;
/* Consultando y retornando el nuevo saldo de CTA2 */
SELECT SALDO INTO NUEVO_SALDO FROM CUENTAS WHERE ID=CTA2;
RETURN NUEVO_SALDO;
END IF;
END IF;
END IF;
END
$$
LANGUAGE PLPGSQL;

Ejemplo (Actualizando los intereses)


Antes de presentar el ejemplo, vamos a adicionar algunas filas a la tabla
cuentas:
INSERT INTO CUENTAS (SALDO,CLI_ID, FECHA_SOBREGIRO) VALUES (-3000,3,'2010-01-01'),
(-7000,2,'2010-03-01');

La siguiente funcin actualiza los intereses de mora en las cuentas que estn
sobregiradas. Los intereses que se cobran son proporcionales al saldo de la
cuenta y se utiliza el porcentaje que se pasa como parmetro.
/*
Actualizando los intereses de las cuentas de acuerdo con el numero de dias en mora
*/
134

CREATE FUNCTION COBRAR_INTERESES(PORCENTAJE REAL) RETURNS VOID AS $$


BEGIN
UPDATE CUENTAS
SET INTERESES = SALDO * PORCENTAJE *
EXTRACT('DAYS'FROM ( NOW()-FECHA_SOBREGIRO))
WHERE FECHA_SOBREGIRO IS NOT NULL;
END;
$$ LANGUAGE plpgsql;

Ejemplo de uso:
bdi00=> SELECT COBRAR_INTERESES(0.01);

Utilizando Row Types


Utilizando %ROWTYPE es posible declarar RECORDS del mismo tipo de una
tabla. En el siguiente ejemplo, se crean RECORDS del tipo de las tablas
CUENTAS y CLIENTES. La funcin simplemente imprime informacin
relacionada con la cuenta que se pasa como parmetro.
/* Retornando el nombre del cliente y el saldo de una cuenta */
CREATE FUNCTION INF_CUENTA(NUMCUENTA INT) RETURNS VARCHAR AS $$
DECLARE
RESULTADO VARCHAR;
cta_row CUENTAS%ROWTYPE; --cta_row es del mismo tipo de la tabla CUENTAS
cli_row CLIENTES%ROWTYPE;
BEGIN
-- Puede utilizar SELECT .. INTO cuando el resultado trae una sola fila
SELECT * INTO CTA_ROW FROM CUENTAS WHERE ID = NUMCUENTA;
IF NOT FOUND THEN
RAISE EXCEPTION 'La cuenta % no existe. ', NUMCUENTA;
ELSE
SELECT * INTO CLI_ROW FROM CLIENTES WHERE ID = CTA_ROW.CLI_ID;
RESULTADO := ' La cuenta pertenece a ' || CLI_ROW.Nombre ||
'. El saldo es ' || CTA_ROW.SALDO;
RETURN RESULTADO;
END IF;
END;
$$ LANGUAGE plpgsql;

Ejemplo de uso:
bdi00=> Select INF_CUENTA(1);
inf_cuenta
---------------------------------------------------La cuenta pertenece a CLIENTE 1. El saldo es 5000
(1 row)

Note el uso de IF NOT FOUND THEN para verificar si el SELECT trajo o no


algn resultado. Obviamente la funcin anterior se hubiera podido escribir de

135

manera mucho ms simple ejecutando una nica consulta que traiga la


informacin del cliente y de la cuenta:
CREATE FUNCTION INF_CUENTA2(NUMCUENTA INT) RETURNS VARCHAR AS $$
DECLARE
SALDO_CTA CUENTAS.SALDO%TYPE;
NOMBRE_CLI VARCHAR;
BEGIN
SELECT CLI.NOMBRE, CTA.SALDO INTO NOMBRE_CLI,SALDO_CTA FROM CUENTAS CTA
INNER JOIN CLIENTES CLI ON (CLI.ID = CTA.CLI_ID)
WHERE ID = NUMCUENTA;
IF NOT FOUND THEN
RAISE EXCEPTION 'La cuenta % no existe. ', NUMCUENTA;
ELSE
RETURN ' La cuenta pertenece a ' || NOMBRE_CLI ||
'. El saldo es ' || SALDO_CTA;
RETURN RESULTADO;
END IF;
END;
$$ LANGUAGE plpgsql;

En este caso, note que la clusula SELECT INTO puede asignar varias
variables al tiempo.

Cursores
Un cursor es una estructura que permite recuperar los datos de una consulta fila
por fila.
Asuma una tabla con una serie de transacciones bancarias pendientes, i.e.,
transacciones que deben ser realizadas y afectar las cuentas de los clientes:
CREATE TABLE PENDIENTES (
ID SERIAL PRIMARY KEY,
MONTO REAL NOT NULL,
CTA_ID INT NOT NULL REFERENCES CUENTAS(ID),
FECHA DATE DEFAULT NOW(),
OPERACION CHAR(1),
REALIZADA BOOL DEFAULT FALSE);
INSERT INTO PENDIENTES (MONTO,CTA_ID,OPERACION)
(300,1,'D'), (400,2,'R'), (233,3,'D');

VALUES

El siguiente procedimiento recorre la tabla pendientes y realiza la operacin


indicada en la tabla CUENTAS.
CREATE OR REPLACE FUNCTION UPD_PENDIENTES() RETURNS VOID AS $$
DECLARE
-- Declaracin del Cursor
-- Note la forma del Select ... FOR UPDATE!
CUR_PEN CURSOR FOR SELECT * FROM PENDIENTES WHERE REALIZADA=FALSE FOR UPDATE;
ACCION PENDIENTES%ROWTYPE;
BEGIN
-- Abrir el cursor

136

OPEN CUR_PEN;
LOOP
-- Extraer una fila del cursor
FETCH CUR_PEN INTO ACCION;
IF ACCION IS NULL THEN EXIT;
END IF;
IF ACCION.OPERACION = 'D' THEN
UPDATE CUENTAS SET SALDO = SALDO + ACCION.MONTO WHERE ID = ACCION.CTA_ID;
ELSE
UPDATE CUENTAS SET SALDO = SALDO - ACCION.MONTO WHERE ID = ACCION.CTA_ID;
END IF;
-- Actualizar una fila de acuerdo con la posicin del cursor
UPDATE PENDIENTES SET REALIZADA=TRUE WHERE CURRENT OF CUR_PEN;
END LOOP;
-- Cierre del cursor.
CLOSE CUR_PEN;
END;
$$ LANGUAGE plpgsql;

La clusula FOR UPDATE evita que otras transacciones estn modificando las
filas seleccionadas.
Ejemplo de uso:
bdi00=> select * from CUENTAS;
id | saldo | cli_id | fecha_sobregiro | intereses
----+-------+--------+-----------------+----------1 | 5000 |
1 |
|
0
2 | -2000 |
2 |
|
0
3 | 3000 |
3 |
|
0
(3 rows)
bdi00=> select * from PENDIENTES;
id | monto | cta_id |
fecha
| operacion | realizada
----+-------+--------+------------+-----------+----------1 |
300 |
1 | 2010-04-26 | D
| f
2 |
400 |
2 | 2010-04-26 | R
| f
3 |
233 |
3 | 2010-04-26 | D
| f
(3 rows)
bdi00=> SELECT UPD_PENDIENTES();
upd_pendientes
---------------(1 row)
bdi00=> select * from CUENTAS;
id | saldo | cli_id | fecha_sobregiro | intereses
----+-------+--------+-----------------+----------1 | 5300 |
1 |
|
0
2 | -2400 |
2 |
|
0
3 | 3233 |
3 |
|
0
bdi00=> select * from PENDIENTES;
id | monto | cta_id |
fecha
| operacion | realizada
----+-------+--------+------------+-----------+----------1 |
300 |
1 | 2010-04-26 | D
| t
2 |
400 |
2 | 2010-04-26 | R
| t
3 |
233 |
3 | 2010-04-26 | D
| t

137

(3 rows)

Cursores Implicitos con FOR <VAR> IN <QUERY>


Otra forma de recorrer las tablas es utilizar cursores implcitamente usando
FOR <VAR> IN <QUERY>. Por ejemplo, asuma que se tiene una tabla con la
lista de usuarios que han efectuado mal uso de sus cuentas y deben ser
desactivadas:
CREATE TABLE USUARIOS_FRAUDE(ID SERIAL, CLI_ID INT);
INSERT INTO USUARIOS_FRAUDE (CLI_ID) VALUES (1), (3);

Ahora adicionamos un atributo en cuenta para saber si est activa o no:


ALTER TABLE CUENTAS ADD INACTIVA BOOL DEFAULT FALSE;

La siguiente funcin inhabilita las cuentas cuyo usuario se encuentra en la tabla


de USUARIOS_FRAUDE
CREATE OR REPLACE FUNCTION INACTIVA () RETURNS VOID AS $$
DECLARE
USR USUARIOS_FRAUDE%ROWTYPE;
BEGIN
FOR USR IN SELECT * FROM USUARIOS_FRAUDE LOOP
UPDATE CUENTAS SET INACTIVA = TRUE WHERE CLI_ID = USR.CLI_ID;
END LOOP;
END;
$$ LANGUAGE plpgsql;

Para este caso particular, un lector atento hubiera podido descubrir que el
ejercicio se poda realizar con una sola sentencia del DML:
UPDATE CUENTAS SET INACTIVA = FALSE WHERE CLI_ID IN (SELECT CLI_ID FROM
USUARIOS_FRAUDE);

Triggers
Un trigger es una accin que se lanza cuando se inserta, elimina o actualiza
una o varios registros de una tabla. En PL/pgSQL, los triggers son funciones sin
argumentos en las cuales se crean las siguientes variables:
NEW: Es un Record con los datos del registro que se est insertando
(actualizando).
OLD: Datos del registro que se est eliminando (o actualizando).
TG_OP: Operacin que se est realizando, puede ser INSERT, UPDATE,
DELETE, o TRUNCATE.
138

Un ejemplo de Auditoria
Suponga que cada que se modifica una cuenta, se debe registrar la accin en la
siguiente tabla:
CREATE TABLE AUDITORIA(
OPERACION CHAR(1),
FECHAUPD TIMESTAMP,
USUARIO TEXT,
ID INT,
SALDO REAL,
CLI_ID INT,
FECHA_SOBREGIRO DATE,
INTERESES REAL,
INACTIVA BOOL);

La siguiente funcin deja un rastro en la tabla AUDITORIA cada que se realiza


una modificacin en la tabla CUENTAS:
CREATE OR REPLACE FUNCTION process_cue_audit() RETURNS TRIGGER AS $$
BEGIN
IF (TG_OP = 'DELETE') THEN
INSERT INTO AUDITORIA SELECT 'D', now(), user, OLD.*;
RETURN OLD;
ELSIF (TG_OP = 'UPDATE') THEN
INSERT INTO AUDITORIA SELECT 'U', now(), user, NEW.*;
RETURN NEW;
ELSIF (TG_OP = 'INSERT') THEN
INSERT INTO AUDITORIA SELECT 'I', now(), user, NEW.*;
RETURN NEW;
END IF;
END;
$$ LANGUAGE plpgsql;

Ahora se crea el trigger sobre la tabla CUENTAS que se activa cada que se
inserta, actualiza o elimina una (o varias) fila(s) en CUENTAS:
CREATE TRIGGER cue_audit
AFTER INSERT OR UPDATE OR DELETE ON CUENTAS
FOR EACH ROW EXECUTE PROCEDURE process_cue_audit();

Algunos ejemplos:
bdi00=> insert into cuentas (saldo,cli_id) values (3500,2);
INSERT 0 1
bdi00=> select * from auditoria;
operacion |
fechaupd
| usuario | id | saldo | cli_id | fecha_sobregiro | intereses
-----------+----------------------------+---------+----+-------+--------+-----------------+---------I
| 2010-04-26 10:30:18.081372 | bdi00
| 6 | 3500 |
2 |
|
0
(1 row)
bdi00=> update cuentas set fecha_sobregiro = now() where id =1;
UPDATE 1
bdi00=> select * from auditoria;
operacion |
fechaupd
| usuario | id | saldo | cli_id | fecha_sobregiro | intereses
-----------+----------------------------+---------+----+-------+--------+-----------------+---------I
| 2010-04-26 10:30:18.081372 | bdi00
| 6 | 3500 |
2 |
|
0

139

U
(2 rows)

| 2010-04-26 10:31:23.2547

| bdi00

1 |

4067 |

1 | 2010-04-26

Validacin
Los triggers son muy tiles cuando se requieren hacer validaciones que que no
se pueden realizar con las restricciones de integridad referencial (PK, FK,
UK,CK). Por ejemplo, asume que un cliente por poltica del banco, no puede
tener ms de 3 cuentas activas. Cada que se inserta una nueva cuenta, o se
actualiza el titular de la cuenta, se debe verificar que no se incumple esta
propiedad. Primero implementamos la funcin:
/* Funcion que verifica que el numero de cuentas de un cliente no
sea mayor a 3 */
CREATE OR REPLACE FUNCTION FUN_CK_NUM_CLIENTES() RETURNS TRIGGER AS $$
DECLARE
NUM_CUENTAS INT;
BEGIN
IF (TG_OP = 'UPDATE' AND OLD.CLI_ID <> NEW.CLI_ID ) OR TG_OP='INSERT' THEN
SELECT COUNT(*) INTO NUM_CUENTAS FROM CUENTAS
WHERE CLI_ID = NEW.CLI_ID;
IF NUM_CUENTAS >= 3 THEN
RAISE EXCEPTION 'LIMITE DEL NUMERO DE CUENTAS ALCANZADO POR EL CLIENTE';
ELSE
RETURN NEW;
END IF;
ELSE
RETURN NEW;
END IF;
END;
$$ LANGUAGE plpgsql;
/* Creacion del Trigger */
CREATE TRIGGER TRG_NUM_CLIENTES
AFTER INSERT OR UPDATE ON CUENTAS
FOR EACH ROW EXECUTE PROCEDURE FUN_CK_NUM_CLIENTES();

Valores Calculados
Los triggers tambin pueden ser utilizados para mantener valores calculados.
Por ejemplo, asumamos que en la tabla CLIENTES se desea mantener el
acumulado en dinero que tiene el cliente en sus distintas cuentas. Para esto,
modificamos la tabla:
ALTER TABLE CLIENTES ADD COLUMN SALDO REAL DEFAULT 0.0;

Como no habamos implementado el trigger que se encargara de llevar este


saldo, por la primera vez lo calculamos manualmente:
CREATE OR REPLACE FUNCTION UPDATE_SALDOS() RETURNS VOID AS $$
140

DECLARE
CLIENTE_SALDO REAL;
CLIENTE_ID REAL;
BEGIN
FOR CLIENTE_ID, CLIENTE_SALDO IN SELECT CLI_ID, SUM(SALDO) FROM CUENTAS GROUP BY
CLI_ID LOOP
UPDATE CLIENTES SET SALDO=CLIENTE_SALDO WHERE ID = CLIENTE_ID;
END LOOP;
RETURN;
END;$$
LANGUAGE plpgsql;

Ahora, por cada modificacin del saldo en una cuenta, actualizamos el saldo en
el cliente:
CREATE OR REPLACE FUNCTION SET_SALDO_CLIENTE() RETURNS TRIGGER AS $$
BEGIN
IF(TG_OP = 'INSERT') THEN
UPDATE CLIENTES SET SALDO = SALDO + NEW.SALDO WHERE ID = NEW.CLI_ID;
RETURN NEW;
ELSIF (TG_OP = 'UPDATE') THEN
IF NEW.CLI_ID = OLD.CLI_ID THEN
UPDATE CLIENTES SET SALDO = SALDO + NEW.SALDO - OLD.SALDO WHERE ID =
NEW.CLI_ID;
RETURN NEW;
ELSE /* LA CUENTA CAMBIO DE TITULAR */
UPDATE CLIENTES SET SALDO = SALDO - OLD.SALDO WHERE ID = OLD.CLI_ID;
UPDATE CLIENTES SET SALDO = SALDO + NEW.SALDO WHERE ID = NEW.CLI_ID;
RETURN NEW;
END IF;
END IF;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
/* Creacion del Trigger */
CREATE TRIGGER TRG_SALDO_CLIENTES
AFTER INSERT OR UPDATE ON CUENTAS
FOR EACH ROW EXECUTE PROCEDURE SET_SALDO_CLIENTE();

Realice algunas operaciones sobre la tabla CUENTAS (cambiando el titular y/o


el saldo) para verificar que la cuenta se lleva correctamente.

Manejo de Errores
Es posible lanzar y capturar errores de la siguiente manera:
CREATE OR REPLACE FUNCTION TEST(int, int) RETURNS INT AS $$
DECLARE
X INT;
BEGIN
X := $1/$2;
RETURN X;
EXCEPTION
WHEN division_by_zero THEN

141

RAISE EXCEPTION 'Division por cero';


RETURN 0;
WHEN others THEN
RAISE NOTICE 'Error';
RETURN 0;
END;
$$ LANGUAGE plpgsql;

Ejemplo de uso:
bdi00=> select test(6,2);
test
-----3
(1 row)
bdi00=> select test(6,0);
NOTICE: Division por cero
test
-----0
(1 row)

Ejercicio Red Social


Asuma el siguiente esquema de bases de datos:
usuarios(*id,nombre,email, num_amigos)
amigos(*id_usr1, *id_usr2)
invitaciones(*id, fecha, *id_usr1, *id_usr2, mensaje, estado)

Cuando un usuario quiere ser amigo de otro, debe enviar una invitacin. Los
estados de la invitacin pueden ser pendiente, aceptado, rechazado.
1. Cree el script de tablas
2. Implemente un procedimiento que cada que se acepte una invitacin, se
adicione la relacin de amistad en la tabla amigos.
3. Por cada nuevo amigo se debe actualizar el nmero de amigos en el
campo USUARIOS.NUM_AMIGOS
4. La relacin de amigos se asume que es simtrica, es decir, si A es amigo
de B entonces B es amigo de A. Realice un trigger que evite la insercin
de (A,B) en la tabla AMIGOS si la tuple (B,A) ya se encuentra. Adems, se
deben rechazar invitaciones de A,B si A,B ya son amigos (o B,A ya son
amigos)
5. Adicione un trigger que rechace nuevas invitaciones de A a B si B ha
rechazado previamente la invitacin.

Solucin Ejemplo de la Red Social con validaciones:

142

CREACION DE TABLAS
CREATE TABLE USUARIOS (
ID SERIAL NOT NULL,
NOMBRE VARCHAR(20),
EMAIL VARCHAR(20),
NUM_AMIGOS INT DEFAULT 0);
CREATE TABLE AMIGOS(
USR1_ID INT NOT NULL,
USR2_ID INT NOT NULL);
CREATE TABLE INVITACIONES (
ID SERIAL NOT NULL,
FECHA TIMESTAMP DEFAULT NOW(),
USR1_ID INT NOT NULL,
USR2_ID INT NOT NULL,
ESTADO CHAR(1) DEFAULT 'P');

RESTRICCIONES
ALTER TABLE USUARIOS ADD CONSTRAINT USR_PK PRIMARY KEY(ID);
ALTER TABLE AMIGOS ADD CONSTRAINT AMI_PK PRIMARY KEY(USR1_ID,USR2_ID);
ALTER TABLE INVITACIONES ADD CONSTRAINT INV_PK PRIMARY KEY(ID);
ALTER TABLE AMIGOS ADD CONSTRAINT AMI_USR_1_FK FOREIGN KEY (USR1_ID) REFERENCES USUARIOS (ID);
ALTER TABLE AMIGOS ADD CONSTRAINT AMI_USR_2_FK FOREIGN KEY (USR2_ID) REFERENCES USUARIOS (ID);
ALTER TABLE INVITACIONES ADD CONSTRAINT INV_USR_1_FK FOREIGN KEY (USR1_ID) REFERENCES USUARIOS
(ID);

ALTER TABLE INVITACIONES ADD CONSTRAINT INV_ESTADO_CK CHECK


(ESTADO IN ('P','A','R'));

FUNCION ADD_FRIENDSHIP
Adiciona la relacin de amistad si se acepta la invitacin. Se asume que los dos
usuarios no son amigos
CREATE OR REPLACE FUNCTION ADD_FRIENDSHIP() RETURNS TRIGGER AS $$
BEGIN
IF NEW.ESTADO = 'A' THEN
INSERT INTO AMIGOS (USR1_ID,USR2_ID) VALUES (NEW.USR1_ID,NEW.USR2_ID);
END IF;
RETURN NEW;
END;
$$ LANGUAGE PLPGSQL;
CREATE TRIGGER TRG_ADD_FRIENDSHIP AFTER UPDATE ON INVITACIONES
FOR EACH ROW EXECUTE PROCEDURE ADD_FRIENDSHIP();

FUNCION UPDATE_NUM_AMIGOS

143

Actualiza el nmero de amigos de un usuario


CREATE OR REPLACE FUNCTION UPDATE_NUM_AMIGOS() RETURNS TRIGGER AS $$
BEGIN
IF TG_OP = 'INSERT' THEN
/* SE DEBEN ACTUALIZAR AMBOS USUARIOS PORQUE LA RELACION ES SIMETRICA */
UPDATE USUARIOS SET NUM_AMIGOS=NUM_AMIGOS+1
WHERE ID IN (NEW.USR1_ID,NEW.USR2_ID);
ELSEIF TG_OP = 'DELTE' THEN
UPDATE USUARIOS SET NUM_AMIGOS=NUM_AMIGOS-1
WHERE ID IN (NEW.USR1_ID,NEW.USR2_ID);
END IF;
RETURN NEW;
END;
$$ LANGUAGE PLPGSQL;
CREATE TRIGGER TRG_UPDATE_NUM_AMIGOS AFTER INSERT ON AMIGOS
FOR EACH ROW EXECUTE PROCEDURE UPDATE_NUM_AMIGOS();

FUNCION CHECK_SIMETRIA
Verifica que no se inserte la relacin de amigos B,A si A,B ya son amigos
CREATE OR REPLACE FUNCTION CHECK_SIMETRIA() RETURNS TRIGGER AS $$
DECLARE
NUM INT;
BEGIN
IF TG_OP = 'INSERT' THEN
SELECT COUNT(*) INTO NUM FROM AMIGOS WHERE USR2_ID = NEW.USR1_ID AND USR1_ID = NEW.USR2_ID;
IF NUM >0 THEN
RAISE EXCEPTION 'YA EXISTE LA RELACION DE AMIGOS ENTRE % Y %',NEW.USR2_ID,NEW.USR1_ID;
END IF;
ELSIF TG_OP = 'UPDATE' THEN
SELECT COUNT(*) INTO NUM FROM AMIGOS WHERE USR2_ID = NEW.USR1_ID AND USR1_ID = NEW.USR2_ID;
IF NUM >0 THEN
RAISE EXCEPTION 'YA EXISTE LA RELACION DE AMIGOS ENTRE % Y %',NEW.USR2_ID,NEW.USR1_ID;
END IF;
END IF;
RETURN NEW;
END;
$$ LANGUAGE PLPGSQL;

CREATE TRIGGER TRG_CHECK_SIMETRIA BEFORE UPDATE OR INSERT ON AMIGOS


FOR EACH ROW EXECUTE PROCEDURE CHECK_SIMETRIA();

FUNCIONE CHECK_INVITACION
Verifica que no se inserte una nueva invitacin que haya sido previamente
rechazada o que las personas ya son amigas
CREATE OR REPLACE FUNCTION CHECK_INVITACION() RETURNS TRIGGER AS $$
DECLARE
NUM INT;
BEGIN
IF TG_OP = 'INSERT' THEN

144

-- Verificar que ya no exista la relacion entre los dos usuarios


SELECT COUNT(*) INTO NUM FROM AMIGOS
WHERE
(USR1_ID = NEW.USR1_ID AND USR2_ID = NEW.USR2_ID) OR
(USR2_ID = NEW.USR1_ID AND USR1_ID = NEW.USR2_ID);
IF NUM >0 THEN
RAISE EXCEPTION 'YA EXISTE LA RELACION DE AMIGOS ENTRE % Y %',NEW.USR1_ID,NEW.USR2_ID;
END IF;
-- Verificar que no exista una invitacion para la misma relacion
SELECT COUNT(*) INTO NUM FROM INVITACIONES
WHERE ESTADO <> 'R' AND (
(USR1_ID = NEW.USR1_ID AND USR2_ID = NEW.USR2_ID) OR
(USR2_ID = NEW.USR1_ID AND USR1_ID = NEW.USR2_ID) );
IF NUM >0 THEN
RAISE EXCEPTION 'YA EXISTE UNA INVITACION ENTRE % Y %',NEW.USR1_ID,NEW.USR2_ID;
END IF;
-- Verificar que no exista una invitacion rechazada para la misma relacion
SELECT COUNT(*) INTO NUM FROM INVITACIONES
WHERE ESTADO = 'R' AND (
(USR1_ID = NEW.USR1_ID AND USR2_ID = NEW.USR2_ID) OR
(USR2_ID = NEW.USR1_ID AND USR1_ID = NEW.USR2_ID) );
IF NUM >0 THEN
RAISE EXCEPTION 'La relacion entre % Y % ya ha sido rechazada',NEW.USR1_ID,NEW.USR2_ID;
END IF;
ELSIF TG_OP = 'UPDATE' THEN -- Cualquier intento de actualizacion de los usuarios se rechaza
IF NEW.USR1_ID <> OLD.USR1_ID OR NEW.USR2_ID <> OLD.USR2_ID THEN
RAISE EXCEPTION 'Los atributos USR1_ID y USR2_ID no pueden ser modificados';
END IF;
END IF;
RETURN NEW;
END;
$$ LANGUAGE PLPGSQL;

CREATE TRIGGER TRG_CHECK_INVITACION BEFORE UPDATE OR INSERT ON INVITACIONES


FOR EACH ROW EXECUTE PROCEDURE CHECK_INVITACION();

ALGUNAS PRUEBAS
INSERT INTO USUARIOS (NOMBRE, EMAIL) VALUES
('USUARIO 1','EMAIL1'),
('USUARIO 2','EMAIL2'),
('USUARIO 3','EMAIL3'),
('USUARIO 4','EMAIL4'),
('USUARIO 5','EMAIL5');
INSERT INTO INVITACIONES (USR1_ID, USR2_ID) VALUES (1,2);

La siguiente insercin es rechazada porque ya existe una invitacin entre 2 y 1.


Verificada por la FUNCION CHECK_SIMETRIA
INSERT INTO INVITACIONES (USR1_ID, USR2_ID) VALUES (2,1);

Ahora se acepta la invitacin


UPDATE INVITACIONES SET ESTADO = 'A' WHERE ID = 1;

Se pueden ver las actualizaciones en las tablas USUARIOS y AMIGOS


145

SELECT * FROM USUARIOS;


SELECT * FROM AMIGOS;

Un intento de modificar los usuarios de la invitacin conduce a un error:


UPDATE INVITACIONES SET USR1_ID = 3 WHERE ID = 1;

Una nueva invitacin. La insercin es rechazada porque ya existe una invitacin


entre 3 y 1, Verificada por la FUNCION CHECK_SIMETRIA
INSERT INTO INVITACIONES (USR1_ID, USR2_ID) VALUES (3,1);

Actualiza la Invitacin
UPDATE INVITACIONES SET ESTADO = 'R' WHERE ID =2;

Ahora no se puede hacer una segunda peticin de 1 a 3 o de 3 a 1 porque


funcin FUNCION CHECK_SIMETRIA lo verifica.
INSERT INTO INVITACIONES (USR1_ID, USR2_ID) VALUES (3,1);

Ms informacin en el Manual de Postgres:


http://www.postgresql.org/docs/9.2/interactive/plpgsql.html

146

Consultas Enumeradas
Son consultas que retornan registros con una columna adicional que enumera
todas las filas.
En este ejemplo se hace uso de la base de datos DBAdmision poblada, el CASO
DE ESTUDIO de la pgina 75 y se explica la consulta detalladamente.
SUGERENCIA:
Si has utilizado la base de datos dbadmision en ejercicios previos es mejor volver
a crearla.
Utilizar el Script: dbadmin.sql
Crear una funcin que liste todos los postulantes, la lista debe estar
enumerada y ordenada por apellido paterno, materno y nombres.
N

Apellidos y Nombres

Alanya Padilla Alina Susan

Alarcon
Andres

Alarco Lama Ricardo Rafael

Altez Yaez Jazmn GApriela

Amable Salva Katerin Lisbet

Antonio Reyes Freddy Angel

Atachagua Cossio Jessica Roxana

Aucasi Huanca Angela Marine

Avila Salvador Pamely Lorena Kenny

10

Balden Balvn Olger

11

Balden SanApria Natalia Ivonne

Castro

Gustavo

Claudio

Primero debemos crear una funcin que nos retorne una tipo de dato numrico, la
llamaremos rownumber, para ello tambin se realizar la creacin temporal de un
objeto SEQUENCE, cuyo nombre ser el timestamp actual, por ejemplo: SELECT
current_timestamp retorna algo como: 2009-11-17 06:18:53.057964-05. La
funcin nextval realizar el retorno del valor siguiente de dicha secuencia, lo que
har que por cada llamada que reciba el valor ir incementando de uno un uno.
147

CREATE OR REPLACE FUNCTION rownumber() RETURNS integer AS $$


BEGIN
EXECUTE 'CREATE TEMP SEQUENCE "'||current_timestamp||'"';
RETURN nextval('"'||current_timestamp||'"');
EXCEPTION WHEN duplicate_table THEN RETURN nextval('"'||current_timestamp||'"');
END
$$ LANGUAGE 'plpgsql';

La funcin anterior se crear por defecto en el esquema pblico.


Como la funcin crea una secuencia temporal hace posible que al finalizar la
ejecucin de la consulta la secuencia se elimine y por lo tanto la numeracin
vuelva a reiniciarse en cada ejecucin.
SELECT rownumber() "Numero",* FROM
(SELECT PC.Paterno || ' ' || PC.Materno || ' ' || PC.Nombres "Apellidos y Nombres"
FROM Persona.Contacto PC
INNER JOIN Persona.Postulante PP ON PP.IDContacto=PC.IDContacto
ORDER BY PC.Paterno,PC.Materno,PC.Nombres) AS tb1

A partir de la versin 8.4 de PostgreSQL, podemos ahorrarnos esfuerzos para


construir esta consulta, ya que en sta versin si exste la funcin row_number,
aunque habr que hacer uso de Window Functions (Funciones Ventanas) que se
ven ms adelante.

148

Consultas, Funciones, Procedimientos y Vistas


Con la base datos poblada y el CASO DE ESTUDIO de la pgina 75 podemos
comenzar a elaborar nuestras primeras consultas usando instrucciones DML.
Se crean funciones cuando se trata de retornar datos, como por ejemplo una
consulta que utilice la clusula SELECT, y procedimientos almacenados
nicamente cuando se trata de realizar una operacin que no retorne ningn dato,
por ejemplo, INSERT, UPDATE o DELETE, aunque en Postgres tambin se puede
retornar datos con procedimientos almacenados, sera ideal respetar la
funcionalidad de cada uno. Las funciones desarrolladas se realizar haciendo uso
del lenguaje procedural 'plpgsql', que generalmente trae PostgreSQL.
SUGERENCIA:
Si has utilizado la base de datos dbadmision en ejercicios previos es mejor volver
a crearla.
Utilizar el Script: dbadmin.sql
CONSULTAS:
1) Crear una consulta que devuelva los siguientes datos:
Periodo

101

309

310

Total

2005-1

15

2005-2

13

12

25

2006-1

17

18

35

2006-2

23

22

45

2007-1

27

28

55

SELECT idperacad AS "Periodo"


,SUM(CASE WHEN IDCarrera = '101' THEN 1 ELSE 0 END ) AS "101"
,SUM(CASE WHEN IDCarrera = '309' THEN 1 ELSE 0 END ) AS "309"
,SUM(CASE WHEN IDCarrera = '310' THEN 1 ELSE 0 END ) AS "310"
,COUNT(*) AS "TOTAL"
FROM Persona.Postulante
GROUP BY IDPerAcad
ORDER BY IDPerAcad

2) Crear una consulta que devuelva los siguientes datos:


Periodo

101

2005-1

309

310

Total

15
149

2005-2

13

12

25

2006-1

17

18

35

2006-2

23

22

45

2007-1

27

28

55

TOTAL

87

87

175

SELECT idperacad AS "Periodo"


,SUM(CASE WHEN IDCarrera = '101'
,SUM(CASE WHEN IDCarrera = '309'
,SUM(CASE WHEN IDCarrera = '310'
,COUNT(*) AS "TOTAL"
FROM Persona.Postulante
GROUP BY IDPerAcad
UNION
SELECT 'TOTAL' AS "Periodo"
,SUM(CASE WHEN IDCarrera = '101'
,SUM(CASE WHEN IDCarrera = '309'
,SUM(CASE WHEN IDCarrera = '310'
,COUNT(*) AS total
FROM Persona.Postulante

THEN 1 ELSE 0 END ) AS "101"


THEN 1 ELSE 0 END ) AS "309"
THEN 1 ELSE 0 END ) AS "310"

THEN 1 ELSE 0 END ) AS "101"


THEN 1 ELSE 0 END ) AS "309"
THEN 1 ELSE 0 END ) AS "310"

FUNCIONES:
3) Crear una funcin que liste todos los postulantes, la lista debe estar
enumerada y ordenada por apellido paterno, materno y nombres.
N

Apellidos y Nombres

Alanya Padilla Alina Susan

Alarcon Castro Gustavo Claudio


Andres

Alarco Lama Ricardo Rafael

CREATE OR REPLACE FUNCTION f_ejemplo_4()


RETURNS SETOF "record" AS
$BODY$
DECLARE
r RECORD;
BEGIN
FOR r IN
SELECT rownumber() "Numero",* FROM
(SELECT PC.Paterno || ' ' || PC.Materno || ' ' || PC.Nombres "Apellidos y
Nombres"
FROM Persona.Contacto PC
INNER JOIN Persona.Postulante PP ON PP.IDContacto=PC.IDContacto
ORDER BY PC.Paterno,PC.Materno,PC.Nombres) AS tb2
LOOP
RETURN NEXT r;

150

END LOOP;
RETURN;
END;
$BODY$
LANGUAGE 'plpgsql' VOLATILE;
--SELECT * FROM f_ejemplo_4() AS ("Numero" INTEGER, "Apellidos y Nombres" TEXT);
CREATE OR REPLACE FUNCTION rownumber() RETURNS integer AS $$
BEGIN
EXECUTE 'CREATE TEMP SEQUENCE "'||current_timestamp||'"';
RETURN nextval('"'||current_timestamp||'"');
EXCEPTION WHEN duplicate_table THEN RETURN nextval('"'||current_timestamp||'"');
END
$$ LANGUAGE 'plpgsql';

PROCEDIMIENTOS ALMACENADOS:
4) Crear un procedimiento almacenado que permita eliminar los postulantes
registrados correspondientes a una modalidad.
--SELECT * FROM Persona.Postulante ORDER BY IDModalidad;
CREATE OR REPLACE FUNCTION sp_ejemplo_12(p_IDModalidad integer) RETURNS integer
AS $$
BEGIN
DELETE FROM Persona.Postulante
WHERE IDModalidad=p_IDModalidad;
return p_IDModalidad;
END;
$$ LANGUAGE plpgsql;
--SELECT sp_ejemplo_12(2);
--SELECT * FROM Persona.Postulante ORDER BY IDModalidad;

VISTAS:
5) Crear una vista que muestre un resumen como el siguiente:
Nombre

2005-1

2005-2

2006-1

2006-2

2007-1

Administracin

TOTAL

12

14

23

62

Contabilidad

13

17

22

65

Ingeniera
Informtica

TOTAL

11

15

25

31

45

127

151

CREATE OR REPLACE VIEW v_ejemplo_11


AS
(
SELECT AC.Nombre,SUM(CASE WHEN PP.Ingreso='1' AND PP.IDPerAcad IN ('2005-1') THEN 1 ELSE 0
END) "2005-1",
SUM(CASE WHEN PP.Ingreso='1' AND PP.IDPerAcad IN ('2005-2') THEN 1 ELSE 0 END) "2005-2",
SUM(CASE WHEN PP.Ingreso='1' AND PP.IDPerAcad IN ('2006-1') THEN 1 ELSE 0 END) "2006-1",
SUM(CASE WHEN PP.Ingreso='1' AND PP.IDPerAcad IN ('2006-2') THEN 1 ELSE 0 END) "2006-2",
SUM(CASE WHEN PP.Ingreso='1' AND PP.IDPerAcad IN ('2007-1') THEN 1 ELSE 0 END) "2007-1",
SUM(CASE WHEN PP.Ingreso='1' AND PP.IDPerAcad IN ('2005-1','2005-2','2006-1','2006-2','20071') THEN 1 ELSE 0 END) "TOTAL"
FROM Persona.Contacto PC
INNER JOIN Persona.Postulante PP ON PP.IDContacto=PC.IDContacto
INNER JOIN Admision.Carrera AC ON AC.IDCarrera=PP.IDCarrera
GROUP BY AC.Nombre
UNION
SELECT 'TOTAL',SUM(CASE WHEN PP.Ingreso='1' AND PP.IDPerAcad IN ('2005-1') THEN 1 ELSE 0 END)
"2005-1",
SUM(CASE WHEN PP.Ingreso='1' AND PP.IDPerAcad IN ('2005-2') THEN 1 ELSE 0 END) "2005-2",
SUM(CASE WHEN PP.Ingreso='1' AND PP.IDPerAcad IN ('2006-1') THEN 1 ELSE 0 END) "2006-1",
SUM(CASE WHEN PP.Ingreso='1' AND PP.IDPerAcad IN ('2006-2') THEN 1 ELSE 0 END) "2006-2",
SUM(CASE WHEN PP.Ingreso='1' AND PP.IDPerAcad IN ('2007-1') THEN 1 ELSE 0 END) "2007-1",
SUM(CASE WHEN PP.Ingreso='1' AND PP.IDPerAcad IN ('2005-1','2005-2','2006-1','2006-2','20071') THEN 1 ELSE 0 END) "TOTAL"
FROM Persona.Contacto PC
INNER JOIN Persona.Postulante PP ON PP.IDContacto=PC.IDContacto
INNER JOIN Admision.Carrera AC ON AC.IDCarrera=PP.IDCarrera
);
--SELECT * FROM v_ejemplo_11;

152

Funciones Ventana (Window Functions)


Las funciones ventana vienen incorporadas a partir de la versin 8.4 de
PostgreSQL.
Las funciones ventana permiten tener ms variedad en al momento de realizar
consultas y en otros casos se puede optimizar como se describir a continuacin.
En el tema referente a Consultas Enumeradas (Pgina 147) se explica que es
necesario crear una funcin extra para poder realizar la enumeracin de las filas
en una consulta, pues hacer esto con las funciones ventana es mucho ms
sencillo.
SUGERENCIA:
Si has utilizado la base de datos dbadmision en ejercicios previos es mejor volver
a crearla.
Utilizar el Script: dbadmin.sql

1) Crear una funcin que liste todos los postulantes, la lista debe estar
enumerada y ordenada por apellido paterno, materno y nombres.
N

Apellidos y Nombres

Alanya Padilla Alina Susan

Alarcon Castro Gustavo Claudio


Andres

Alarco Lama Ricardo Rafael

SELECT row_number() OVER (ORDER BY PC.Paterno,PC.Materno,PC.Nombres) AS "N"


,PC.Paterno || ' ' || PC.Materno || ' ' || PC.Nombres AS "Apellidos y Nombres"
FROM Persona.Contacto PC
INNER JOIN Persona.Postulante PP ON PP.IDContacto=PC.IDContacto

Si pudieron darse cuenta, a partir de la version 8.4 ya se puede hacer uso de la


funcin row_number(), pero nunca de manera independiente, ste necesita de
la clusula OVER para ser ejecutada. Otra de las cosas que nos ahorramos
hacer en este ejemplo en comparacin con el desarrollado en el post anterior,
es que ahora no necesitamos crear una consulta anidada.

153

2) Crear una funcin que liste todos los postulantes de un determinado


periodo acadmico. La lista debe reiniciar la numeracin por orden
alfabtico.
N

Apellidos y Nombres

Alanya Padilla Alina Susan

Alarcon Castro Gustavo Claudio Andres

Balden Balvn Olger

Balden Sanabria Natalia Ivonne

Cachun Cmac Miguel Fernando

Cajachagua Chui Jose Arturo

SELECT row_number() OVER (PARTITION by substring(PC.Paterno FROM 1 FOR 1)


ORDER BY PC.Paterno,PC.Materno,PC.Nombres) AS "N"
,PC.Paterno || ' ' || PC.Materno || ', ' || PC.Nombres AS "Apellidos y Nombres"
FROM Persona.Contacto PC
INNER JOIN Persona.Postulante PP
ON PP.IDContacto=PC.IDContacto

Aqu hacemos lo mismo que en la primera consulta, pero en sta hacemos la


particin por el inicio de cada apellido, por ejemplo: substring(ABCDEF from 1
for 1), retorna solo A., de esa manera la numeracin se volver a realizar
cuando el inicio del apellido sea diferente al anterior.
En conclusin, lo que hace un Window Function es ejecutar la consulta por
cada segmento o grupo de filas, esto d ms poder a una consulta en
comparacin con los que se aplican implcitamente en todo el resultado.
3) Listar todos los postulantes que ingresaron con sus respectivos puntajes
ordenado descendentemente y acompaado del puntaje promedio
obtenido por cada carrera.
Carrera

Postulantes

Promedio

Puntaje

Administracin

Caari Rodriguez Jose Antonio

73.065

97

Administracin

Huamn Huaman Nidia Anais

73.065

93

Administracin

Ricapa Quispe Nilton Csar

73.065

89

Contabilidad

Benito

74.369

98

Dionisio

Melissa

154

Katherine
Contabilidad

Salazar Gutirrez Enrique Pal

74.369

98

Contabilidad

Sulca Palomino Ivan

74.369

98

SELECT AC.Nombre AS "Carrera"


,PC.Paterno || ' ' || PC.Materno || ' ' || PC.Nombres AS "Postulantes"
,round(AVG(PP.Puntaje) OVER (PARTITION BY PP.idcarrera),3) AS "Promedio"
,PP.Puntaje AS "Puntaje"
FROM Persona.Contacto PC
INNER JOIN Persona.Postulante PP ON PP.IDContacto=PC.IDContacto
INNER JOIN Admision.Carrera AC ON PP.IDCarrera=AC.IDCarrera
WHERE PP.Ingreso='1'
ORDER BY AC.idcarrera, PP.puntaje DESC

Tambin existe otro mecanismo para realizar las segmentaciones, utilizando


explcitamente la clusula WINDOW y referenciando el campo donde se
aplicar con la clusula OVER.
SELECT AC.Nombre AS "Carrera"
,PC.Paterno || ' ' || PC.Materno || ' ' || PC.Nombres AS "Postulantes"
,ROUND(AVG(PP.Puntaje) OVER w ,3)AS "Promedio"
,PP.Puntaje AS "Puntaje"
FROM Persona.Contacto PC
INNER JOIN Persona.Postulante PP ON PP.IDContacto=PC.IDContacto
INNER JOIN Admision.Carrera AC ON PP.IDCarrera=AC.IDCarrera
WHERE PP.Ingreso='1'
WINDOW w AS (PARTITION BY PP.idcarrera)
ORDER BY AC.idcarrera, PP.puntaje DESC

Esta ltima consulta retornar exactamente lo mismo que en su forma anterior.

155

Automatizacin de Backups
SUGERENCIA:
Si has utilizado la base de datos dbadmision en ejercicios previos es mejor volver
a crearla.
Utilizar el Script: dbadmin.sql
El proceso de creacin de backups en postgres se realiza por medio de pg_dump,
y la automatizacin para su ejecucin se puede lograr por medio de herramientas
como las que se incluye en PGADMIN haciendo uso de los jobs, steps y schedules
o mediante el sistema operativo, como veremos en este ejemplo.
1- CREACIN DE SCRIPT
Script para Linux: pg_backup.sh
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.

#!/bin/bash
#-Por: sAfOrAsPG_BIN='/usr/bin/pg_dump'
PG_HOST='localhost'
PG_PORT='5432'
PG_DATABASE='dbadmision'
PG_USER='postgres'
export PGPASSWORD='postgres'
PG_PATH='/var/PGBACKUP'
FECHAYHORA=$(date + "%d-%m-%Y-%H-%M-%S")
PG_FILENAME= "${PG_PATH}/${PG_DATABASE}-${FECHAYHORA}.backup"
${PG_BIN} -i -h ${PG_HOST} -p ${PG_PORT} -U ${PG_USER}
${PG_FILENAME} ${PG_DATABASE}

-F

-b

-v

-f

Estableciendo Permisos para ejecutar el Script:


1. # chmod +x pg_backup.sh

Cambiando de propietario del script y directorios donde se guardarn los backups,


el propietario debe ser el usuario postgres.
2. # chown postgres:postgres pg_backup.sh --Script
3. # chown -R postgres:postgres /var/PGBACKUP --Directorio de Backups

Script para Windows: pg_backup.bat


1.
2.
3.
4.
5.
6.

@echo off
::-Por: sAfOrAsSET PG_BIN=C:\PostgresPlus\8.3R2AS\postgresstudio\pg_dump.exe
SET PG_HOST=localhost
SET PG_PORT=5432
SET PG_DATABASE=dbadmision

156

7.
8.
9.
10.
11.
12.
13.
14.

SET PG_USER=postgres
SET PGPASSWORD=postgres
SET PG_PATH=C:\PGBACKUP\
SET FECHAYHORA=%date:/=-%-%time:~0,8%
SET FECHAYHORA=%FECHAYHORA::=-%
SET FECHAYHORA=%FECHAYHORA: =0%
SET PG_FILENAME=%PG_PATH%\%PG_DATABASE%-%FECHAYHORA%.backup
%PG_BIN% -i -h %PG_HOST% -p %PG_PORT% -U %PG_USER% -F c -b -v -f %PG_FILENAME%
%PG_DATABASE%

Se debe establecer permisos de ejecucin del script y derechos del usuario


postgres sobre los directorios donde se almacenarn los backups y sobre el script.
2- AUTOMATIZACIN:
Automatizacin en linux: Por medio de crones.
15.
16.
17.
18.
19.
20.

# crontab -e
0 0 * 12 *

/home/usuario/pg_backup.sh

<<Guardar>> CTRL + O
<<Salir>> CRTL + X

Este script ejecuta pg_backup.sh del siguiente modo:


0: Minutos (00)
0: Horas (00)
*:Dias del mes (todos)
12 Mes (Diciembre)
* Dias de la semana (L,M,M,J,V,S,D)
Por lo tanto se ejecutar todos los dias de la semana durante el mes de Diciembre
a las 00hh:00mm (Media Noche).
Automatizacin en Windows: Con taskschd CONTROL SCHEDTASK o AT
SOBRE LAS VARIABLES DEL SCRIPT:
Variable
PG_BIN
PG_HOST
PG_PORT
PG_DATABASE
PG_USER

descripcin
Ubicacion de pg_dump, es el binario que realiza los backups
direccin del host
puerto del servidor
nombre de la base de datos
nombre del usuario
Contrasea del servidor: Es una variable especial registrada
PGPASSWORD en el sistema, el nombre de esta variable debe permanecer
inmutable en el sistema operativo.

157

Bibliografia
http://www.postgresql.org/
http://www.postgresql.org/docs/
http://www.postgresql.org/about/casestudies/
http://www.postgresql.org/docs/7.3/interactive/diskusage.html
http://www.postgresql.org.es/node/667
http://www.pgadmin.org/
http://es.wikipedia.org/wiki/Anexo:Comparaci%C3%B3n_de_sistemas_administrad
ores_de_bases_de_datos_relacionales
http://www.davidghedini.com/pg/entry/install_postgresql_9_on_centos
http://www.if-not-true-then-false.com/2012/install-postgresql-on-fedora-centos-redhat-rhel/
http://blog.neobytec.com/instalando-postgresql-en-centos-6-2-6-3/
http://phenobarbital.wordpress.com/2012/07/24/postgresql-una-instalacion-depostgresql-basica-pero-mejor/
http://tuxapuntes.com/instalar-postgresql-en-centos-6-3/
http://cic.puj.edu.co/wiki/doku.php?id=materias:taller_pl_pgsql
http://help.arcgis.com/es/arcgisdesktop/10.0/help/index.html#//001s000000010000
00
http://wiki.centos.org/es/HowTos/Network/IPTables

158

You might also like