Página principal
Artículos y trucos
Catálogo de productos
Ejemplos y descargas
Mis libros
Cursos de formación
Investigación y desarrollo
Libros recomendados
Mis páginas favoritas
Acerca del autor
 
En colaboración con Amazon
 
Intuitive Sight

Escogiendo un servidor

Quiero dejar claro un punto importante: no me considero un "gurú" de los servidores de bases de datos. Tengo cierta experiencia trabajando con determinados servidores, sobre todo desde el punto de vista del programador más que como administrador. Creo, no obstante, que estoy en condiciones de evaluar los aspectos de los servidores SQL más comunes que más afectan a los desarrolladores de aplicaciones. Quizás no conozca determinada instrucción de determinado servidor que sirva para resolver aquel "gran problema" que a determinado programador está empujando al manicomio. Pero de lo que se trata es de evitar llegar hasta dichos extremos. Terminado el sermón, ahí van mis consejos.

Los servidores que voy a analizar son aquellos con los que tengo más experiencia. Por supuesto, también me referiré de pasada a versiones anteriores.

Tenía dos alternativas para organizar este artículo: definir áreas de evaluación y ver cómo se comportan los distintos servidores, o analizar cada servidor mencionando sus aspectos positivos y negativos. Me he decidido por la última, pues al analizar por áreas puedes perder de vista el contexto en que se implementa o se deja de implementar alguna característica. Y la última advertencia: el orden de evaluación no implica preferencias personales (o casi).

INTERBASE

Es el servidor más asequible de todos, sobre todo para los programadores de Delphi, C++ Builder y JBuilder. Es el más barato de los cuatro que analizo aquí. Además existe una versión gratuita para Linux. InterBase es multiplataforma: existen versiones para Windows 9x, Windows NT, HP-UX, Solaris, Netware, SCO, Linux, etc, etc. Puede comprobar en www.interbase.com la versión actual de cada una de las plataformas soportadas.

La principal baza de InterBase es la Arquitectura Multigeneracional. Casi todos los restantes sistemas de bases de datos, cuando leen un registro durante una transacción, colocan un bloqueo de lectura sobre el mismo. De este modo, cualquier otro proceso concurrente puede también leer el registro, pero no modificarlo. Si se produce este conflicto, la aplicación que llega más tarde tiene que esperar a que la otra termine. InterBase, sin embargo, resuelve esta situación creando versiones del registro que se modifica. Así, las transacciones de lectura pueden alcanzar la máxima coherencia sin afectar a las transacciones de escritura. En situaciones de mucho jaleo, esta característica es incluso más importante que las cifras "crudas" de rapidez de localización, lectura y modificación.

Otro de sus puntos fuertes es su lenguaje SQL y de extensiones procedimentales. InterBase es uno de los pocos sistemas que implementan todas las acciones referenciales establecidas por el estándar ANSI. Dicho en cristiano: al definir una restricción de integridad referencial (foreign key) podemos indicar que al eliminar una fila maestra se eliminen todas las filas de detalles asociadas (on delete cascade) o que, alternativamente, se prohiba la operación si existen dichas filas (on delete no action); el objetivo de ambas opciones, por supuesto, es evitar la aparición de referencias "huérfanas", a filas inexistentes. Usted dirá: "sí, pero eso también lo hace Oracle (o el sistema que sea)". Es cierto, pero no todos los sistemas permiten actualmente especificar on update cascade, para propagar en cascada las modificaciones realizadas sobre la clave primaria de la tabla maestra. Además, se pueden especificar las opciones adicionales on delete set default, on delete set null, y las correspondientes para on update.

El lenguaje de restricciones check es muy potente. Las cláusulas check pueden incluir expresiones con subconsultas, algo que solamente permite DB2 además de InterBase (hasta donde conozco). En el resto de los sistemas, una restricción de este tipo nos forzaría a programar un trigger.

¿Y qué tal los triggers? InterBase soporte triggers que se disparan para cada fila independientemente, antes y después de la operación. Y se pueden especificar varios triggers por evento. La ejecución de un trigger, además, se trata atómicamente. Si ocurre un error durante la ejecución de un trigger se deshacen todos los cambios realizados por la operación inicial que desencadenó el trigger. Lo mismo sucede con los procedimientos almacenados que, dicho sea de paso, permiten programar procedimientos de selección para devolver conjuntos de datos.

El gran defecto de InterBase, desde mi punto de vista, es la falta de un potente mecanismo de particiones. Es cierto que una base de datos puede distribuirse en varios ficheros, que pueden ubicarse en diferentes discos del mismo ordenador, pero no tenemos control alguno (al menos por el momento) de dónde se almacena cada tabla o índice. Tampoco existen muchas posibilidades en la elección del almacenamiento de tablas, o en la implementación de índices.

Otro defecto importante tiene que ver con el conjunto de funciones escalares predefinidas: creo que en total sólo hay tres o cuatro de estas funciones. Claro, se pueden definir funciones en módulos dinámicos, y registrarlas para que el servidor puede utilizarlas como funciones definidas por el usuario (UDF). Pero el uso de estas funciones nos obliga a elegir "para siempre" un sistema operativo: si queremos pasar desde Windows NT a algún UNIX, probablemente necesitemos recompilar o reprogramar completamente nuestras bibliotecas de funciones. Y si pasamos a NetWare peor, pues en este sistema operativo InterBase no permite el uso de funciones de usuario.

Y si seguimos mencionando cosas que faltan, llegamos a las opciones de replicación. No hay replicación predefinida. Pero, ¿cuán importante es esta carencia? Algunos utilizan la replicación para proteger físicamente los datos. En este caso, InterBase ofrece una variante más sencilla: el uso de shadows que duplican los cambios en una base de datos en otro disco del mismo ordenador. Otro uso de la replicación está relacionado con el soporte para aplicaciones de tomas de decisión. Este tipo de aplicaciones necesita transacciones serializables para mayor coherencia, y ya sabemos que este nivel de aislamiento se logra en otros sistemas mediante bloqueos compartidos, afectando el rendimiento de las transacciones OLTP. La solución habitual es ejecutar estas aplicaciones sobre una réplica de la base de datos. En InterBase no hay que llegar a estos extremos, pues la arquitectura multigeneracional resuelve el conflicto entre lectores y escritores. De todos modos, no es difícil implementar la replicación mediante programa, y es muy posible que próximas versiones de InterBase ya traigan alguna solución preparada.

Regresar

ORACLE

Agarre el nombre del producto como si se tratase de un calcetín y déle la vuelta: Oracle==elcarO. Pero es tan bueno como costoso, a diferencia de otros productos que son caros por puro vicio. Oracle es un producto con muchos años en el mercado, y eso se nota. Si es justificable algún curso de administración de bases de datos, ese es el de Oracle, pues las opciones de configuración abundan más que las pulgas sobre un perro flaco.

Yo no puedo hablarle acerca de qué tal va un Oracle multiservidor con opciones paralelas, porque no tengo ese hardware. Pero sí he probado a optimizar una base de datos en un servidor con varios discos ... y vaya si se nota la diferencia con respecto a una base de datos con opciones por omisión. Ahí es donde está el problema: si usted no está dispuesto a invertir tiempo y materia gris en estudiar cómo se configura correctamente un Oracle, no malgaste su dinero y quédese con un InterBase. En caso contrario, resígnese a tener pesadillas con particiones, espacios de índices y tablas, índices hash, índices por bits, índices con claves invertidas, tablas organizadas por medio de índices, tablas relacionadas mediante clusters, y todo lo demás.

El lenguaje SQL soportado por Oracle, denominado PL/SQL, es muy completo. Permite la expresión de consultas recursivas (cláusulas start with/connect by), y soporta un número grande de funciones escalares. Los triggers son tanto a nivel de filas como de instrucciones, y se disparan antes y después. Su ejecución es también atómica, lo cual facilita su programación. La presencia de cláusulas when y update of los hacen incluso más fáciles de escribir que en InterBase. Se pueden utilizar explícitamente cursores en los triggers y procedimientos almacenados (InterBase sólo los permite implícitamente en la instrucción for). Por último, podemos utilizar paquetes para definir nuevos tipos de datos, y para crear variables globales para cada conexión cliente.

Y están las recientes extensiones de objetos. Se pueden definir clases, que encapsularán datos y métodos, aunque todavía no puede utilizarse la herencia y no existe la posibilidad de esconder información. Se pueden crear columnas de tipo objeto, se permite incluso crear tablas basadas en una clase, y se admite el uso de referencias a objetos, como si se tratase de punteros. A esto se le añaden los nuevos tipos como tablas anidadas y arrays. Puede que en un par de años la forma de programar aplicaciones de bases de datos sea radicalmente diferente gracias a la Programación Orientada a Objetos. Pero ese momento, desgraciadamente, aún no ha llegado.

¿Alguna pega a Oracle? La implementación actual de las transacciones con lecturas repetibles del BDE requiere que estas transacciones sean sólo lectura. No sé si se trata de una limitación intrínseca de Oracle o una de las tonterías habituales del BDE. También hay problemas con el uso de campos LOB (imágenes, documentos, etc) y las transacciones implícitas.

