Página inicial | Presentación


CADENA DE TABLAS RELACIONADAS

Introducción

Descripción teórica

Cuando se define una Foreign Key en una tabla, por ejemplo cuando se pone una de sus columnas en relación con la clave primaria de otra tabla, se crea una relación 1:N entre la tabla con la clave primaria y aquella con la columna relacionada. Esto significa que a cada registro de la primera corresponden N registros de la segunda (con N>=0), y también que cada registro de la segunda se relaciona con uno y solo con un registro de la primera.

Por ejemplo, véase el siguiente esquema relacional extraído de Neptuno.mdb, la base de datos de ejemplo de Microsoft Access:

esquema relacional extraído de Neptuno.mdb

En la tabla Pedidos ha sido definida una Foreign Key sobre la columna IDCliente que la pone en relación con la clave primaria IDCliente de la tabla Clientes: esto significa que a cada cliente pueden corresponder más pedidos, mientras que cada pedido pertenece a uno y solo a un cliente.

Llamaremos tabla principal de la relación a la tabla a la cual pertenece la clave primaria, y tabla secundaria de la relación a la tabla en la cual ha sido definida la Foreign Key que hace referencia a tal clave primaria. En el ejemplo, Clientes es la tabla principal, y Pedidos es la tabla secundaria, con respecto a la relación que deriva de la Foreign Key definida entre las dos columnas IDCliente.

Por otra parte, como se puede ver en el ejemplo, una tabla que sea secundaria con respecto a una relación puede también ser primaria con respecto a otra. En efecto, en la tabla Detalles de Pedidos ha sido definida una Foreign Key sobre la columna IDPedido que la pone en relación con la clave primaria IDPedido de la tabla Pedidos, por lo cual a cada pedido pueden corresponder más detalles, mientras que cada detalle pertenece a uno y solo a un pedido. En tal caso, con respecto a esta relación Pedidos es la tabla principal, y Detalles de Pedidos es la secundaria.

Se ha creado de esta manera una cadena de tablas relacionadas (que se puede extender cuanto se quiera) en la cual cada tabla representa un nivel de un árbol N-ario que tiene como nodos los registros. Llamaremos tabla principal de la cadena a la única que no es secundaria con respecto a ninguna relación, es decir a la primera tabla, correspondiente al nivel 0 del árbol N-ario (en el ejemplo la tabla Clientes).

Implicación práctica

Tal situación no es nada difícil de encontrar: baste con pensar, además que en el mismo ejemplo visto, en la descripción de las partes de un sistema en el que cada parte puede ser a su vez constituida por subpartes. El problema principal en la implementación de la gestión de una cadena de tablas relacionadas deriva de la dificultad en el añadir nuevos datos cuando queramos unificar más niveles en una única operación de inserción.

Imaginémonos, por ejemplo, que un cliente realice un nuevo pedido para solicitar ciertos productos a determinadas condiciones. En una hipotética aplicación que estamos proyectando, hemos decidido que, después de haber seleccionado al cliente (que por simplicidad suponemos ya presente en la base de datos), tenemos que pulsar el botón Nuevo pedido para abrir un formulario en el cual insertar los datos del pedido. En el formulario hemos puesto el botón Nuevo detalle para añadir, uno por uno, los datos de los distintos detalles de este pedido. Después de haber añadido todos los detalles y haber rellenado el formulario, podemos guardar todo pulsando el botón Guardar Pedido.

Un proyecto pensado de esta manera parece bastante razonable, pero en el momento de implementarlo nos encontraríamos de frente a una dificultad: si los detalles se guardan en la base de datos sólo en el momento de guardar el pedido, ¿dónde se les memorizaría mientras?

Resulta evidente que es necesario definir una estructura auxiliar en la cual memorizar temporáneamente los datos de los detalles, y a la cual acceder en el momento de guardar el pedido en la base de datos.

El problema se complicaría si decidiéramos por ejemplo guardar más pedidos a la vez, en cuyo caso se tendría que desplazar el botón Guardar pedido al nivel del cliente, transformándolo en un botón Guardar pedidos que realice la grabación en la base de datos de los N nuevos pedidos insertados. Esta vez sería necesaria una estructura auxiliar de dos niveles que memorice temporáneamente cada pedido con los detalles correspondientes. Más niveles se quieran unificar, más compleja se volvería la gestión de la estructura auxiliar necesaria.

Implementación de la cadena

Las clases ExtendedODBCRecSet y ExtendedDaoRecSet amplían la funcionalidad de las clases de las que derivan (CBufferRecSet y CBufferDaoRecSet respectivamente) para poder representar el elemento intermedio de una cadena de recordset relacionados. Además de prever una estructura auxiliar para la gestión de un conjunto de registros a insertar sucesivamente en la base de datos, definen los estados en los que se puede encontrar un recordset intermedio debido a su interacción con los demás recordset de la cadena:

