Artículo para la revista Linux Actual número 14:

Javier Fernández-Sanguino Peña

15 mayo 2000


En este artículo de la serie dedicada a bases de datos, vamos a introducir una posible aplicación así como la creación de la base de datos en sí y las distintas posibilidades de implementación para llevarla a cabo.

1. Introducción a este artículo

En el artículo anterior de la serie de bases de datos vía la World Wide Web vimos los componentes de los que iba a formar parte nuestro sistema de acceso a la base de datos y las ventajas de utilizar GNU/Linux como sistema de desarrollo para nuestro proyecto. En este artículo vamos a seguir en la línea dictada por el anterior determinando el componente que nos falta para desarrollar el sistema, en particular, el lenguaje a través del cual vamos a programar el acceso la base de datos; veremos varias alternativas y nos decantaremos (por varias razones) por una de ellas.

También vamos a hacer una breve introducción a la aplicación que vamos a realizar, definiremos el esquema entidad-relación y la conversión a tablas de la misma.

Quedará para el siguiente artículo el diseño del interfaz en sí y su implementación con herramientas de generación automática.

2. Acceso a bases de datos mediante WWW

El uso de Apache y PostgreSQL nos da la arquitectura necesaria para instalar un sistema de acceso a base de datos vía WWW, pero como se puede dar cuenta el lector, aún falta un componente intermedio ¿quién actúa de unión entre el servidor de WWW y el servidor de la Base de Datos? (ver Figura 1).

****************** FIGURA 1*****************************

Es el diseñador el que ha de tomar la decisión de qué se puede implementar entre la base de datos, y el servidor, aunque en realidad puede no ser en absoluto necesario que estos se comuniquen, como ahora veremos. Hay dos posibles soluciones a este problema, por un lado se puede mantener la arquitectura cliente/servidor a través del protocolo HTTP, y por otro se puede romper esta arquitectura y separar los dos servidores de forma que el cliente utilice un método de acceso distinto para cada uno.

En este segundo caso (presentado en la Figura 3) el papel del servidor de WWW sería el de ofrecer la aplicación que permite al cliente se comunicarse con la base de datos. Esta aplicación estaría necesariamente programada en Java y se distribuiría como un applet dentro de una página HTML. Esta posibilidad no va a ser tratada dentro de esta serie ya que rompe el esquema que hemos pretendido introducir, el diseño de esta aplicación no sería con tecnologías estándar de la WWW (formularios, páginas, etc..) sino que sería realizada ad hoc para el problema particular al que nos enfrentamos. El interfaz gráfico se realizaría con los elementos proporcionados por el lenguaje Java (ya sea AWT o Swing), y la comunicación con la base de datos se haría a través del estándar JDBC.

******************** FIGURA 3 **************************

Para el primer caso (mostrado en la figura 2) tenemos varias posibilidades de comunicación entre el servidor y el sistema de base de datos, todas tienen en común el hecho de que nos van a permitir "introducir" la aplicación como elemento dentro de páginas HTML normales. Utilizando tags especiales podremos incorporar los elementos de programación de dichos lenguajes, que serán preprocesados antes de enviar la página al cliente. El cliente, por tanto, no será consciente de la existencia de una base de datos por debajo por que, por lo que a él respecta, los datos se devuelven de la misma forma de lo que está acostumbrada a ver cualquier persona que navega por la WWW. Para realizar la entrada de datos se utilizarán, pues, formularios como se definen en el estándar HTML, cuyos datos serán procesados dentro de la programación de las otras páginas.

******************** FIGURA 2 *************************

Tenemos varios métodos para hacer esto:

