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 intro­ ducir 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. 11.. IInnttrroodduucccciióónn aa eessttee aarrttííccuulloo 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. 22.. AAcccceessoo aa bbaasseess ddee ddaattooss mmeeddiiaannttee WWWWWW 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 _a_p_p_l_e_t 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 _a_d _h_o_c 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 _A_W_T o _S_w_i_n_g), 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 _t_a_g_s 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: · mod_perl. Se trata de un módulo para Apache que permite introducir código Perl (_P_r_a_c_t_i_c_a_l _E_x_t_r_a_c_t_i_o_n _a_n_d _R_e_p_o_r_t _L_a_n_g_u_a_g_e) en las páginas, de forma que se pueda obtener un comportamiento dinámico. Asímismo, permite acelerar la ejecución de CGI's ya escritos en Perl entre un 400% y un 2000%, ya que, al introducirlo el Apache, desaparece la sobrecarga de inicialización del intérprete (que siempre estará cargado). Usando Perl, junto con el módulo DBI, podemos acceder, de forma transparente, a cualquier base de datos. Este mecanismo se usa en múltiples servidores "activos" como . · PHP/FI (_H_y_p_e_r_t_e_x_t _P_r_e_p_r_o_c_e_s_s_o_r, antes _P_e_r_s_o_n_a_l _H_o_m_e_P_a_g_e). Se trata de un lenguaje de programación que puede introducirse dentro de páginas HTML, con una sintaxis parecida a C, y funciones similares a las que realiza el lenguaje ASP para el Servidor de Información de Microsoft, pero se trata de una implementación libre y, por tanto, mucho más abierta. PHP/FI pasó de ser una aplicación para construir páginas personales (con contadores y elementos parecidos) a utilizarse en gran número de servidores profesionales. Este lenguaje soporta la comunicación con bases de datos, y está disponible tanto como CGI independiente como módulo en Apache. Soporta las bases PostgreSQL, MySQL y msql. · www-sql. Es un sencillo lenguaje para introducir consultas SQL en páginas HTML, de forma que éstas sean preprocesadas por un programa antes de enviar la página al cliente. Actualmente sólo tiene soporte para las bases de datos PostgreSQL y MySQL. 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). 33.. IInnssttaallaacciióónn ddee wwwwww--ppggssqqll 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 _s_c_r_i_p_t 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 _l_o_c_a_l_h_o_s_t (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 (_p_o_s_t_m_a_s_t_e_r). 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. 44.. EEjjeemmpplloo ddee uunn pprrooyyeeccttoo 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. 55.. EEssqquueemmaa eennttiiddaadd rreellaacciióónn 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 _e_n_t_i_d_a_d_-_r_e_l_a_c_i_ó_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 **************************** · Entidades: · Persona. Se trata del objeto principal de la base de datos y almacena la información personal característica de un individuo. Tiene como atributos la información de la dirección de esta persona (calle, ciudad, país, código postal) y la personal (nombre, apellido, dni/pasaporte, fecha de nacimiento). Se le añade un atributo específico para la base de datos que es la promoción (o año de salida de la organización). Como atributo unívoco de dicha base de datos, y que servirá para identificar a los individuos se va a escoger el número de identidad (o dni), siendo éste la clave primaria. · Teléfono. Se trata de un objeto secundario, con un único atributo, el número de teléfono (que en realidad podría partirse en prefijo internacional/prefijo nacional, pero que dejamos así por simplicidad). · Correo electrónico. Otro objeto secundario con un único atributo, la dirección de correo. · Empresa. Se trata de la caracterización de los lugares de trabajo de las personas, se compone de los siguientes atributos: nombre, dirección de la empresa (calle, ciudad, país y código postal), actividad o sector en el que se desarrolla la empresa, y número de empleados. Como característica única escogeremos el nombre de la misma, de tal forma que no podrá haber en la base de datos dos empresas con el mismo nombre. · Relaciones: · Trabaja en. Se trata de una relación entre personas y empresas, que determina que una determinada persona tiene un determinado puesto en una empresa, por ello como característica de dicha relación tenemos el atributo 'puesto'. Este diseño lo materializamos en cinco tablas que serán las creadas dentro de la base de datos, como veremos más abajo. 66.. CCrreeaacciióónn ddee llaa bbaassee ddee ddaattooss 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 _a_l_u_m_n_i 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 _w_w_w_-_d_a_t_a, 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 _n_o_b_o_d_y, 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 _p_o_s_t_g_r_e_s, 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 _a_l_u_m_n_i (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 _n_o_b_o_d_y 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. 77.. RReessuummeenn 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. 88.. SSuummaarriiooss ¿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. 99.. LLiissttaaddooss 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. · Paquetes relacionados con www-sql: · www-mysql: La interfaz a la base de datos MySQL. · www-pgsql: La interfaz a la base de datos PostrgreSQL. · Paquetes relacionados con el módulo de perl de Apache: · libapache-mod-perl: El módulo de Perl para Apache, puede ser utilizado para introducir código en páginas HTML junto con libhtml- embperl-perl ó libhtml-ep-eperl. · libapache-dbi-perl: Módulo que se puede usar junto con un intérprete de Perl embebido para acceder transparentemente a bases de datos utilizando Perl::DBI. · libapache-asp-perl: el sistema ASP (Active Server Pages) migrado a Apache y con soporte de Perl. · libapache-dbilogger-perl: módulo de Apache para poder seguir las transferencias a través de los accesos DBI. · Paquetes relacionados con PHP y conectividad a bases de datos: · php3-cgi: ofrece un ejecutable independiente que se puede comportar como un CGI para procesar páginas, y usar conjuntamente con diversas ampliaciones para conectarse a distintas bases de datos: php3-cgi-msql, php3-cgi-mysql, y php3-cgi-pgsql. · php3: módulos para Apache de PHP, se puede utilizar conjuntamente con php3-mysql, php3-pgsql y php3-msql. · www-sql. Se puede leer más información en , y lo podemos descargar de , si no disponemos de un paquete disponible en nuestra distribución favorita. · Para conocer más sobre la integración de Perl y Apache, la mejor fuente de información es · Para conocer más sobre PHP, debemos acudir a , si lo que se desea es descargarlo, ir directamente a . 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 1100.. CCaappttuurraass · Figura 1 (enlacebd.png) Pie: Falta un componente entre la base de datos y el servidor de WWW. · Figura 2 (enlacebd2.png) Pie: Aplicación en el lado del servidor. · Figura 3 (enlacebd3.png) Pie: Aplicación en el lado del cliente. · Figura 4 (acceso.png) Pie: Pasos del método de acceso a la base de datos · Figura 5 (entidadrel.png) Pie: Esquema entidad relación del proyecto- · Figura 6 (creagrafico.png) Pie: Creación de las tablas de forma gráfica. · Figura 7 (psql.png) Pie: El interfaz de texto de PostgreSQL 1111.. NNoottaass ddee mmaaqquueettaacciióónn 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 _f_u_n_d_a_m_e_n_t_a_l 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. 1122.. NNoottaass ddee ccoooorrddiinnaacciióónn 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é.