acceso directo
es el estado normal, que permite navegar entre los registros presentes en el recordset;
añadiendo
es el estado de inserción de registros, durante el cual se gestiona la estructura auxiliar que contiene los registros que se han añadido al recordset, pero que todavía no se han guardado en la base de datos;
grabando
es el estado en el que se encuentra el recordset mientras guarda en la base de datos los datos presentes en la estructura auxiliar;
fijo
es un estado de espera, necesario para garantizar la finalización de las operaciones que se estén ejecutando en otros recordset de la cadena;
editando
es el estado habitual en el que se tiene que encontrar un recordset para poder realizar la modificación del registro actual.

Para garantizar la consistencia de los datos, cada recordset intermedio se preocupa también de actualizar los recordset que lo siguen en la cadena. En general, las operaciones posibles en cada momento dependen del estado en el que se encuentra el recordset, y normalmente atañen al recordset como elemento de la cadena. Para operaciones globales, o sea las que conciernen a la cadena en su conjunto, se han definido las clases MainODBCRecSet y MainDaoRecSet, derivadas de ExtendedODBCRecSet y ExtendedDaoRecSet respectivamente, que representan al recordset principal de la cadena (es decir al elemento inicial). Tal recordset puede añadir un nuevo nivel al final de la cadena actual (AddNewLevel), ejecutar el Open de cualquier nivel de la cadena (GlobalOpen), realizar la grabación de la estructura auxiliar en la base de datos (Update), anular una operación pendiente (CancelUpdate), etc.

Demostración del funcionamiento

(Pasa inmediatamente al lanzamiento de la demostración)

Requisitos del sistema

Para poder ver una demostración de cómo se efectúa la gestión de una cadena de tablas relacionadas, tienes que tener instalada la versión española de Microsoft Access con la base de datos de ejemplo Neptuno.mdb. Es además necesario utilizar un navegador que permita descargar un control ActiveX y utilizarlo a través de JavaScript, por lo que si no tienes Microsoft Internet Explorer 4.0 o una versión posterior ¡será un intento muy difícil!

Fiabilidad del software

No teniendo la menor intención de pagar a una Certification Authority (una compañía encargada del otorgamiento de certificados digitales) para poder firmar mi software con un certificado considerado fiable, he creado mi propio certificado, y con ese he firmado el software necesario para la demostración.

La firma de un software garantiza que:

  1. si el software dice que ha sido firmado por la Organización X, puedes estar tranquilo de que ha sido verdaderamente firmado por la Organización X;
  2. a menos que el navegador indique lo contrario, puedes estar tranquilo también de que nadie ha manipulado el software desde el momento de la firma.

Cuando el certificado no ha sido emitido por una Certification Authority, no se sabe nada acerca de quien lo posee, por lo cual antes de ejecutar su software hay que decidir si se puede confiar en él o no (nunca se sabe, podría ser un malintencionado...). Pues, yo espero que tú confíes en mí, por lo menos porque te he avisado...

Si quieres echar un vistazo a mi certificado, lo puedes hacer eligiendo abrir el archivo (¡no guardarlo!) después de haber pinchado aquí. En él encontrarás, además de datos técnicos variados, informaciones sobre su emisor (yo) y sobre la validez del certificado.

Seguridad del software

La única cosa de la que te tengo que avisar, por lo que se refiere a la seguridad del software que se ejecutará durante la demostración, es que se establecerá un acceso directo a la base de datos Neptuno.mdb, lo que te permitirá modificar, añadir y borrar sus registros a tu discreción. Si de verdad quieres conservar los datos originales y no tienes la posibilidad de reinstalarlo, ¡te conviene hacer antes una copia de seguridad!

Ejecución de la demostración

Si es la primera vez que ejecutas esta demostración, te aconsejo que antes de nada busques en tu ordenador el fichero Neptuno.mdb. Si no existe, significa que no tienes instalada la base de datos de ejemplo de Microsoft Access (lo que es uno de los requisitos del sistema), por lo cual no podrás ejecutar la demostración (¡instálala antes de continuar!). Si sin embargo existe, acuérdate donde está, porque su posición te servirá para poder continuar.

Al lanzar la demostración, se abrirá una nueva ventana que intentará descargar e instalar un componente ActiveX. Según el nivel de seguridad configurado en tu navegador, te podrán aparecer unos mensajes de aviso contra el software que no se reconoce como de confianza. Eso pasa porque he firmado tal componente con un certificado que no ha sido otorgado por una Certification Authority (ver la sección Fiabilidad del software). Si quieres que se ejecute la demostración, tienes que dar las autorizaciones que se te pidan.

