Capítulo de muestra - Ra-Ma

Anuncio
1
Sistemas de
almacenamiento
de la información
Objetivos del capítulo
4 Aprender qué son y cómo
se utilizan los archivos
secuenciales, aleatorios e
indexados.
4 Entenderlos en un contexto
de evolución histórica.
4 Conocer sus ventajas e
inconvenientes.
4 Entender en qué manera
han influido en el posterior
diseño de las bases de
datos relacionales.
GESTIÓN DE BASES DE DATOS
1.1
© RA-MA
sistema basado en archivos
1.1.1Historia de los archivos
Debemos entender la evolución de las bases de datos como un proceso
continuo de modernización que nos ha llevado desde el papel hasta el estado
actual. Hace treinta años, las necesidades eran menores y los grandes
ordenadores enfocaban sus objetivos a controlar los procesos básicos de una
empresa, que en aquel momento eran la contabilidad en primer término y tras
ello la facturación.
Hoy día controlamos muchas más cosas; los procesos de la producción; la
optimización de los recursos; los documentos de la empresa; los centros de
comunicación con el cliente; la inteligencia de negocio aplicada a las ventas y
tantos otros.
En cambio, hace treinta años, los problemas se podían solucionar con una
decena de archivos, ¿Quién me quiere comprar algo? Mis clientes. Por tanto
necesito un archivo de clientes. ¿Quién me suministra la materia prima?
Mis proveedores. Por tanto necesitamos un archivo de proveedores. Y así
sucesivamente.
La mayor parte de las empresas de hace treinta años utilizaban archivos de
papel, donde anotaban los datos de sus clientes en forma de fichas escritas con
una máquina de escribir de la época.
Por eso los archivos también recibían el nombre de ficheros, y por esa razón
también la primera informatización empezaba por pasar del sistema de fichas
de papel o de cartulina a un sistema informatizado.
La principal ventaja del sistema informatizado estaba en evitar tiempo
para encontrar una ficha de papel dentro de un enorme cajón de fichas. Poder
encontrar una ficha en menos de un minuto ya era una importante diferencia
con respecto a enviar a una persona a buscarla a otra planta del edificio (el
archivo de muchas empresas solía estar en los sótanos) y traérnosla al cabo de
cinco minutos.
Pasábamos, pues, de un sistema en que el soporte era papel, a un nuevo
sistema en el que el soporte era digital.
20
© RA-MA
1
n
SISTEMAS DE ALMACENAMIENTO DE LA INFORMACIÓN
1.1.2Métodos de acceso a los datos
Toda la historia de los archivos ha ido ligada al avance de la tecnología;
principalmente del hardware y en menor medida del software.
A continuación vamos a ver cuatro tipos de archivos, aunque los más
utilizados han sido tres:
1
2
3
4
Archivos secuenciales.
Archivos de acceso aleatorio.
Archivos indexados.
Archivos hash.
Los archivos de los tipos 1, 2 y 3 son los más comunes, puesto que cuando
se empezaron a utilizar los archivos hash, el concepto de base de datos cambió
y se cuestionó también el complejo sistema hash frente a sus mejoras de
rendimiento.
Veamos con detalle estos tipos de acceso a los archivos.
1.2
Archivos secuenciales
Situémonos en la época. Los sistemas de almacenamiento físico eran
tambores de cinta magnética de un diámetro comparable al de los antiguos
discos de vinilo conocidos como LP.
En casa es posible que nuestros padres tengan aún unas cintas de música
llamadas cassettes. Pues bien, las unidades de cinta informáticas eran como
unos cassettes gigantes donde se almacenaban datos digitales: ceros y unos en
orden secuencial.
21
GESTIÓN DE BASES DE DATOS
© RA-MA
¿Qué quiere decir secuencial? Que van ordenados en posiciones sucesivas,
y que si queremos llegar a la posición número 100, debemos pasar antes por la
1, la 2 y así sucesivamente; secuencialmente.
Este era el hardware que teníamos y el software de gestión más sencillo era
el procesador de textos.
No pensemos en un procesador de textos como Word. Word es una maravilla
comparado con lo que había en la época. No había tipos de letra. No podíamos
ver cómo quedaba el formato del documento. Teníamos editores de líneas; es
decir, disponíamos de instrucciones para abrir un archivo concreto quedándonos
en la línea cero por defecto; otros comandos para desplazarnos hasta una línea,
mostrar su contenido; modificar a partir de una posición y almacenar los
cambios línea a línea. Tras ello, con otro comando grabábamos el archivo y
finalmente con el comando Q salíamos de nuevo a la pantalla negra del sistema
operativo.
El sistema más normal para crear un archivo de clientes era escribir su
nombre, separar con un retorno de carro, escribir su dirección seguida de otro
retorno de carro, población y así sucesivamente.
Entre cliente y cliente se colocaba una marca de final de bloque que indicaba
el inicio de los datos de un nuevo cliente o bien el final del archivo de clientes.
Cada uno de estos bloques con los datos de un cliente recibe el nombre de
registro y cada una de estas informaciones (nombre, dirección, población, etc.)
recibe el nombre de campo.
Por tanto, un registro se compone de campos.
Veamos un ejemplo:
Juan Martínez
Calle del Pez, 5
Madrid
<FIN>
Comercial Martínez
Calle de la Cuesta, 10
Sevilla
<FIN>
José Sánchez
Calle Mayor, 7
Salamanca
<FIN>
22
© RA-MA
1
n
SISTEMAS DE ALMACENAMIENTO DE LA INFORMACIÓN
1.2.1Utilidad de los archivos secuenciales para
imprimir
Este tipo de archivos era muy útil si tenía justamente este formato, puesto
que servía para imprimir etiquetas y enviar circulares. La marca <FIN> que
también podía sustituirse por un punto solitario, quedaba en el espacio entre
etiquetas y no se veía.
Esto funcionaba siempre que tuviésemos el cuidado de colocar bien el
cabezal de la impresora en la primera etiqueta. Si no, teníamos que abortar el
listado porque las etiquetas salían desplazadas. Y a repetir de nuevo.
¿Qué era el cabezal de la impresora? Sólo teníamos impresoras de agujas.
Las láser tardaron más tiempo en salir al mercado y su precio era prohibitivo
para la mayor parte de empresas; ¡sólo las compraban las imprentas!
Las impresoras de agujas disponían de un cabezal con una matriz de filas
de 9 agujas que golpeaban una cinta empapada en tinta, dejando la huella del
impacto sobre el papel o en este caso sobre la etiqueta.
23
GESTIÓN DE BASES DE DATOS
© RA-MA
Pues bien, este era el sistema de trabajo con un archivo de clientes, y en la
primera época eran sólo los informáticos (con bata blanca) los autorizados a
trabajar con los editores de líneas para confeccionar los archivos de clientes.
Imprimir las etiquetas para enviar las cartas era un trabajo que, si se hacía
a máquina, podría tardar semanas. Con el ordenador y la impresora se podía
hacer en media hora.
1.2.2Características de los archivos secuenciales
1.2.2.1Lectura ordenada obligatoria
Para leer un registro situado en medio del archivo debemos pasar por todos
los registros anteriores.
1.2.2.2No permite el retroceso (forward only)
En los archivos secuenciales se realiza la lectura sólo hacia delante. Por
ejemplo: si nosotros leemos el primer registro del cliente, el segundo, el tercero,
el cuarto y después deseamos volver al segundo, la única forma de hacerlo
consiste en cerrar el archivo y volver a abrirlo, ya que no podemos retroceder.
1.2.2.3Los archivos secuenciales son monousuarios
Los archivos secuenciales no permiten el acceso simultáneo (concurrencia)
de varios usuarios. Si por desventura se accediera simultáneamente en modo
escritura, los resultados son impredecibles: puede producirse corrupción de
datos por escrituras entremezcladas o desaparición inadvertida de datos. El
último que escribe tiene mayores posibilidades de mantener su información.
Evitemos la concurrencia en archivos secuenciales.
1.2.2.4Estructura rígida de campos
Todos los registros deben aparecer en orden. Esto quiere decir que si nosotros
escogemos el orden Nombre, Dirección, Población en el primer registro, no
podemos cambiarlo por Dirección, Población, Nombre en el siguiente registro.
El programa de lectura de un archivo secuencial va a ciegas leyendo líneas y
necesita saber qué significado tiene cada línea según su orden.
24
© RA-MA
1
n
SISTEMAS DE ALMACENAMIENTO DE LA INFORMACIÓN
Pero, ¿qué pasa si queremos grabar más datos de cada cliente? Por ejemplo
su teléfono o su código fiscal, o sus condiciones de pago…
La primera consecuencia es que debemos rehacer todos los programas de
lectura para tener en cuenta estos nuevos campos. Y esto puede representar
mucho trabajo si tenemos que acabarlo de un día para otro.
La segunda consecuencia es que ese archivo ya no nos serviría para imprimir
etiquetas. Tendríamos que guardar un archivo central con todos los datos y, a
partir de éste, extraer en otro archivo sólo los datos que deseamos imprimir.
Tras ello ya podríamos lanzar el nuevo listado por la impresora. Por tanto,
debemos crear un nuevo proceso y complicar el que ya teníamos.
1.2.2.5El modo de apertura condiciona lectura o escritura
Las lecturas y las escrituras dependen del modo en que se haya abierto un
archivo secuencial. En el momento de abrir un archivo, dependiendo del modo
que hayamos escogido, quedaremos autorizados a leer o a escribir, pero no a
las dos cosas.
1.2.2.6Lecturas parciales pero escrituras totales
Las operaciones de lectura pueden ser parciales, pero las operaciones de
escritura conllevan obligatoriamente la escritura total de toda la secuencia
completa de registros.
Dicho de otro modo: al abrir un archivo en modo escritura estamos borrando
su contenido anterior si lo hubiere.
Por esta razón algunos lenguajes de programación contienen un modo de
apertura llamado Append que escribe al final de un archivo existente en vez
de reescribirlo de nuevo.
1.2.2.7La marca de final de archivo (EOF)
Las operaciones de lectura deben comprobar siempre que no rebasan el
final del archivo secuencial, mediante la comparación del carácter de final
de archivo (EOF o End Of File). Este carácter se coloca siempre y de modo
implícito al cerrar un archivo secuencial en modo escritura.
25
GESTIÓN DE BASES DE DATOS
© RA-MA
1.2.2.8Borrado de registros omitiendo contenido
El borrado de un registro puede hacerse por varios métodos, aunque el más
utilizado consiste en la escritura de todos los registros menos el que deseamos
eliminar.
Otro sistema es mantener la información, pero marcarla como borrada, lo
cual implica hacer consideraciones de programación más complejas.
1.2.2.9La posibilidad de uso de la marca de sincronismo
Existe una posibilidad –realmente una técnica– que no se utilizaba en los
primeros años del uso de los archivos secuenciales y que tiene que ver con la
marca de sincronismo entre registros.
La marca de sincronismo es una línea con un conenido específico que es
palabra reservada. Es decir, si la marca que nosotros elegimos es <FIN>,
no puede haber ningún cliente que se llame <FIN> ni ninguna dirección ni
población que sea <FIN>.
Por tanto, cuando nosotros veamos en una línea un contenido aislado como
la palabra reservada <FIN> sabremos que se acaba un registro y a continuación
empieza otro con el mismo orden.
Esto nos permite crear registros con campos que tienen este orden:
Nombre
Dirección
Población
CIF
Teléfono
Email
<FIN>
26
© RA-MA
1
n
SISTEMAS DE ALMACENAMIENTO DE LA INFORMACIÓN
Y nos permite también mezclar registros con diferentes estructuras, siempre
que haya una parte inicial común:
Nombre
Dirección
Población
CIF
Teléfono
Email
<FIN>
Nombre
Dirección
Población
<FIN>
Nombre
Dirección
Población
CIF
Teléfono
Email
<FIN>
La técnica se basa en la lectura línea a línea. Cuando se descubre que
el contenido de una línea es “<FIN>”, sabemos que el siguiente campo es el
primer campo del siguiente registro y que, por tanto, debemos omitir la lectura
de los posibles campos que puedan seguir pertenecientes al registro actual.
27
GESTIÓN DE BASES DE DATOS
© RA-MA
1.2.2.10Registros de longitud variable
Los registros de un archivo secuencial tienen una longitud variable porque
también sus campos tienen una longitud variable.
No ocupa el mismo espacio un cliente que se llame Juan Sánchez, que otro
cliente que se llame José María González de Castro y Santos de Carballar.
Esto implica que a priori no vamos a saber el tamaño de las variables que
debemos usar en memoria para almacenar estos contenidos.
Para superar este tipo de problemas apareció el archivo de acceso aleatorio,
que veremos más adelante.
1.2.2.11Contenido legible en un procesador de textos
El contenido de un archivo secuencial es legible en un procesador de
textos.
Pasó mucho tiempo antes de que aparecieran los editores de pantalla
completa que permitían mover el cursor hasta la línea que queríamos con las
flechas del teclado o con combinaciones de teclas.
El primero de ellos fue Wordstar y aquí ya empezamos a hablar de
procesadores de textos. No funcionaban por comandos sino por combinaciones
de teclas. En este momento las máquinas de escribir ya empezaban a estar
amenazadas.
28
© RA-MA
1
n
SISTEMAS DE ALMACENAMIENTO DE LA INFORMACIÓN
1.2.2.12Consideraciones adicionales sobre los archivos
secuenciales
Los archivos secuenciales siguen siendo buenas opciones para
almacenamiento de pocos registros en los que la velocidad de acceso no sea un
punto clave.
Todos los sistemas operativos soportan operaciones de lectura y escritura
sobre archivos secuenciales.
Todos los lenguajes de programación están dotados de funciones para
acceder a archivos secuenciales.
Los programas encargados de las altas, bajas, modificaciones, consultas,
listados y otras operaciones que afectan exclusivamente a un archivo (por
ejemplo, clientes) reciben el nombre de mantenimientos.
Podemos, pues, realizar mantenimientos de archivos secuenciales mediante
programas escritos en lenguajes de todo tipo: antiguos y modernos, como BASIC,
Pascal, Fortran, COBOL, C/C++, Java, Visual Basic, C#, Prolog, LISP, etc.
En nuestro caso vamos a utilizar cuatro lenguajes de gran difusión comercial
y académica:
1.
2.
3.
4.
Visual C++.
Visual Basic 6.0.
Java.
C#.
En las actividades encontraremos ejemplos en estos cuatro lenguajes.
1.3
ARCHIVOS DE ACCESO ALEATORIO
Si los archivos secuenciales se emparejan en el tiempo con el hardware de
los tambores de cinta magnética, los archivos de acceso aleatorio aparecen con
el disquete y el disco duro.
29
GESTIÓN DE BASES DE DATOS
© RA-MA
Los archivos de acceso aleatorio no están sujetos a la esclavitud de pasar
por el inicio hasta llegar a la porción de la información que nos interesa.
En los archivos de acceso aleatorio podemos colocarnos en una posición
determinada expresada por un número.
Por ejemplo, podemos ir directamente a la posición 100, volver atrás hasta
la posición 20, avanzar ahora hasta la 200 y así tantas veces como queramos.
Esto implica que si utilizamos una estructura delimitada en longitud,
podemos calcular la posición en la que debemos situarnos para leer un
registro.
La medida básica de la posición del puntero de lectura es el byte; primer
byte, segundo byte y así sucesivamente.
Esto quiere decir que, si empleamos caracteres de dos bytes (por ejemplo,
en Unicode), las posiciones para leerlos serán la 0, la 2, la 4, etc., avanzando
cada vez de dos en dos.
Pongamos por caso que tenemos un registro como éste codificado en ANSI
(1 byte por carácter):
Nombre: 80 caracteres ANSI
n Dirección: 100 caracteres ANSI
n Población: 50 caracteres ANSI
n
Su longitud será de 230 caracteres. Esto implica que el primer registro se
encontrará en la posición 0; el segundo registro se encontrará en la posición
230; el tercero estará en la posición 460 y así sucesivamente.
30
© RA-MA
1
n
SISTEMAS DE ALMACENAMIENTO DE LA INFORMACIÓN
Por tanto, podemos decir que la posición será:
Pos = NumRegistro * LongitudRegistro
Si en cambio codificamos los caracteres en Unicode (UTF-16) de forma que
su longitud es de 16 bits por carácter, esto es 2 bytes, el registro quedará así:
Nombre: 80 caracteres UTF-16.
n Dirección: 100 caracteres UTF-16.
n Población: 50 caracteres UTF-16.
n
Su longitud será de 460 caracteres para un solo registro, ya que cada
carácter ocupa 2 bytes.
Ya tenemos la manera de calcular la posición. Ahora, cada lenguaje de
programación dispondrá de su propia función para el posicionamiento del
cursor de lectura o de escritura para realizar el acceso aleatorio.
1.3.1 ¿Qué sucede si un campo es de tipo numérico?
En los archivos secuenciales se guardaba el número con su formato
expresado en decimal: dígito a dígito. Por tanto, el número “10” ocupaba 2
caracteres y el número “1234567” ocupaba 7 caracteres.
En los archivos aleatorios no se guardan los dígitos, sino el valor binario.
Un número entero simple de 16 bits (de 0 a 65535) emplea 2 bytes.
31
GESTIÓN DE BASES DE DATOS
© RA-MA
Si se trata de un número entero de 32 bits (de 0 hasta 4.000 millones
aproximadamente) ocupa 4 bytes.
Si se trata de un número en coma flotante (normalmente se ajustan a la
norma IEE488 como Excel) usa 8 bytes para almacenar mantisa y exponente.
Estos datos ya no son legibles con un procesador de texto y si intentamos
leerlos nos aparecerán caracteres extraños, con posibilidad de que el contenido
no aparezca entero, ya que es frecuente encontrar un valor binario que coincida
con el valor EOF (final de archivo).
1.3.2Características de los archivos de acceso
aleatorio
1.3.2.1Posicionamiento inmediato
Permiten situar el puntero de lectura o escritura sobre una posición
concreta del archivo sin necesidad de pasar por las posiciones anteriores,
con el consiguiente incremento de rapidez. Una sola apertura proporciona la
capacidad de avanzar y retroceder sin necesidad de reabrir el archivo.
1.3.2.2Registros de longitud fija
Todos los registros tienen la misma longitud, ya que se utiliza siempre una
estructura rígida dimensionada a la máxima longitud para cada campo.
1.3.2.3Apertura para lectura/escritura
Permiten su apertura en modo mixto (lectura y escritura), de forma que con
una sola operación de apertura podemos leer o escribir a voluntad en cualquier
posición según nos convenga.
1.3.2.4Permiten el uso concurrente (multiusuario)
Al establecerse zonas específicas y limitadas de actuación para lectura y
escritura, diversos usuarios pueden acceder y escribir en diferentes porciones
del archivo de forma simultánea.
32
© RA-MA
1
n
SISTEMAS DE ALMACENAMIENTO DE LA INFORMACIÓN
Esto lleva a considerar la posibilidad de concurrencia de dos usuarios en
el mismo registro. Para ello se utilizan algoritmos de gestión de los bloqueos.
Dichos algoritmos administran zonas (que no siempre coinciden con registros)
y las marcan para evitar dicha concurrencia de forma temporal. El tema del
bloqueo lo trataremos más adelante dentro de los capítulos dedicados a bases
de datos relacionales.
1.3.2.5Dimensionamiento máximo al ser creados
Los archivos de acceso aleatorio deben dimensionarse hasta un número de
registros máximo en el momento de crearse.
1.3.2.6Borrado de registro mediante ceros
El borrado de un registro se realiza poniendo a 0 el espacio que ocupa;
rellenándolo con bytes con el valor binario 0. En sistemas más complejos se
emplea un algoritmo de reutilización de gaps o espacios vacíos, o incluso de
compactación.
Si empleamos un algoritmo de compactación de registros de gaps, deberemos
ser conscientes de que el número de registro cambiará para un cliente dado
en el momento en que se reubica, por lo cual una clave de acceso basada en
número de registro no tendrá validez.
Si utilizamos un algoritmo de reutilización de gaps deberemos ser concientes
de que un cliente nuevo puede reutilizar el espacio de un cliente borrado. Por
tanto, si utilizamos referencias a su número de registro en otros archivos,
deberemos ser cuidadosos de que un cliente no sea falsamente referenciado en
otros archivos.
Estos son problemas de integridad referencial que se resuelven mejor en
sistemas gestores de bases de datos, como veremos más adelante, y que fueron
una de las razones para realizar el cambio desde el sistema de información
basado en archivos al sistema de información basado en bases de datos.
33
GESTIÓN DE BASES DE DATOS
© RA-MA
1.3.3Consideraciones adicionales sobre los archivos
de acceso aleatorio
Los archivos de acceso aleatorio están especialente indicados para
aquellos casos en que el código del registro (cliente, proveedor, etc.) pueda ser
directamente el número de registro en el que se guardan los datos.
Al trabajar con archivos de acceso aleatorio deberemos tener en cuenta no
rebasar nunca el final de archivo. Si nuestro archivo está dimensionado hasta
100 registros, intentar que no haya ningún usuario que nos pregunte por el 101
o por el 200. Para ello deberemos establecer nuestros sistemas de prevención
desde el interfaz o desde el sistema de cálculo de la posición del puntero de
lectura / escritura.
Los archivos de acceso aleatorio son un paso más que nos conduce por el
camino de los archivos indexados, puesto que constituyen el depósito de los
datos. Como veremos más adelante, el almacenamiento temporal o no de las
claves es el elemento que lo diferencia de los indexados.
1.4
ARCHIVOS INDEXADOS
Los archivos indexados son básicamente archivos de acceso aleatorio a los
que se añade una utilidad para acceder al registro deseado a través de una
clave.
En el caso de los archivos de acceso aleatorio, la clave es siempre el número
de registro.
Los archivos indexados pueden buscar un cliente según su nombre, según
su código de identificación fiscal o según cualquier otro campo.
Para ello se construye una estructura de índice por cada campo que se desea
indexar.
Esta estructura de índice se mantiene en la memoria RAM de forma
ordenada, de manera que podamos encontrar rápidamente una relación entre
el apellido de un cliente y el número de registro en el que se encuentra.
34
© RA-MA
1
n
SISTEMAS DE ALMACENAMIENTO DE LA INFORMACIÓN
Esto es lo que permite realizar las búsquedas por clave sin necesidad de
recorrer todos los registros de la base de datos.
Tradicionalmente, la estructura de información utilizada para localizar los
registros por clave es el árbol binario o árbol de índices.
1.4.1Historia y funcionamiento básico de los árboles
de índices
En el año 1962, Giorgi Maxímovich Adelson-Velskii y Yevgueni Mijáilovich
Landis, dos matemáticos rusos, crearon un sistema de acceso muy rápido
llamado árbol AVL (Adelson-Velskii-Landis).
Un árbol se compone de nodos, que son los que contienen la información
de la clave y del número de registro en donde se encuentran los datos que nos
interesan.
Dentro de un nodo tenemos:
1. El propio valor de la clave.
2. Un dato útil para referenciar en donde se encuentran los campos del
registro, como por ejemplo, un número de registro para ir a buscar los
datos.
3. Un puntero hacia un nodo que contenga una clave con un valor inferior
o un nulo si no la hay, a la que llamaremos puntero L (de left o puntero
a la izquierda).
4. Un puntero hacia un nodo con una clave mayor o un nulo si no la hay, a
la que llamaremos R (de right o puntero a la derecha).
5. Otros datos interesantes para conocer rápidamente el estado del árbol,
como por ejemplo la altura del nodo respecto a la base del árbol o el
factor de equilibrio, que son datos que veremos más adelante. Los árboles
binarios se representan al revés, como una coliflor boca abajo, en la que
la raíz está siempre arriba.
35
GESTIÓN DE BASES DE DATOS
© RA-MA
Veamos un ejemplo de árbol en el que ordenaremos números:
A la izquierda de cada nodo colgamos un elemento más pequeño que el
propio y a la derecha colgamos un elemento más grande.
En todos los procesos de búsqueda mediante árboles, se entra a buscar
siempre por la raíz.
Imaginemos que estamos buscando el número 4.
Entramos por la raíz, que es el 5.
¿Es éste el que buscamos? No. ¿Es menor? Sí. Nos vamos hacia la
izquierda.
Encontramos el 3. ¿Mayor, menor o igual que 4? Mayor.
Nos vamos hacia la derecha y lo encontramos. Hemos realizado 3
comparaciones hasta llegar al dato que buscamos.
Esto es más lógico que emplear una lista ordenada, ya que en una lista los
números se organizarían así:
1
2
3
4
5
6
7
En el caso de buscar el mismo número, el 4, el número de comparaciones
sería el mismo que empleando un árbol.
Si buscásemos el número 2 en la lista, el número de comparaciones sería 1,
más rápido que con el árbol.
36
© RA-MA
1
n
SISTEMAS DE ALMACENAMIENTO DE LA INFORMACIÓN
En cambio, si buscáramos el 7, deberíamos hacer 6 comparaciones; mucho
más lento, puesto que el árbol sólo tiene 3 niveles. En un árbol de 8 elementos,
la altura máxima del árbol es de 3 niveles. No hará falta nunca rebasar 3
comparaciones para llegar al dato que buscamos, independientemente de si es
grande o pequeño.
En una lista ordenada, el número de comparaciones crece linealmente en
función de la cantidad de elementos que almacenamos en la lista.
En cambio, con el árbol, el número de comparaciones queda mucho más
contenido. Comparemos el peor de los casos en cada sistema.
Tabla 1.1
Árbol
Lista ordenada
8 elementos
3
8
16 elementos
4
16
32 elementos
5
32
64 elementos
6
64
128 elementos
7
128
Si nos fijamos, veremos que 8 es 23. Por tanto, en un árbol de N elementos,
el número de comparaciones máximo es el logaritmo en base 2 de los elementos
contenidos.
Los árboles ya se conocían antes de Adelson-Velskii y Landis. Eran y son
llamados árboles BST o Binary Search Tree, pero a pesar de que agilizaban el
acceso a los datos, se podían mejorar.
¿Por qué?
Porque los árboles que empezaban teniendo 10 o 15 elementos eran muy
rápidos, pero cuando iban creciendo existía el riesgo de crecer de forma
asimétrica; se iban descontrolando; crecían de forma asimétrica.
La palabra asimétrica expresa un crecimiento desequilibrado en el que unas
ramas acaban siendo mucho más largas que otras, causando una desproporción
en el número de pasos que deben darse (número de comparaciones necesarias)
para llegar hasta encontrar una clave dependiendo de en qué rama se
encuentre.
37
GESTIÓN DE BASES DE DATOS
© RA-MA
Este árbol respeta las normas L<Dato<R. L significa izquierda. R significa
derecha. A la izquierda los números más pequeños y a la derecha los mayores,
pero no está equilibrado; es un árbol asimétrico degenerado.
Más que un árbol parece una vara de sarmiento o una vara irregular. Esto
del sarmiento lo veremos un poco más adelante.
El mejor promedio de acceso a los datos se da cuando el árbol está
equilibrado.
Si hablamos de árboles AVL, hablamos de estructuras de árbol en las cuales
el equilibrio se garantiza mediante un algoritmo de autoequilibrado automático,
el cual permite unos tiempos de acceso rápido a los datos, puesto que compacta
el árbol para conseguir el número mínimo posible de alturas.
Para evaluar si nuestro árbol está bien equilibrado tenemos el valor del
factor de equilibrio que hemos citado brevemente antes dentro de los datos
propios de cada nodo.
El factor de equilibrio se calcula como la diferencia de las alturas de las
ramas izquierda y derecha a partir de un nodo dado. Aplicado a la raíz nos da
el factor de equilibrio global del árbol.
Un árbol AVL es el que tiene una diferencia entre izquierda y derecha no
superior a un nivel. Es decir 0 (óptimo) o 1 como máximo (admisible) ya que
dependiendo de los niveles es probable (casi seguro) que no todos los nodos de
la pirámide puedan llenarse al mismo nivel de las hojas (nodos terminales).
Los sistemas de rellenado del árbol y los algoritmos de rotación de los nodos
para reorganizarlo ya son harina de otro costal.
38
© RA-MA
1
n
SISTEMAS DE ALMACENAMIENTO DE LA INFORMACIÓN
Podemos tener algoritmos de autoequilibrado más veloces y menos veloces.
Todos hemos tenido experiencias con bases de datos que cada cierto tiempo
denegaban peticiones porque se estaban reorganizando índices. Posiblemente
no lo sabíamos, pero durante unos segundos la base de datos se quedaba
congelada y no nos atendía porque se estaba reorganizando internamente.
El tema es complejo y se centra en dos cuestiones:
1. Decidir si vamos a reevaluar el autobalanceo del árbol en cada nueva
inserción de datos (lo cual empeora la velocidad de inserción) o si vamos
a hacerlo cada cierto tiempo o cada cierto número de inserciones (lo cual
causa ese lapso de denegación de servicio).
2. Una vez decidido si vamos por uno u otro camino, encontrar la manera
de que la reorganización sea lo más rápida posible en la búsqueda del
algoritmo óptimo.
En 1976, Colin Day propuso un algoritmo bastante rápido, escrito en
lenguaje FORTRAN, que fue traducido a lenguaje Pascal, para ganar en
estructuración y recursividad, y modificado en 1988 por Quentin Stout y Bette
Warren dando origen 12 años más tarde al algoritmo conocido como DSW (DayStout-Warren).
Se trata de un algoritmo elegante que se basa en una teoría apoyada en dos
funciones: una Tree-To-Vine (de árbol hacia sarmiento o vara) y otra simétrica
Vine-To-Tree (de sarmiento o vara hacia árbol). La teoría se basa en que se
puede construir un árbol equilibrado si los datos de las claves se suministran
en orden.
Por tanto, se recorre el árbol de forma ordenada (recorrido In-order) y se
genera un árbol completamente lineal y degenerado. Resultado: una vara o
rama única. Como si sólo tuviésemos una lista con nodos que tuviesen un único
puntero L y careciesen de puntero R.
Después se reconstruye el árbol a partir de la vara, suministrando los datos
ordenadamente, montando los nodos a base de rotaciones progresivas.
Después vinieron cuestiones sobre cómo atravesar el árbol de forma óptima,
con o sin recursividad, utilizando los algoritmos de Frank M. Carrano y de
Mark A. Weiss, siendo éste un alumno de Robert Sedgewick de la Universidad
de Princeton.
39
GESTIÓN DE BASES DE DATOS
© RA-MA
Sedgewick realizó aportaciones finales de funciones auxiliares que fueron
recogidas en el libro Algorithms in C++, Parts 1-4 (Fundamental Algorithms,
Data Structures, Sorting, Searching) de Addison-Wesley, Boston 1998.
Timothy Rolfe optimizó al máximo el código con todas estas consideraciones
y lo empleó en la Eastern Washington University, como material de apoyo para
dar clases de estructuras de información y algoritmos.
En España, el profesor Ceballos de la Universidad Complutense de Alcalá,
viene difundiendo y estructurando desde hace años en sus clases y en sus libros
los árboles y los algoritmos de equilibrado.
1.5
actividades
Las actividades que implican código fuente se encuentran en el CD ROM
del libro dentro de la carpeta \Actividades\Capítulo 1
Para archivos secuenciales:
1. Escribir un programa que genere un archivo secuencial llamado
CLIENTES.TXT en el que grabaremos tres registros de clientes como
los expuestos en el ejemplo anterior, con los campos de nombre, dirección
y población.
2. Abrir el archivo con el bloc de notas de Windows (Notepad.exe) y verificar
que su contenido es legible.
3. Escribir un programa de lectura de un archivo secuencial línea a línea
mediante un bucle que verifique el final de archivo.
Para archivos de acceso aleatorio:
4. Escribir un programa de creación de un archivo de acceso aleatorio
para un archivo de clientes (CLIENTES.DAT) con un espacio de
almacenamiento de 10 registros, en el cual se escriban los tres primeros
clientes que ya utilizamos en el ejemplo anterior. Escribir una función
dentro de este programa que, dado un número de registro entre 0 y 9,
nos permita recuperar el contenido de uno de los registros anteriores.
40
© RA-MA
1
n
SISTEMAS DE ALMACENAMIENTO DE LA INFORMACIÓN
Para archivos indexados:
5. Trabajar con el programa de ejemplo Actividad5 que se encuentra en el
CD ROM del libro. Investigar cuáles son sus funcionalidades y revisar en
el código fuente cuál es el procedimiento interno para manejar el árbol
binario de indexación, el archivo de datos y el interfaz de la aplicación.
1.5.1 actividad 1
Escogeremos un lenguaje de programación de entre los cuatro propuestos:
4
4
4
4
C++
Visual Basic 6.0
Java
C#
1.5.1.1Actividad 1A: En lenguaje C++
En lenguaje C++, este fragmento de código fuente se encarga de generar
un archivo secuencial y rellenarlo con tres clientes, cerrando el archivo a
continuación. Se trata de una aplicación muy sencilla en modo consola (pantalla
de texto). El ejemplo ha sido compilado con Microsoft Visual C++. Si se desea
compatibilizarlo con otros compiladores de C como GNU C, se debe sustituir el
#include “stdafx.h” por #include <stdio.h>
#include “stdafx.h”
#include “io.h”
int main(int argc, char* argv[])
{
FILE * pArchivo;
printf(“Ejemplo de escritura de tres registros en
archivo secuencial\n”);
pArchivo = fopen(“CLIENTES.TXT”, “w”);
if (pArchivo)
{
//Primer cliente:
fprintf(pArchivo, “%s\n”, “Juan Martínez”);
41
GESTIÓN DE BASES DE DATOS
© RA-MA
fprintf(pArchivo, “%s\n”, “Calle del Pez, 5”);
fprintf(pArchivo, “%s\n”, “Madrid”);
fprintf(pArchivo, “%s\n”, “<FIN>”);
//Segundo cliente:
fprintf(pArchivo, “%s\n”, “Comercial Martínez”);
fprintf(pArchivo, “%s\n”, “Calle de la Cuesta, 10”);
fprintf(pArchivo, “%s\n”, “Sevilla”);
fprintf(pArchivo, “%s\n”, “<FIN>”);
//Tercer cliente:
fprintf(pArchivo,
fprintf(pArchivo,
fprintf(pArchivo,
fprintf(pArchivo,
//Cerrar el archivo:
fclose(pArchivo);
“%s\n”,
“%s\n”,
“%s\n”,
“%s\n”,
“José Sánchez”);
“Calle Mayor, 7”);
“Salamanca”);
“<FIN>”);
printf(“%s\n”, “3 registros escritos.”);
}
else
{
printf(“%s\n”,”No se ha podido abrir el archivo para
escritura.”);
}
printf(“%s\n”, “Final de programa”);
}
return 0;
1.5.1.2Actividad 1B: En lenguaje Visual Basic 6.0
En lenguaje Visual Basic 6.0, este fragmento de código fuente se encarga de
generar un archivo secuencial y rellenarlo con tres clientes, cerrando el archivo
a continuación.
Private Sub Command1_Click()
On Error GoTo manejador
42
© RA-MA
1
n
SISTEMAS DE ALMACENAMIENTO DE LA INFORMACIÓN
M
sgBox (“Ejemplo de escritura de 3 registros en un archivo
secuencial”)
ChDir App.Path
Open “CLIENTES.TXT” For Output As #1
‘Primer cliente:
Print #1, “Juan Martínez”
Print #1, “Calle del Pez, 5”
Print #1, “Madrid”
Print #1, “<FIN>”
‘Segundo cliente:
Print #1, “Comercial Martínez”
Print #1, “Calle de la Cuesta, 10”
Print #1, “Sevilla”
Print #1, “<FIN>”
‘Tercer cliente:
Print #1, “José Sánchez”
Print #1, “Calle Mayor, 7”
Print #1, “Salamanca”
Print #1, “<FIN>”
‘Cerrar el archivo:
Close #1
MsgBox (“3 registros escritos.”)
Exit Sub
manejador:
MsgBox (Err.Description)
End Sub
1.5.1.3Actividad 1C: En lenguaje Java
En lenguaje Java, este fragmento de código fuente se encarga de generar
un archivo secuencial y rellenarlo con tres clientes, cerrando el archivo a
continuación.
import java.io.*;
43
GESTIÓN DE BASES DE DATOS
© RA-MA
public class Actividad1C
{
public static void main (String[] args)
{
FileWriter archivo = null;
try
{
System.out.println(“Ejemplo de escritura de 3
registros en un archivo secuencial\r\n”);
//Cliente 1:
archivo = new FileWriter(“CLIENTES.TXT”);
archivo.write(“Juan Martínez\r\n”);
archivo.write(“Calle del Pez, 5\r\n”);
archivo.write(“Madrid\r\n”);
archivo.write(“<FIN>\r\n”);
//Cliente 2:
archivo.write(“Comercial Martínez\r\n”);
archivo.write(“Calle de la Cuesta, 10\r\n”);
archivo.write(“Sevilla\r\n”);
archivo.write(“<FIN>\r\n”);
//Cliente 3:
archivo.write(“José Sánchez\r\n”);
archivo.write(“Calle Mayor, 7\r\n”);
archivo.write(“Salamanca\r\n”);
archivo.write(“<FIN>\r\n”);
archivo.close();
System.out.println(“3 registros grabados.\r\n”);
}
catch(IOException e)
{
System.out.println(“Error: “+e.toString());
}
}
}
1.5.1.4Actividad 1D: En lenguaje C#
En lenguaje C#, este fragmento de código fuente se encarga de generar
un archivo secuencial y rellenarlo con tres clientes, cerrando el archivo a
continuación.
44
© RA-MA
using
using
using
using
1
n
SISTEMAS DE ALMACENAMIENTO DE LA INFORMACIÓN
System;
System.Collections.Generic;
System.Text;
System.IO;
namespace Actividad1D
{
class Program
{
static void Main(string[] args)
{
StreamWriter archivo = null;
try
{
Console.WriteLine(“Ejemplo de escritura de 3
registros en un archivo secuencial”);
archivo = new StreamWriter(“CLIENTES.TXT”);
if (archivo!=null)
{
//Cliente 1:
archivo.WriteLine(“Juan Martínez”);
archivo.WriteLine(“Calle del Pez, 5”);
archivo.WriteLine(“Madrid”);
archivo.WriteLine(“<FIN>”);
//Cliente 2:
archivo.WriteLine(“Comercial Martínez”);
archivo.WriteLine(“Calle de la Cuesta, 10”);
archivo.WriteLine(“Sevilla”);
archivo.WriteLine(“<FIN>”);
//Cliente 3:
archivo.WriteLine(“José Sánchez”);
archivo.WriteLine(“Calle Mayor, 7”);
archivo.WriteLine(“Salamanca”);
archivo.WriteLine(“<FIN>”);
archivo.WriteLine();
//Cerrar el archivo:
archivo.Close();
Console.WriteLine(“3 registros grabados.”);
}
}
45
GESTIÓN DE BASES DE DATOS
© RA-MA
catch(IOException e)
{
Console.WriteLine(“Error: “+e.ToString());
}
}
}
}
1.5.2Actividad 2
Para esta actividad no es necesario recurrir a ninguno de los archivos
contenidos en el CD ROM que acompaña al libro.
Abrir el archivo con el bloc de notas de Windows (Notepad.exe) y verificar
que su contenido es legible.
En esta actividad verificaremos que el contenido generado dentro del
archivo secuencial se corresponde con texto y además veremos las diferencias
entre las diferentes páginas de códigos que usa por defecto cada lenguaje.
Para abrir los textos utilizaremos el bloc de notas de Windows.
En todos los ejemplos, el resultado será el mismo, pero con diferencias en
las páginas de código.
En el ejemplo de la actividad 1.1, 1.2 y 1.3, correspondientes respectivamente
al programa escrito en lenguaje C++ (Visual C++ v.6.0), el programa escrito en
Visual Basic 6.0 y el programa escrito en Java, el archivo resultado está escrito
en código ANSI de Windows.
En cambio, en el ejemplo de la actividad 1D, correspondiente al programa
escrito en C#, el resultado está escrito en Unicode de 8 bits (UTF-8), lo
cual quiere decir que no es compatible binariamente con los tres formatos
anteriores.
Este es un punto a tener en cuenta cuando debemos afrontar migraciones
de datos entre aplicaciones escritas en diferentes lenguajes.
46
© RA-MA
1
n
SISTEMAS DE ALMACENAMIENTO DE LA INFORMACIÓN
1.5.3Actividad 3
Escribir un programa de lectura de un archivo secuencial línea a línea
mediante un bucle que verifique el final de archivo.
1.5.3.1Actividad 3A: En lenguaje C++
Un programa mínimo de lectura de un archivo secuencial y salida hacia
pantalla quedaría así:
#include “stdafx.h”
#include <string.h>
//Actividad 3A:
//Lectura de archivo secuencial con tres clientes.
int main(int argc, char* argv[])
{
FILE * pArchivo = NULL;
char szLinea[255];
pArchivo = fopen(“CLIENTES.TXT”, “r”);
if (pArchivo)
{
while (!feof(pArchivo))
{
memset(szLinea, 0, sizeof(szLinea));
fgets(szLinea, 255, pArchivo);
//Eliminar último caracter LF:
*(szLinea + strlen(szLinea)-1)=0;
printf(“%s\n”, szLinea);
}
fclose(pArchivo);
}
return 0;
}
47
GESTIÓN DE BASES DE DATOS
© RA-MA
1.5.3.2Actividad 3B: En lenguaje Visual Basic 6.0
A continuación exponemos el código fuente contenido en una función que
reacciona a la pulsación de un botón. Lee el contenido del archivo secuencial
línea a línea y lo coloca en una caja de lista:
Private Sub Command1_Click()
Dim Linea As String
ChDir App.Path
Open “CLIENTES.TXT” For Input As #1
While Not EOF(1)
Line Input #1, Linea
List1.AddItem (Linea)
Wend
Close #1
Exit Sub
manejador:
MsgBox (Err.Description)
End Sub
1.5.3.3Actividad 3C: En lenguaje Java
Este es el programa Java que lee línea por línea un archivo secuencial:
import java.io.*;
public class Actividad3C
{
public static void main(String[] args)
{
File archivo = null;
DataInputStream flujo = null;
String strLinea = “”;
System.out.println(“Ejemplo de lectura de un archivo
secuencial\r\n”);
48
try
{
//Verificar si existe el archivo “CLIENTES.TXT”);
archivo = new File(“CLIENTES.TXT”);
if (archivo.exists())
© RA-MA
1
n
SISTEMAS DE ALMACENAMIENTO DE LA INFORMACIÓN
{
flujo = new DataInputStream(new
BufferedInputStream(new
FileInputStream(archivo)));
while (strLinea != null)
{
strLinea = flujo.readLine();
//o readUTF para UTF-16
if (strLinea!=null) System.out.println(strLinea);
}
}
flujo.close();
}
catch (EOFException e)
{
//Final de archivo
System.out.println();
}
catch (IOException e2)
{
System.out.println(e2.getMessage());
}
}
}
1.5.3.4Actividad 3D: En lenguaje C#
Este es el fragmento de código fuente que lee un archivo secuencial línea a
línea, escrito en C#. Reacciona a la pulsación de un botón sobre un formulario
de Windows.
private void button1_Click(object sender, EventArgs e)
{
StreamReader lector;
string strLinea;
try
{
lector = new StreamReader(“CLIENTES.TXT”);
while (!lector.EndOfStream)
{
49
GESTIÓN DE BASES DE DATOS
© RA-MA
strLinea = lector.ReadLine();
listBox1.Items.Add(strLinea);
}
lector.Close();
}
catch(IOException ex)
{
MessageBox.Show(ex.Message);
}
}
1.5.4Actividad 4
En esta actividad llevaremos a la práctica dos objetivos:
1. Escribir un programa de creación de un archivo de acceso aleatorio
para un archivo de clientes (CLIENTES.DAT) con un espacio de
almacenamiento de 10 registros, en el cual se escriban los tres primeros
clientes que ya utilizamos en el ejemplo anterior.
2. Escribir una función dentro de este programa que, dado un número de
registro entre 0 y 9, nos permita recuperar el contenido de uno de los
registros anteriores.
En este caso, por razones de espacio sólo elaboraremos el programa en C++.
Se trata de un programa Windows basado en un formulario en el que el código
fuente asociado a la pulsación de un botón genera el archivo de acceso aleatorio
y escribe los tres clientes iniciales de ejemplo.
typedef struct tagCliente
{
char Nombre[80];
char Direccion[100];
char Poblacion[50];
} cliente;
void CActividad4AView::OnCrearArchivo()
{
FILE * pArchivo;
tagCliente MiCliente;
tagCliente Cliente1;
50
© RA-MA
1
n
SISTEMAS DE ALMACENAMIENTO DE LA INFORMACIÓN
tagCliente Cliente2;
tagCliente Cliente3;
int nLongRegistro = sizeof(tagCliente);
int n;
pArchivo = fopen(“CLIENTES.DAT”, “wb”);
if (pArchivo)
{
//Escribir los 10 registros:
memset(&MiCliente, 0, sizeof(tagCliente));
for (n=0;n<10;n++)
{
fwrite(&MiCliente, sizeof(tagCliente), 1, pArchivo);
}
//Rebobinar a principio de archivo:
fseek(pArchivo, 0, SEEK_SET);
memset(&Cliente1, 0, sizeof(tagCliente));
strcpy(Cliente1.Nombre, “Juan Martínez”);
strcpy(Cliente1.Direccion, “Calle del Pez, 5”);
strcpy(Cliente1.Poblacion, “Madrid”);
fwrite(&Cliente1, sizeof(tagCliente), 1, pArchivo);
memset(&Cliente2, 0, sizeof(tagCliente));
strcpy(Cliente2.Nombre, “Comercial Martínez”);
strcpy(Cliente2.Direccion, “Calle de la Cuesta, 10”);
strcpy(Cliente2.Poblacion, “Sevilla”);
fwrite(&Cliente2, sizeof(tagCliente), 1, pArchivo);
memset(&Cliente3, 0, sizeof(tagCliente));
strcpy(Cliente3.Nombre, “José Sánchez”);
strcpy(Cliente3.Direccion, “Calle Mayor, 7”);
strcpy(Cliente3.Poblacion, “Salamanca”);
fwrite(&Cliente3, sizeof(tagCliente), 1, pArchivo);
fclose(pArchivo);
MessageBox(“Archivo aleatorio creado”, “Proceso
completado”, MB_OK);
}
}
51
GESTIÓN DE BASES DE DATOS
© RA-MA
Ahora vamos a tratar el siguiente objetivo: escribir una función dentro
de este programa que, dado un número de registro entre 0 y 9, nos permita
recuperar el contenido de uno de los registros anteriores.
void CActividad4AView::OnBuscarCliente()
{
// Obtener el número de registro que deseamos buscar:
UpdateData(TRUE);
//Comprobar que está dentro del rango:
if (m_NumRegistro < 0)
{
MessageBox(“No se puede buscar un número de registro
negativo.”, “Error”, MB_OK);
return;
}
if (m_NumRegistro > 9)
{
MessageBox(“Escoja un registro del 0 al 9”);
return;
}
//Llamar a la función de búsqueda:
BuscarCliente(m_NumRegistro);
}
void CActividad4AView::BuscarCliente(int nRegistro)
{
FILE * pArchivo;
tagCliente Cliente;
char szMensaje[1024];
int nPos;
pArchivo = fopen(“CLIENTES.DAT”, “r+”);
if (pArchivo)
{
//Hallar la posición en el archivo:
nPos = nRegistro * sizeof(tagCliente);
//Posicionarse:
fseek(pArchivo, nPos, SEEK_SET);
//Leer el contenido:
fread(&Cliente, sizeof(tagCliente), 1, pArchivo);
52
© RA-MA
1
n
SISTEMAS DE ALMACENAMIENTO DE LA INFORMACIÓN
sprintf(szMensaje, “Registro: %d\nNombre: %s\nDireccion: %s\
nPoblacion: %s\n”,
nRegistro, Cliente.Nombre, Cliente.Direccion, Cliente.
Poblacion);
}
}
MessageBox(szMensaje, “Registro leído:”, MB_OK);
fclose(pArchivo);
1.5.5Actividad 5
En esta práctica partiremos de un ejemplo que se encuentra realizado y
documentado en el CD ROM que acompaña al libro.
El ejemplo contiene clases de indexación mediante árbol binario realizadas
en C++.
El objetivo de esta práctica es ver cómo se integran estas clases en una
aplicación sencilla para indexar un archivo de clientes mediante una aplicación
en entorno Windows. El código fuente está realizado en Visual C++, pero las
clases de indexación pueden ser compiladas bajo Linux mediante el compilador
C de GNU.
Los ejemplos se encuentran en la carpeta \Actividades\Capítulo 1\
Actividad5 y dentro de esta carpeta encontraremos también un texto que
nos guiará a través de la aplicación de ejemplo y nos ayudará a hacer un
seguimiento de su código fuente.
53
GESTIÓN DE BASES DE DATOS
2
© RA-MA
RESUMEN DEL capítulo
Los antecesores de las bases de datos son los archivos de almacenamiento
de datos.
Históricamente se ha pasado por tres fases, que corresponden a los tres
tipos de archivo principales: archivos secuenciales, archivos de acceso
aleatorio y archivos indexados.
Especialmente estos últimos proporcionan una tecnología que está
presente en el diseño de los servidores de bases de datos relacionales
(SGBD).
Podemos escribir programas en diferentes lenguajes que trabajen con
estos tipos de archivos, los cuales siguen siendo una buena opción para
tareas sencillas y robustas.
2
n 1.
ejercicios propuestos
Para comprobar el funcionamiento
del proceso de búsqueda en un árbol
binario equilibrado (archivo indexado), estableceremos un punto de ruptura o break point en la línea 521 del
archivo BST.cpp. Recordemos que el
punto de ruptura se establece pulsando la tecla F9 habiendo situado el
cursor sobre esta línea. Se trata de la
instrucción while de la función Find
del árbol binario. Con este punto de
ruptura, si ejecutamos la aplicación
en modo depuración (tecla F5) y buscamos un cliente, iremos pasando
54
sucesivamente por esta función viendo si avanzamos hacia el puntero L
o hacia el puntero R hasta llegar a
la clave buscada o hasta llegar a un
nodo terminal (hoja) que no coincida
porque la clave no existe.
n 2.
Escribir un programa para guardar las apuestas de un partido de fútbol (por ejemplo, Barcelona-Madrid)
dentro de un archivo secuencial. Los
campos serán Nombre del apostante, Goles Barcelona, Goles Madrid y
Valor apostado.
© RA-MA
1
n
SISTEMAS DE ALMACENAMIENTO DE LA INFORMACIÓN
n 3.
Escribir un programa de búsqueda de apuesta que encuentre los ganadores de la apuesta a partir del
resultado de goles del Barcelona y de
goles del Madrid.
2
n 4.
Intentar estos mismos programas
mediante archivo de aceso aleatorio
o archivo indexado, a gusto del lector.
test de conocimientos
1
¿Qué tipo de archivos permiten la
lectura directa de los datos a partir
de su número de registro?
a)Archivo secuencial.
b)Archivo de acceso aleatorio.
c)Archivo indexado.
d)Todos los anteriores.
2
¿Qué tipo de archivos se relacionan
históricamente con los tambores de
cinta magnética?
a)Archivo secuencial.
b)Archivo de acceso aleatorio.
c)Archivo indexado.
d)Todos los anteriores.
4
¿Qué concurrencia permiten los
archivos de acceso aleatorio?
1. Monousuario.
2. Multiusuario.
5
¿Qué típica estructura de datos
se emplea en la construcción de
indexados?
a)La tabla.
b)La coliflor equilibrada.
c)El sarmiento (vine-to-tree / treeto-vine).
d)El árbol binario equilibrado.
3
¿Qué concurrencia permiten los
archivos secuenciales?
a)Monousuario.
b)Multiusuario.
55
Descargar