Como se puede ver, las alternativas a la hora de hacer el diseño son abundantes y dependen, en gran medida, de la versatilidad que se quiera tener a la hora de implementar la aplicación. La alternativa de introducir Perl en las páginas es quizás la más versátil, ya que, una vez hecho se puede hacer uso de cualquiera de los módulos de Perl para casi cualquier función conocida (como por ejemplo conectarse a teléfonos móviles con WAP). El lenguaje PHP es también muy versátil, aunque no tanto como Perl, y se encuentra más limitado en el acceso a base de datos. Finalmente, www-sql es una librería mucho más específica, con un pseudo-lenguaje de programación mucho menos expresivo que los anteriores (tiene pocos sistemas de bucles y pocas funciones para manipular los datos).

Como quiera que en el proyecto que vamos a abordar no va a ser en exceso complicado, vamos a elegir la alternativa que más sencilla va a resultar de implementar, que será www-sql (en su versión para PostgreSQL, es decir www-pgsql).

3. Instalación de www-pgsql

La instalación de este lenguaje será bastante sencilla. Es necesario instalar la aplicación en si, lo cual logramos instalando el paquete www-pgsql en un sistema Debian GNU/Linux (para otras distribuciones mirar el listado 2).

************** LISTADO 2******************************+

Una vez hecho esto, se debería haber instalado un programa (www-pgsql) en la localización de los CGI scripts de nuestro sistema, este será generalmente /usr/lib/cgi-bin, aunque puede modificarse por el fichero de configuración de Apache srm.conf (en la línea ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/). Lo que hace falta ahora es modificar tanto nuestro servidor de WWW como nuestra base de datos para que sea posible acceder a través de este sistema.

Para modificar a Apache, lo que vamos a hacer es modificar su fichero de configuración srm.conf, para que todos los ficheros que terminen en .pgsql sean procesados por el programa que acabamos de instalar. Añadiendo lo siguiente:

# Para www-pgsql
AddHandler www-pgsql pgsql
Action www-pgsql /cgi-bin/www-pgsql
Esto permitiría que cuando a Apache le sea solicitado un fichero que tenga como extensión pgsql, enviará, antes de devolverlo al cliente que lo ha pedido, este fichero a un programa (/cgi-bin/www-pgsql) para que lo procese. Lo que será enviado al cliente será el resultado de este programa. Para poder activar esta directiva es necesario que en el fichero htttp.conf esté definida la carga del módulo mime_module.

Para modificar el a gestor de la base de datos PostgreSQL y que nuestro script pueda funcionar, es necesario editar los ficheros de configuración para permitir varias cosas. Por un lado es necesario habilitar la posibilidad de conectarse a la base de datos a través de TCP/IP, de no estar habilitado sólo los clientes en la máquina local podrían hacerlo. www-pgsql realiza una conexión TCP/IP con el sistema de base de datos (aunque esté instalado en el mismo servidor) y será necesario habilitarlo, lo que lanzará al demonio de gestión de la misma con la opción -i. Para ello modificamos el fichero de configuración del gestor de la base de datos (en Debian GNU/Linux /etc/postgres/postmaster.init) para añadir lo siguiente:

# Whether to allow connections through TCP/IP as well as through Unix
# sockets: yes/no.
# By default, for greater security, we do not allow TCP/IP access.
# This means that only users on this machine can access the database.
PGALLOWTCPIP=yes

A continuación es necesario modificar la configuración de la base de datos para que permita acceso, sin clave, desde el ordenador local, por defecto, en el fichero /var/postgres/data/pg_hba.conf. Se hace esto sólo para conexiones a través de sockets en dominio UNIX (local) y a través de localhost (dirección IP: 127.0.0.1), pero es necesario habilitarlos para nuestra dirección IP. Suponiendo que nuestra dirección IP fuera 192.168.1.1, modificaríamos el fichero para que queda de la siguiente forma:

# Por defecto, permite cualquier cosa en sockets dominio UNIX y
localhost
local        all                                         trust
host         all         127.0.0.1     255.255.255.255   trust 
# Añadido para www-pgsql
host         all         192.168.1.1   255.255.255.255     trust