Ahora, suponiendo que el componente ActiveX se haya descargado e instalado correctamente (de lo contrario, quizá sea el navegador el que no cumpla los requisitos del sistema), aparecerá una ventana de diálogo, por medio de la cual permitirás al software localizar la base de datos Neptuno.mdb en tu ordenador (en relación a esto echa un vistazo a la sección Seguridad del software).

Siendo previstas dos diferentes modalidades para acceder a los datos de la base de datos (DAO y ODBC), consulta la siguiente tabla para elegir la modalidad que prefieras probar. Considera que de esta elección depende el tipo de ventana de diálogo que aparecerá al principio de la demostración, y la manera en la que el software accederá a la base de datos Neptuno.mdb, mientras que las operaciones posibles durante la demostración quedarán invariadas (para saber cuáles son, selecciona el icono de ayuda durante la demostración).

Una vez hayas decidido, no queda más que lanzar desde el fondo de la tabla la demostración que prefieras.

DAO
(Data Access Objects)
ODBC
(Open DataBase Connectivity)

El acceso a la base de datos se realizará directamente a través del motor de Microsoft Access (el Microsoft Jet Database Engine).

El acceso a la base de datos se realizará comunicando con un controlador que implementa para Microsoft Access el protocolo estándar ODBC.

Para que la comunicación pueda tener lugar, es necesario haber definido una conexión ODBC de tipo Microsoft Access a la base de datos Neptuno.mdb. Si tal conexión todavía no ha sido definida, la puedes crear bien ahora, eligiendo Fuentes de datos ODBC (32 bits) desde el Panel de Control, o bien después de haber lanzado la demostración, cuando la ventana de diálogo te pida el nombre de la conexión. Para ulteriores detalles, consulta la ayuda en línea en el momento de la creación.

Todo lo que tendrás que hacer cuando se abra la ventana de diálogo será sólo seleccionar la posición en tu ordenador donde se encuentra el archivo que contiene la base de datos (Neptuno.mdb).

Todo lo que tendrás que hacer cuando se abra la ventana de diálogo será sólo cambiar a la pestaña Origen de datos de equipo y seleccionar el nombre de la conexión a utilizar (si la conexión todavía no ha sido definida, este será el momento justo para hacerlo, eligiendo el botón Nueva...).

Lanza la demostración DAO Lanza la demostración ODBC

Test de velocidad

Utilizando las clases aquí definidas, se ha creado con Visual C++ un programa para acceder a la base de datos de ejemplo de Microsoft Access 97 (Neptuno.mdb), limitadamente a la cadena de tablas Clientes, Pedidos, Detalles de Pedidos. Han sido luego realizadas tres tipos de pruebas, cada una bien con el acceso de tipo DAO, bien con el acceso de tipo ODBC. Por interés estadístico, además de la versión Release se ha hecho casi siempre el test también sobre la versión Debug del programa.

El test ha sido realizado en un ordenador con microprocesador Pentium II MMX a 333 MHz, con 64 MB de memoria RAM.

Prueba n. 1

Se han insertado 10 clientes (tabla Clientes), con 10 pedidos cada cliente (tabla Pedidos), y 10 productos cada pedido (tabla Detalles de Pedidos), con un total de 1.110 registros.

DAO Release 2,470 1,370 1,320 1,320 seg (en media 1,620 seg)
Debug 3,790 3,020 3,020 3,020 seg (en media 3,213 seg)
ODBC Release 2,810 1,930 1,760 1,810 seg (en media 2,078 seg)
Debug 4,560 4,070 3,460 3,410 seg (en media 3,875 seg)

Prueba n. 2

Se han insertado 20 clientes (tabla Clientes), con 20 pedidos cada cliente (tabla Pedidos), y 20 productos cada pedido (tabla Detalles de Pedidos), con un total de 8.420 registros.

DAO Release 9,500 9,450 9,390 9,500 seg (en media 9,460 seg)
Debug 21,590 21,370 21,420 21,370 seg (en media 21,438 seg)
ODBC Release 17,520 17,790 17,520 17,800 seg (en media 17,658 seg)
Debug 30,420 30,100 29,770 30,430 seg (en media 30,180 seg)

Prueba n. 3

Se han insertado 50 clientes (tabla Clientes), con 50 pedidos cada cliente (tabla Pedidos), y 50 productos cada pedido (tabla Detalles de pedidos), con un total de 127.550 registros.

DAO Release 3 min 3,620 seg 2 min 43,510 seg (en media 2 min 53,565 seg)
ODBC Release 8 min 44,370 seg 7 min 35,610 seg (en media 8 min 9,990 seg)

Página inicial | Presentación

1