Regresar

MICROSOFT SQL SERVER

En el Mundo Medio de Tolkien habitaban hombres, elfos, enanos, gigantes y hobbits. Los hobbits eran los "medianos". De MS SQL Server se puede decir que es un hobbit. No es el más rápido, no es el más barato, no es el más elegante ... pero es el más popular.

La arquitectura física de la versión 6.5 no era mala ... era pésima. Bloqueos a nivel de página (para las actualizaciones), ficheros de datos y de transacciones que no crecían automáticamente, páginas fijas de 2048 bytes... Todo esto ha mejorado en la versión 7. En vez de seguir utilizando el concepto de device para el almacenamiento físico (herencia de Sybase), en la nueva versión los datos se almacenan directamente en ficheros físicos. Es muy fácil definir grupos de ficheros, asignar tablas e índices a estos grupos, e implementar particiones. Antes había que definir segmentos y asignar las tablas a estos segmentos mediante procedimientos almacenados. Ya se permiten bloqueos a nivel de fila. Y las técnicas de replicación implementadas son muy potentes. El mayor inconveniente de SQL Server es que el servidor solamente se puede ejecutar en Windows (NT, 95, 98).

Un punto a favor de SQL Server es la posibilidad de activar la seguridad integrada con NT. Cuando esta opción está activa, el usuario solamente tiene que autentificar su identidad al entrar en el sistema operativo. De ahí en adelante, SQL Server identifica al usuario y lo asocia con uno de sus logins internos.

Mis principales críticas a este sistema vienen del lado de la programación SQL. Por ejemplo, una importantísima limitación de SQL Server: no se soportan acciones referenciales declarativas. Es decir, no se pueden especificar borrados o actualizaciones en cascada para las relaciones de integridad referencial. Unamos esto a las restricciones que impone su obsoleto sistema de triggers.

He aquí algunos de los pecados de Transact SQL:

  • Los triggers son siempre a nivel de instrucción, no de fila.
  • Los triggers, además se ejecutan siempre después de la instrucción, no antes.
  • Dentro de un trigger o de un procedimiento almacenado se puede ejecutar un rollback de una transacción.
  • En realidad, el punto 3 se debe a que las acciones de los triggers no son atómicas, que es lo que debería ser.

Hasta el momento, el BDE accede a SQL Server por medio de la interfaz de programación DBLibrary. Se espera que Borland sustituya en breve este método de acceso por ADO, que según comentan las malas lenguas, va mucho más rápido. Mientras tanto, sepa usted que cada tabla o consulta abierta en un cliente, tiene que implementarse mediante una conexión separada al servidor. Esta política trae como consecuencia toda una serie de problemas que no voy a tratar aquí.

Regresar

DB2

DB2 es un producto de IBM, y eso ya lo dice todo. Alta tecnología, elegancia en la implementación, precios elevados ...y pifias inexplicables. En lo que respecta a la arquitectura física, DB2 es de esos sistemas que permiten configurar hasta el más mínimo detalle. Casi todo lo que he dicho acerca de Oracle, es también aplicable a DB2. Existen versiones de DB2 para muchas plataformas.

Este sistema incorpora extensiones curiosas a SQL. Por ejemplo, es interesante (y elegante) la forma de plantear consultas recursivas. DB2 tiene triggers a nivel de fila y de instrucción, de ejecución previa y posterior. Además son atómicos. Eso sí, las instrucciones que permiten ejecutar están bastante limitadas, pues no existen condicionales, bucles y tonterías similares. Esto nos fuerza a hacer actos de magia con la cláusula when de la cabecera del trigger, y a aprendernos trucos sucios y extensiones propietarias de update, insert y demás. Nada grave o irresoluble, sin embargo.

La gran pifia de DB2: ¿necesita un procedimiento almacenado? ¡Escríbalo en C, o en cualquier otro lenguaje externo que pueda comunicarse con DB2! Vale, pero como el servidor puede ejecutarse en OS/2, Windows NT, AIX, etc, olvídese de DB2 si quiere distribuir su aplicación en empresas que tengan el producto instalado. En caso contrario, tendrá que experimentar con los compiladores de C de todos los sistemas operativos posibles. No es imposible, pero sí demasiado trabajoso. Además, C, Java, Visual Basic, o el lenguaje en que se programe el procedimiento, son lenguajes de "bajo nivel" en comparación con SQL. Lo que podemos hacer en tres líneas de SQL requiere 18 en C++.

Regresar