Hay que tener cuidado, sin embargo, ya que esta configuración abre un posible agujero de seguridad en la base de datos. Si un usuario pone ficheros, al margen de la aplicación que vamos a desarrollar aquí, con la extensión pgsql y un cliente un cliente a ellos podrá poner arbitrariamente cualquier código SQL dentro de páginas WWW que podrían descubrir información reservada de la base de datos. No vamos a cubrir este aspecto en esta serie de artículos, pero el usuario interesado podrá ver la forma de inhabilitar el acceso a esta directiva (salvo en las zonas del servidor que le interesen) en la documentación del servidor Apache.

De esta forma tendríamos la siguiente configuración (mostrada en la figura 4):

  1. Cuando el servidor de WWW detecte un acceso a una página terminada en .pgsql la enviará al programa www-pgsql para que la procese.
  2. El programa www-pgsql procesará las directivas de conexión a la base de datos (más adelante se verá cómo) y las enviará al gestor de base de datos de PostgreSQL (postmaster).
  3. El demonio gestor de la base de datos recibirá las directivas sql y las procesará (gracias a que le hemos habilitado el acceso).
  4. El programa recoge los resultados y los utiliza para modificar la presentación de la página.
  5. La página con sus modificaciones es devuelta al cliente de WWW que la mostrará al usuario.

En realidad algunos de estos cambios (así como la creación de un usuario para acceder a la base de datos como se verá más adelante) son necesarios porque www-pgsql establece necesariamente conexiones a través de sockets TCP/IP. Lo hace aunque la conexión se realice con el propio ordenador local (con el que podría establecer conexiones a través de sockets en el dominio UNIX). Es posible modificar las fuentes del programa para cambiar esto, pero supondremos que el usuario dispone del programa original sin ningún tipo de modificaciones.

4. Ejemplo de un proyecto

Vistas ya todas las herramientas que vamos a utilizar, vamos a ver ahora el problema concreto sobre el que se van a aplicar para demostrar su uso.

El proyecto que se va a abordar es la creación de una Asociación de Antiguos Alumnos en Internet, el objetivo es que, a través de un cliente universal (un navegador de la WWW) se pueda acceder a una base de datos de información de Antiguos Alumnos de una determinada organización (instituto, escuela o universidad). Desde el servidor debe ser posible que las personas den de alta su información personal y que puedan consultar la información de personas de la asociación a través de formularios creados al efecto.

Para asentar más el problema, vamos a indicar que el objetivo de dicha asociación va a ser el de poder mantener en contacto a personas independientemente de su situación personal actual (trabajo), de forma que una persona que esté buscando a otra que pertenezca a la asociación, pueda hacerlo de una forma rápida. De esta manera se pueden perpetuar los lazos de comunicación existentes entre las personas antes de abandonar la organización, pero trasladándolos a un nuevo medio (correo electrónico e Internet).

En primer lugar vamos a abordar la parte esencial de este proyecto, evidentemente, si se estuviera diseñando este proyecto se deberían plantear objetivos posteriores a éste, tales serían, por ejemplo, la creación de un tablón de anuncios para fomentar la comunicación entre asociados o la generación de una lista de correo para la comunicación hacia todos los asociados de una forma directa. Vamos a centrarnos, sin embargo en la primera parte del proyecto.

5. Esquema entidad relación

A la hora de concretar la base de datos que va a necesitar nuestro proyecto es necesario hacer uso de una serie de metodologías para poder convertir la idea que tenemos del mismo en tablas que vayan a ser almacenadas en la base de datos.

El paso del concepto abstracto que se tiene del proyecto a la concreción de los elementos físicos (tablas) que maneja una base de datos no es, ni mucho menos, un paso inmediato y ni siquiera lleva siempre a la misma solución. Perspectivas distintas y distintos objetivos en la aplicación llevarán a desarrollar distintas tablas.

Sin embargo es necesario partir de un diagrama concreto, conocido como de entidad-relación que nos permite concretar la "idea del mundo" de nuestra aplicación. El diseño de estos diagramas hace necesario conocer cierta teoría de las bases de datos y tener cierta experiencia en su manejo. No se va aquí a explicar los pasos dados hasta llegar a él sino que se va a explicar el elegido, y que se muestra en la figura 5:

********************** FIGURA 5 ****************************

Este diseño lo materializamos en cinco tablas que serán las creadas dentro de la base de datos, como veremos más abajo.

6. Creación de la base de datos

Una vez definido el esquema entidad relación vamos a crear la base de datos en nuestro sistema de bases de datos. Primero, vamos a proceder a crear dos usuarios para poder gestionar la base de datos, en primer lugar el usuario alumni que será el "dueño" de la base de datos de nuestro proyecto, y por otro lado un usuarioque será utilizado para acceder a los datos. Para acceder a los datos podríamos utilizar el usuario www-data, que es el usado por defecto por el interfaz www-pgsql, pero es necesario tener en cuenta a la hora de crearlo y otorgar permismos que es necesario encerrarlo entre comillas (debido al uso del carácter '-' en el nombre). También podemos utilizar, si nos es más conveniente, el usuario nobody, los ejemplos aquí serán con éste último.

Es necesario crear el usuario 'alumni' dentro de nuestro sistema, ya que, además de ser el que administre la base de datos será también en su directorio de usuario (/home/alumni/public_html) donde vamos a alojar sus páginas (para que sean accesibles como http://miservidor/~alumni). Lo haremos de la forma habitual (esto es, con adduser) aunque convendría dejarlo, de momento con la contraseña bloqueada.

Para terminar con la asignación de privilegios , tenemos que dar acceso a estos usuarios a la base de datos. Para ello tenemos que "convertirnos" en usuario postgres, que es el responsable de dar de alta usuarios dentro del sistema de base de datos: haremos (como superusuario) su - postgres y crearemos tanto los usuarios como la base de datos que van a utilizar, que no será más que un directorio (dentro de /var/postgres/data/base). Un ejemplo de la sesión la tenemos en el listado 1.

Conviene distinguir, llegados a este punto, que los usuarios de la base de datos no han de existir necesariamente como usuarios de nuestro sistema, ya que a la hora de conectar con ésta utilizaremos un nombre de usuario determinado. Sin embargo, por simplicidad, aquí se van a usar los mismos usuarios en nuestro sistema operativo y en el gestor de bases de datos.

********************** LISTADO 1 ***************************

Una vez creados los usuarios podemos "convertirnos" en usuario alumni (con su - alumni como superusuario) y crear las tablas en la base de datos. Para ello nos conectaremos, bien vía el interfaz de línea de comandos psql o mediante el interfaz gráfico pgaccess (ver Figura 6). Dado que el interfaz de texto es más ilustrativo para el administrador es el que vamos a tratar aquí. Las órdenes SQL para crear las tablas las tenemos en el listado 3, para ejecutarlas, sólo tendremos que conectarnos a la base de datos con psql alumni y ejecutarlas tal cual están escritas allí (teniendo en cuenta sólo que tras mandar una orden SQL hay que terminarla con el carácter ';').

********************** FIGURA 6 *******************************

********************* LISTADO 3 ****************************

Lo único que quedará tras crear las tablas es dar los permisos al usuario nobody para que pueda acceder a éstas, lo hacemos con la siguiente orden SQL: grant select on empresa, persona, trabaja_en, usa_mail, usa_tfo to nobody. Una vez hecho esto podríamos ver los permisos actuales con \z.

******************** FIGURA 7 ********************

En general, se pueden ver todas las órdenes que podemos enviar desde el interfaz con \h y todas las órdenes administrativas importantes (listar tablas, permisos, usuarios...) las vemos con \?. Conviene acudir a la página de manual (man psql) para conocer más sobre esta herramienta y a la documentación de PostgreSQL (en Debian GNU/Linux se instala con el paquete postgresql-doc) en /usr/doc/postgresql.

7. Resumen

En este artículo se ha abordado el concepto de interfaz entre la base de datos y el servidor de WWW que es el que nos va a permitir, más adelante, enlazar, a través de la programación en páginas HTML, el interfaz del usuario con la base de datos. Ya hemos creado nuestra base de datos de ejemplo con el que trabajaremos en el siguiente artículo, lo único que nos falta es crear el interfaz vía WWW sobre el que se va a construir la aplicación final.

8. Sumarios

¿Qué actúa de unión entre el servidor y la base de datos?.

Por su sencillez, escogemos www-sql como alternativa.

Es necesario modificar Apache y PostgreSQL para preparar el interfaz.

Se va a abordar un ejemplo concreto.

La definición del esquema entidad relación es necesaria.

Se van a crear tablas en función del esquema.

Necesitamos crear la base de datos y los usuarios.

Las conexiones a la base de datos la hacemos como el usuario creado.

Psql es la manera más ilustrativa de modificar la base de datos.

Sólo falta crear el interfaz WWW.

9. Listados

LISTADO 1-

postgres@fuego:~$ createuser alumni
Enter user's postgres ID or RETURN to use unix user ID: 1013 -> 
Is user "alumni" allowed to create databases (y/n) y
Is user "alumni" a superuser? (y/n) n
createuser: alumno was successfully added
postgres@fuego:~$ createuser nobody
Enter user's postgres ID or RETURN to use unix user ID: 65534 -> 
Is user "nobody" allowed to create databases (y/n) n
Is user "nobody" a superuser? (y/n) n
createuser: nobody was successfully added
Shall I create a database for "nobody" (y/n) n
don't forget to create a database for nobody
postgres@fuego:~$ createdb alumni

PIE LISTADO 1: Creación de los usuarios y de la base de datos

LISTADO 2

En general los lenguajes de interfaz a los sistemas de base de datos vía web podremos encontrarlos incorporados a nuestra distribución favorita, los paquetes relacionados en Debian GNU/Linux se indican a continuación, pero si no dispone de ellos en su distribución puede acudir a lista más abajo para recoger las fuentes e instalarlas en su sistema.

PIE LISTADO 2: Información de los lenguajes de interfaz WWW-BD

LISTADO 3-

create table empresa 
( idempresa             int not null,
  nombre                text not null,
  ciudad                text,
  calle                 text,
  pais                  text,
  codigo_postal         int,
  actividad             text,
  num_empleados         int,
  pagina_www            text,
  primary key (idempresa)
)


create table persona
( dni                   int not null,
  nombre                text,
  apellidos             text,
  calle                 text,
  ciudad                text,
  codigo_postal         int,
  pais                  text,
  graduacion            int,
  ingreso               int,
  fecha_nacimiento      date,
  pagina_personal       text,
  primary key (dni)
)

create table trabaja_en 
( dni                   int not null,
  idempresa             int not null,
  puesto                text,
  departamento          text,
  primary key (dni, idempresa)
)

create table usa_mail
( dni                   int not null,
  e_mail                text not null,
  primary key (dni, e_mail)
)

create table usa_tfo
( dni                   int not null,
  telefono              text not null,
  primary key (dni, telefono)
)

PIE LISTADO 3: Tablas a crear en la base de datos

10. Capturas

11. Notas de maquetación

Dado que en este artículo tiene muchos listados y capturas quizás el texto no llegue, por sí sólo, a las cuatro páginas previstas, pero se considera fundamental incluir todas las gráficas ya que el texto tiene muchas referencias a ellos.

Caso de ser necesario el orden de preferencia es el que sigue: figura 6, figura 3, figura 1, figura 7, figura 2. El resto (capturas y listados) conviene no quitarles porque se perdería demasiada información.

12. Notas de coordinación

El siguiente artículo quizás sea más largo de lo que he planteado pero aún no lo tengo decidido así que quizás me haga falta un artículo más para cerrar la serie. Cuando haya escrito el siguiente ya lo diré.