GDBMS

  1. Introducción

  2. Parseado

  3. Extensibilidad

    1. Drivers

    2. Funciones

    3. Tipos

  1. Ejecución de consultas



1.- Introducción

GDBMS es una librería de acceso a datos extensible que permite la ejecución de un subconjunto del estándar SQL sobre fuentes de datos heterogéneas. Esto quiere decir que se puede realizar una instrucción SQL que involucre tablas que residan en servidores de base de datos distintos, o incluso entre una tabla de un servidor remoto y un fichero en local.

2.- Procesado de instrucciones

Para ejecutar las instrucciones primero hay que analizarlas sintácticamente. Esto se realiza con la librería javacc usando la gramática sql.html, lo cual nos genera un árbol sintáctico asociado a la instrucción y es en esta primera fase donde se detectan los errores sintácticos.

Una vez obtenido el árbol sintáctico, se obtiene un arbol de adaptadores de forma paralela en la que cada nodo de dicho árbol se basa en la información del nodo correspondiente del árbol sintáctico para proporcionar información de más alto nivel. Cada nodo del árbol de adaptadores tiene un nodo correspondiente en el arbol sintáctico, sin embargo, no sucede al revés. Un nodo del árbol sintáctico no tiene por qué tener una correspondencia con un nodo del de adaptadores. Lo que quiere decir esto es que un nodo adaptador puede representar un nodo sintáctico o un subárbol sintáctico. Durante la ejecución de las instrucciones, se puede pedir información a dicho árbol tal como el valor de una expresión para una determinada fila. En este caso, asociado a al nodo del árbol sintáctico (nodo sintáctico desde ahora) que representa la expresión habrá un nodo adaptador que en base a los valores de los nodos sintácticos devolverá el valor de la expresión para la fila que se está evaluando.

3.- Extensibilidad

Hay varios puntos en los que se puede extender a gdbms

3.1.- Drivers

La fuente de datos sobre la que opera gdbms es un DataSource, que es una clase que proporciona acceso a los datos que representa y permite algunas operaciones adicionales como acceder a los campos por nombre, etc. Además existen DataSource que son producto de operaciones, es decir, una join entre dos DataSource es otro DataSource. Las DataSouce's usan a los drivers para acceder a los datos.

Se pueden crear drivers para leer información de ficheros de disco y para acceder a tablas de bases de datos. El acceso a estas últimas se realiza mediante JDBC por lo que se puede acceder actualmente a cualquier sistema de base de datos para el cual exista un driver JDBC.

Para crear un DataSource en gdbms tenemos varias alternativas. Todas ellas vienen definidas por la clase DataSourceFactory, que proporciona varios métodos para obtener los DataSource.

Si la información se encuentra en un fichero o en una base de datos podemos añadir la fuente de datos al sistema mediante las llamadas addXXXDataSource y luego obtener los DataSource asociado mediante la llamada createRandomDataSource(String sql). De ésta última llamada, podemos deducir que las fuentes de datos de base de datos no tienen por qué corresponderse con una tabla completa y pueden ser una consulta sobre una tabla que recupere un subconjunto de los campos y de los registros. Cabe destacar que en estos métodos estamos indicando datos que definen la fuente de datos (ubicación del fichero, nombres de las columnas, etc...) por lo que si se cambia esta información seguramente no se podrá obtener un DataSource asociado al origen de los datos.

Además de los drivers de fichero y de base de datos, existen unas interfaces que al ser implementadas permiten a la factoría crear DataSource. Esto es fundamental para integrar gdbms en otros sistemas como por ejemplo gvSIG, en la que hay objetos que han leido la información alfanumérica y se quiere obtener un DataSource que acceda a estos datos.

Si la información se encuentra en un objeto que ya contiene la información por estar en un framework de otro sistema y simplemente se quiere tener un DataSource con la información de dicho objeto, se deberá usar la llamada addDataSource(ReadDriver rd, String dataSourceName) y que dicho objeto implemente la interfaz ReadDriver.

3.2.- Funciones

3.3.- Tipos

4.- Ejecución de consultas

La ejecución de una instrucción SQL puede ser delegada en un servidor de base de datos, con el ahorro temporal de la ejecución, si los DataSource's implicados cumple que son del mismo servidor y son accedidas con el mismo usuario y password y están registrados de una determinada manera. En caso de encontrarse una SQL que cumpla la condición anterior se deberá de sustituir los nombres de los datasource por los nombres de las tablas a las que acceden y al final de la cláusula where habría que añadir con AND las condiciones where de los datasource. Una vez realizado eso se podría delegar en el servidor dicha instrucción.

Las condiciones para delegar la ejecución en el servidor son:

Por otro lado cabe resaltar varios inconvenientes que presenta el hecho de que se delegue en el servidor la ejecución. El primero es que las referencias a campos de la tabla deben ser cualificadas, ya que de lo contrario se debería de hacer peticiones adicionales al servidor con la finalidad de saber a qué tabla pertenece cada campo. El segundo es el coste temporal de ejecutar una consulta sobre varias tablas sin que ésta se delegue en el servidor. Por una parte hay que traerse del servidor las tablas implicadas que no tiene por qué estar en la máquina local (de hecho es lógico que no sea así) y por la otra, una vez los datos han sido descargados se deberá de realizar la operación en Java que no destaca por la velocidad de ejecución. Es por esto que si se quiere realizar una operación con tablas que residan en el mismo servidor, conviene añadir una nueva fuente de datos indicando la consulta SQL que la define. De esta manera nos aseguramos de que la ejecución se realiza en el servidor.

En caso de que no se pueda delegar la ejecución en ningún servidor el resultado se computa en el núcleo de gdbms mediante una serie de decoradores que se ponen sobre los DataSouce's involucrados en la instrucción. Estos decoradores implementan la interfaz DataSouce por lo que el resultado de la operación es también un DataSouce. Para una ejecución más eficiente se simplifica el arbol de adaptadores. Durante la ejecución de una instrucción, se procesa el subárbol de expresiones múltiples veces para evaluarla, es por esto que la simplificación de este árbol aporta una aceleración del procesado de las instrucciones. Para simplificar el árbol el proceso realizado consiste en recorrer el subárbol de expresiones y para cada expresión que sólo tenga como hijo una subexpresión y no realice ninguna operación sobre el resultado de la expresión anterior, se hace un bypass del padre a ese único hijo, eliminándose el nodo en proceso. Los nodos susceptibles de desaparecer son los siguientes: