2004_08_03a04

Anuncio
Revista Electrónica Granma Ciencia. Vol.8, No.3, Septiembre-Diciembre de 2004
ISSN 1027-975X
TÍTULO: El Lenguaje SQL, su aplicación en el acoplamiento de tablas en Base de Datos
Relacionales. Caso Oracle.
AUTOR: Osmani A. Miranda Escalona
INSTITUCIÓN: Jefatura Provincial del MININT. Carretera Central, Vía Santiago de Cuba km
1 ½ Rpto. Viviendas Campesinas. Bayamo. Granma.
E-MAIL: [email protected]
RESUMEN
El modelo relacional es hoy el más utilizado entre los que se emplean para el diseño de
bases de datos. En su uso juegan un importante papel los acoplamientos entre las diferentes
relaciones o tablas de datos. En este trabajo se explica como se realizan los acoples
naturales, internos, externo izquierdo, externo derecho y externo total entre tablas,
empleando el Lenguaje Estructurado de Consultas (SQL). La implementación del SQL tiene
algunas variaciones en dependencia del Sistema de Gestión de Bases de Datos Relacional
(SGBDR) que lo emplee. Veremos aquí el caso Oracle.
INTRODUCCIÓN
El concepto Base de Datos (BD) está asociado indudablemente al Sistema Objeto de Estudio
(SOE). Se pudo elegir en su lugar el término Sistema Objeto, Sistema Objeto de Análisis o
Sistema Objeto de Automatización. De cualquier manera la BD es un modelo del mundo real
o de una abstracción que se quiere analizar o automatizar.
Un modelo se emplea para designar a una construcción hecha por el hombre, para simular el
comportamiento de la parte del mundo que estudia, excluyendo las características no
esenciales de acuerdo con el problema estudiado. De esta manera, se pueden crear modelos
Físicos, Químicos, Matemáticos, Lógicos o Termodinámicos, entre otros. En este caso se
construyen Modelos de Datos. Existen tres modelos de datos fundamentales: Jerárquico,
Reticular y Relacional.
Modelo de Datos Jerárquico: Los datos en este modelo se almacenan en registros,
compuestos a su vez por campos que contienen, además de los datos de cada nodo,
enlaces entre registros representantes de relaciones de padres a hijos, usando una
estructura arborescente de un único tipo.
Modelo de Datos Reticular: Puede ser visto como una extensión del anterior donde los datos
se almacenan también en registros enlazados, diferenciándose, en que se utilizan redes en
lugar de árboles.
Modelo de Datos Relacional: Este modelo creado por E .F. Codd fue presentado en 1970 con
fundamentos matemáticos sólidos que sirven de base, no solo al modelo, sino también a los
lenguajes de manipulación en particular.
La esencia de este modelo radica en establecer nexos (relaciones) entre datos de dos o más
conjuntos de entidades modeladas o entre los elementos de un mismo conjunto de
entidades. Estas asociaciones se representan a través de tablas cuyas columnas
representan los atributos de las entidades asociadas. Las filas describen ocurrencias de esas
relaciones; también se les llama tuplas. La estructura de una base de datos con un nivel de
complejidad moderado, generalmente está compuesta por varias tablas relacionadas entre
sí. Para manipular la información contenida en ella es necesario realizar acoples entre las
diferentes tablas.
En este artículo se pretende ofrecer elementos acerca de los fundamentos matemáticos del
acoplamiento de tablas en bases de datos relacionales y su definición con el lenguaje SQL
estándar y su implementación en el Sistema de Gestión de Bases de Datos Relacionales
(SGBDR) Oracle.
De los fundamentos matemáticos del modelo relacional.
La simplicidad en la estructura del Modelo Relacional y su excelente poder semántico le dio
una fuerza que le permite mantenerse hasta los días de hoy como el más usado para el
diseño de BD. El modelo relacional ha sido ampliado con variantes, como el Relacional
Anidado y el Binario,n para darle mayores posibilidades sin que pierda la fuerza que lo
caracteriza en las consultas.
Para el modelo Relacional es introducida una alteración radical en los conceptos aplicados
hasta el momento en que aparece. Es la relación o tabla el elemento que se utiliza para
almacenar, no solamente a los datos, sino a prácticamente todos los componentes que se
utilizan en la construcción de la estructura conceptual del modelo.
Definición de Tabla o Relación.
Una Tabla o Relación se define formalmente como:
R  D1 x D2 x . . . x Dn donde:
n : Grado de la relación o tabla y la cantidad de dominios que participan en el producto
cartesiano que definen el espacio existencial de la relación.
Di es el décimo dominio (no necesariamente distintos) del espacio de R.
Ese producto define un conjunto de tuplas t de la forma:
t = (d1,d2,. . ., dn ) de modo que (d1D1 , d2D2 , . . . ,dnDn).
Sean:
ti una tupla de ese espacio o universo.
M la extensión del producto cartesiano de los dominios.
E = {ti / i = [1, M] }
P un predicado que caracteriza los miembros de E que pueden formar parte de R.
Se dice entonces que:
R = {t / P(t) /\ ( tE) }
Se interpreta diciendo que R está compuesta por las tuplas t que satisfacen el predicado P y
que pertenecen al espacio E.
Fig. 1: Definición de una relación
Veamos a continuación un ejemplo de relación o tabla.
Fig. 2: Ejemplo de relación
Álgebra Relacional como base teórica operacional.
El Álgebra Relacional es una extensión del Álgebra de Relaciones donde son definidas
algunas operaciones adicionales para aumentar su poder expresivo.
Las operaciones se pueden dividir en dos grupos: Básicas, se dividen en Unarias y Binarias,
y Derivadas.
Básicas Unarias: Complemento, Proyección y Selección.
Básicas Binarias: Unión, Intersección, Diferencia, Producto, Cociente.
Derivadas Binarias: Equis – Join, Alfa – Join.
Teniendo en cuenta los objetivos de este material solo profundizaremos en las operaciones
de Unión, Equis – Join y Alfa – Join.
Unión
Aplicación binaria de E x E en E tal que:
E = {D1xD2x...xDn}.
R  E.
S  E.
Permite obtener otra Relación T denotada por T = RS de modo que:
T  E.
T = {t / (tR) \/ (tS) }.
Ejemplo . Sea R la misma relación anterior, con esquema:
R (Numlínea, NotaProm, Grado) y S otra de igual esquema pero con extensión:
S ={(2, 1, 3),( 2, 3, 4),( 3, 4, 5),( 1, 2, 3)}
Encuentre la Relación T cuya extensión sea R  S .
Producto Extendido
Aplicación binaria de E x W en EW tal que:
E = {D1xD2x...xDn}.
W = {H1xH2x....xHm}.
E y W pueden tener dominios iguales pero no con igual denominación.
R  E.
S  W.
Permite obtener otra Relación T denotada por T = RxS de modo que:
T  EW.
T = {t / (tEW) } con forma t=(d1,d2,...dn,h1+n,h2+n,...hm+n).
Hi puede coincidir con Dj para alguna i , j .
Derivadas
El Producto Cartesiano es, posiblemente, la operación que se emplea con mayor frecuencia
para solucionar las más variadas consultas que se hacen a una BD. Eso se debe a que
constituye la operación intermedia necesaria para realizar cualquiera de las operaciones de
Join (Agrupación) disponibles en los LMD del SGBD que se utiliza. Se estudiarán las dos
más conocidas, que son: el Agrupamiento Natural (Natural Join) y el Agrupamiento Alfa.(Alfa
Join).
Acerca de SQL
El Dr. E.F Codd publicó un artículo en Junio de 1970 bajo el título "A Relational Model of Data
for Large Shared Data Banks" donde presentaba el modelo relacional; aceptado en ese
momento, como un modelo matemático para la implementación de SGBDR. Es entonces
cuando IBM desarrolla el “Structured English Query Language” ("SEQUEL"): lenguaje
computacional para emplearlo. En 1979, “Relational Software. Inc”, hoy “Oracle Corporation”,
presenta la primera implementación comercial de SQL, el cual es actualmente reconocido
como un lenguaje estándar para SGBDR. El término SQL cuya traducción es “Structured
Query Language”:
En 1992, ANSI e ISO organizaciones de definición de estándares completaron la
estandarización de SQL y definieron el conjunto de sentencias básicas que debía tener toda
implementación para ser llamada estándar. A este SQL se le denominó popularmente ANSISQL, SQL92 o SQL2; aunque los nombres formales del nuevo estándar son: (ANSI X3.1351992, "Database Language SQL") o (ISO/IEC 9075:1992, "Database Language SQL"). Hoy
en día todas las bases de datos comerciales cumplen el estándar ANSI, aunque cada
fabricante añade sus mejoras al lenguaje SQL.
Acoples en SQL Estándar
El Lenguaje SQL permite recuperar datos correspondientes a varias tablas mediante acoples
de estos datos. Las consultas multitablas corresponden a lo que en el álgebra relacional se
llama producto cartesiano y al acople como un subconjunto del primero. Se denomina acople
al proceso de formar combinaciones de filas haciendo coincidir los contenidos de las
columnas relacionadas.
Es común encontrar en las combinaciones multitablas aquellas que implican solo dos tablas y
que tienen una relación padre – hijo. La tabla padre es aquella que tiene la llave primaria y la
tabla hijo es aquella que tiene la llave foránea.
Veamos un ejemplo:
Se tiene una Base de Datos donde se controlan medios técnicos de informática y
comunicaciones. Existe una tabla principal Mtécnico con los datos generales y existen otras
microcomputadora, radio, teléfono, impresora, monitor, y otras con datos específicos de
cada medio técnico. En este caso la tabla padre es Mtécnico y cualquiera de los otros es hija
de ésta.
Tenemos en la tabla Mtécnico los siguientes datos (Número de serie, ubicación, estado
técnico, fecha de alta y fecha de baja) y en la tabla microcomputadora los datos (Número de
serie, microprocesador, velocidad, RAM, Tipo de RAM, TipoBUS). Se quiere recuperar el
número de serie, ubicación y estado técnico de las microcomputadoras con microprocesador
PENTIUM IV.
Para realizar esta consulta en SQL estándar se escribe:
SELECT NoSerie, ubicacion, estado FROM Mtecnico MT, Microcomputadora MC
WHERE MT.NoSerie=MC.NoSerie and Microprocesdor=”PENTIUM IV”;
En la cláusula WHERE se igualan la llave primaria de una tabla (MT.NoSerie) con la
extranjera de la otra (MC.NoSerie). A estas columnas que se emparejan se denominan
columnas de emparejamiento. En estos casos la comparación se llama equicomposiciones,
ya que siempre es por igualdad. En dependencia de los requerimientos de la consulta una
tabla puede actuar unas veces como padre y otras como hijo.
La composición puede ser de más de dos tablas. Veamos otro ejemplo donde adicionamos
una tercera tabla: soportes, donde se registran datos acerca de los soportes magnéticos y
ópticos de información. Los datos contenidos en esa tabla son: (NoSerie, Tipo, Capacidad,
Tecnología). Se quieren los mismos datos que en el ejemplo anterior pero adicionándole el
requerimiento de que las microcomputadoras deben poseer discos duros con tecnología
SCSI.
La consulta se escribiría:
SELECT NoSerie, ubicacion, estado FROM Mtécnico MT, Microcomputadora MC, Soporte
SO
WHERE MT.NoSerie=MC.NoSerie and MC.NoSerie=SO.NoSerie
and Microprocesdor=”PENTIUM IV” and (SO.Tipo=”DISCO DURO” and
SO.Tecnologia=”SCSI”);
Pueden existir composiciones de desigualdad, aunque son muy raras.
Algunas consultas multitabla afectan a una relación de una tabla con ella misma. Por
ejemplo. Se tiene una tabla nombrada software con los software instalados en las
microcomputadoras con los siguientes datos (NroSerie de la microcomputadora, código,
nombre, versión, tipo, cod_SO). Se desea listar el nombre de los software registrados y el
sistema operativo del cual depende.
SELECT SW.Nombre, SO.Nombre FROM software SW, software SO
WHERE SW.cod_SO=SO.codigo;
Nótese como es necesario en este caso definir alias para evitar ambigüedades al nombrar
las columnas.
Acoples externos
En los acoples realizados anteriormente se recuperan sólo las filas que emparejan datos, es
decir, si en la tabla padre existen filas que no tienen filas relacionadas en la tabla hijo, estas
no se seleccionarán. Tiene la desventaja de que se puede perder información de utilidad en
dependencia de los requerimientos de la aplicación o el contexto. Para evitar este
inconveniente existen los acoples externos cuya finalidad es que las filas sin emparejar
aparezcan en los resultados. Existen entonces tres casos de acoples externos:
- Recupera todas las filas de la tabla padre y solo la de la tabla hijo relacionada con ellas
(acople izquierdo).
- Recupera todas las filas de la tabla hijo y solo la de la tabla padre relacionada con ellas
(acople derecho).
- Recupera todas las filas de la tabla padre y todas las filas de la tabla hijo estableciendo
los nexos correspondientes (acople completo).
Fig. 3: Tipos de Acoples
Para indicar la composición externa de las tablas se utilizan símbolos especiales para el
emparejamiento de las columnas, o una sintaxis especial de la cláusula FROM. Los símbolos
que se emplean para los acoples externos son los siguientes: (*=) para el acople izquierdo,
(=*) acople derecho y (*=*) acople completo.
Ejemplos:
Consulta simple de las microcomputadoras
SELECT NoSerie, RAM,TipoRAM,TipoBus FROM microcomputadora;
Se obtendría la siguiente recuperación:
NoSerie
RAM TipoRAM
FY3404974 128 SIMM
FX8746487 256 DIMM
DH8746383 128 DIMM
HY8764834 64
SIMM
DF9587423 128 DIMM
JK0923474 128 SIMM
JK9486359 256 DIMM
7 filas seleccionadas
TipoBus
ISA
ISA
PCI
PCI
ISA
PCI
PCI
Realizando un acople interno con los soportes de información pudiéramos obtener los
siguientes resultados:
SELECT NoSerie, RAM,TipoRAM,TipoBus FROM microcomputadora MC, soportes SO
WHERE MC.NoSerie= SO.Noserie;
NoSerie
RAM TipoRAM
FY3404974 128 SIMM
DH8746383 128 DIMM
HY8764834 64
SIMM
DF9587423 128 DIMM
JK0923474 128 SIMM
JK9486359 256 DIMM
6 filas seleccionadas
TipoBus
ISA
PCI
PCI
ISA
PCI
PCI
En este caso solo se recuperan 6 filas ya que la microcomputadora con número de serie
FX8746487 no tiene registrado soportes de información.
Veamos ahora el caso del acople externo izquierdo.
SELECT NoSerie, RAM,TipoRAM,TipoBus,Tipo, Capacidad
FROM microcomputadora MC, soportes SO
WHERE MC.NoSerie*= SO.Noserie;
NoSerie
FY3404974
FX8746487
DH8746383
HY8764834
DF9587423
JK0923474
RAM
128
256
128
64
128
128
TipoRAM
SIMM
DIMM
DIMM
SIMM
DIMM
SIMM
TipoBus
ISA
ISA
PCI
PCI
ISA
PCI
Tipo
Disco Duro
NULL
Disco Duro
Disco Duro
Disco Duro
Disco Duro
Capacidad
10 Gb
NULL
10 Gb
10 Gb
40 Gb
40 Gb
JK0923474 128 SIMM
JK0923474 128 SIMM
JK9486359 256 DIMM
9 filas seleccionadas
PCI
PCI
PCI
Lector de CD700 Mb
Disco 31/2 1,44 Mb
Disco Duro 40 Gb
La fila de la tabla microcomputadora que no aparecía en la tabla selección anterior, ahora
aparece rellenando los valores de las columnas correspondientes a la tabla soportes con
valores nulos.
Caso de acoplamiento externo derecho
SELECT NoSerie, RAM,TipoRAM,TipoBus,Tipo, Capacidad
FROM microcomputadora MC, soportes SO
WHERE MC.NoSerie=* SO.Noserie;
NoSerie
RAM TipoRAM
FY3404974 128 SIMM
DH8746383 128 DIMM
HY8764834 64
SIMM
DF9587423 128 DIMM
JK0923474 128 SIMM
JK0923474 128 SIMM
JK0923474 128 SIMM
JK9486359 256 DIMM
NULL
NULL NULL
NULL
NULL NULL
10 filas seleccionadas
TipoBus
ISA
PCI
PCI
ISA
PCI
PCI
PCI
PCI
NULL
NULL
Tipo
Capacidad
Disco Duro 10 Gb
Disco Duro 10 Gb
Disco Duro 10 Gb
Disco Duro 40 Gb
Disco Duro 40 Gb
Lector de CDNULL
Disco 3½
1,44 Mb
Disco Duro 40 Gb
Disco 3½
1,44 Mb
Disco 5¼
1,2 Mb
Caso de acoplamiento externo completo
SELECT NoSerie, RAM,TipoRAM,TipoBus,Tipo, Capacidad
FROM microcomputadora MC, soportes SO
WHERE MC.NoSerie*=* SO.Noserie;
NoSerie
RAM TipoRAM
FY3404974 128 SIMM
FX8746487 256 DIMM
DH8746383 128 DIMM
HY8764834 64
SIMM
DF9587423 128 DIMM
JK0923474 128 SIMM
JK0923474 128 SIMM
JK0923474 128 SIMM
JK9486359 256 DIMM
NULL
NULL NULL
NULL
NULL NULL
11 filas seleccionadas
TipoBus
ISA
ISA
PCI
PCI
ISA
PCI
PCI
PCI
PCI
NULL
NULL
Tipo
Capacidad
Disco Duro 10 Gb
NULL
NULL
Disco Duro 10 Gb
Disco Duro 10 Gb
Disco Duro 40 Gb
Disco Duro 40 Gb
Lector de CDNULL
Disco 3½
1,44 Mb
Disco Duro 40 Gb
Disco 3½
1,44 Mb
Disco 5¼
1,2 Mb
Los símbolos “*=”,”=*” y “*=*” no son empleados por el SQL estándar sino por algunas
implementaciones que veremos más adelante, solo los hemos empleado para simplificar la
explicación. En realidad, todas los acoples internos y externos se pueden incluir en la
cláusula FROM de la sentencia SELECT con la siguiente sintaxis:
Fig. 4: Sintaxis para la implementación de acoples en SQL92
Donde:
Fig. 4.1: Detalle de la Sintaxis (tipos de acoples)
Por lo que los ejemplos anteriormente expuestos quedarían.
Composición interna:
SELECT MC.NoSerie, RAM,TipoRAM,TipoBus
FROM microcomputadora MC INNER JOIN soportes SO
ON MC.NoSerie= SO.Noserie;
SELECT MC.NoSerie, RAM,TipoRAM,TipoBus
FROM microcomputadora INNER JOIN soportes
USING (NoSerie);
La segunda variante utilizando USING se puede emplear cuando las columnas de
emparejamiento tienen igual nombre en ambas tablas.
Acople externo izquierdo:
SELECT MC.NoSerie, RAM,TipoRAM,TipoBus,Tipo, Capacidad
FROM microcomputadora LEFT OUTER JOIN soportes
USING (NoSerie);
Acople externo derecho:
SELECT MC.NoSerie, RAM,TipoRAM,TipoBus,Tipo, Capacidad
FROM microcomputadora RIGHT OUTER JOIN soportes
USING (NoSerie);
Acople externo completo:
SELECT MC.NoSerie, RAM,TipoRAM,TipoBus,Tipo, Capacidad
FROM microcomputadora FULL OUTER JOIN soportes
USING (NoSerie);
Implementación en Oracle
En esta sección nos referiremos a la versiones anteriores a Oracle 9i, las cuales no
implementan los acoples externos con la misma sintaxis del SQL estándar, por lo que nos
detendremos en ese aspecto.
Para escribir una consulta que funcione como un acoplamiento externo de las tablas A y B y
seleccione todas las filas de A se debe aplicar el operador de acople externo “(+)” a todas las
columnas de B en la condición de acople. Para cada fila de A que no acople con filas en B,
Oracle rellenará con nulos para cualquier lista que contenga columnas de B.
De forma que los ejemplos que estudiamos se representarían como sigue:
Acople externo izquierdo
SELECT MC.NoSerie, RAM,TipoRAM,TipoBus,Tipo, Capacidad
FROM microcomputadora MC, soportes SO
WHERE MC.NoSerie= SO.Noserie(+);
Acople externo derecho
SELECT MC.NoSerie, RAM,TipoRAM,TipoBus,Tipo, Capacidad
FROM microcomputadora MC, soportes SO
WHERE MC.NoSerie(+)=SO.Noserie;
El acoplamiento externo total no se implementa directamente sino que es necesario
obtenerlo a través de la unión de un acople externo izquierdo y uno derecho tal como sigue.
Implementación de acople externo total:
SELECT MC.NoSerie, RAM,TipoRAM,TipoBus,Tipo, Capacidad
FROM microcomputadora MC, soportes SO
WHERE MC.NoSerie= SO.Noserie(+)
UNION
SELECT MC.NoSerie, RAM,TipoRAM,TipoBus,Tipo, Capacidad
FROM microcomputadora MC, soportes SO
WHERE MC.NoSerie(+)=SO.Noserie;
Los acoples externos en Oracle están sujetos a las siguientes reglas y restricciones:
-
El operador “(+)” puede aparecer solo en la cláusula WHERE y puede ser aplicada solo a
columnas de una tabla o vista.
-
Si las tablas A y B están acopladas por múltiples condiciones de acoplamiento, debe
usarse el operador “(+)” en todas las condiciones, de lo contrario Oracle asumirá que se
trata de un acople interno sin alertas.
-
El operador “(+)” puede ser aplicado solo a columnas, no a expresiones; sin embargo una
expresión puede contener columnas marcadas con el operador “(+)”.
-
Una condición que contenga el operador “(+)” no puede ser combinada con otra condición
usando el operador lógico OR.
-
Una condición no puede usar el operador de comparación IN para comparar columnas
marcadas con el operador “(+)” con una expresión.
-
Una condición no puede comparar cualquier columna marcada con el operador “(+)” con
una subconsulta.
Si la cláusula WHERE contiene condiciones que comparan una columna de una tabla B con
una constante, el operador (+) debe ser aplicado a la columna, la cual debería retornar
valores nulos, de lo contrario Oracle solo retornará el resultado de un acople interno.
En una consulta que funciona como acoplamiento externo de más de dos pares de tablas, la
tabla simple puede ser generadora de nulos solo para otra tabla. Por esta razón no se puede
aplicar el operador (+) a una columna de B en la condición de acople para A y B y en la
condición de acople para B y C.
Lo nuevo en Oracle 9i
Oracle 9i experimenta un salto importante con respecto a las versiones anteriores. Permite el
uso del estándar ANSI para la sintaxis de los acoples externos aunque mantiene la
posibilidad de emplear la sintaxis anterior, es decir, a través el operador “(+)”. Los ejemplos
mostrados para explicar la implementación de acoples internos y externos en el SQL
estándar empleando las cláusulas [INNER, o (FULL,RIGHT,LEFT) JOIN] son completamente
válidos también para Oracle 9i. También es válido en recurrir de las cláusulas ON o a la
cláusula USING cuando las columnas de las dos que participan en el acople tienen el mismo
nombre. Se puede emplear también CROSS JOIN para obtener el producto cartesiano de
las relaciones o tablas que se acoplarán. De esta forma quedaría la sintaxis ANSI general del
acople que implementa Oracle 9i tal como se describe en la figura 4.
CONCLUSIONES
En este trabajo se han relacionado algunos aspectos esenciales acerca de los fundamentos
matemáticos del modelo relacional y la importancia del acoplamiento entre las diferentes
tablas que puedan resultar de un proceso de normalización de una base de datos; así como
la forma en que el Lenguaje SQL implementa estos acoplamientos. Ejemplificamos además,
como algunos de los más actualmente usados Sistemas de Gestión de Bases de Datos
Relacionales (SGBDR) implementa este lenguaje, cada uno con sus particularidades.
BIBLIOGRAFÍA
Cobo, Luis. <[email protected]> “Introducción al Lenguaje Estructurado de
Consultas (SQL)” domingo, Enero 25, 1999 10:19 AM.
Greenwald, Rick. Robert Stackowiack y Jonathan Stern. “Oracle esentials: Oracle 9i, Oracle
8i y Oracle 8, Second Edition”. O´Reilly and Associates, Inc. Sebastopol, 2001. 364 p.
Loney, Kevin. George Koch: “Oracle 9i: The Complete Reference”. KcGraw-Hill/Osborne.
2003 . – 1214 p.
Marrero Cruz, Arnaldo. Implementación y Programación de Bases de Datos SQL Server,
Data CIMEX SA, 1998 [disquete].
Martínez del Busto, Maria Elena. Curso de SQL, Maestría de Computación Aplicada 2004,
Conferencias 1,5 y 6 [disquete].
Navarro, José.”Iniciación a Oracle 8i” [disquete].
MySQL Reference Manual for version 3.22.19b., 1999 [disquete]
Teach Yourself SQL in 21 Days, Second Edition, Macmillan Computer Publishing.
Manual de Acces Intermedio [disquete].
Descargar