Вы находитесь на странице: 1из 25

1

Unidad No. 2
Nivel interno (almacenamiento de la base de datos)

2.1 Introducción
Campo
Un campo (Field) es el elemento de datos básico (es la unidad mínima de información
de un registro). Un campo individual contiene un valor único, y esta caracterizado por
su longitud y por el tipo de dato. Dependiendo del diseño del archivo, los campos
pueden ser de dos tipos:
• Tamaño fijo o
• Tamaño variable.
Un campo puede contener un subcampo. Æ POR EJ.: el campo fecha se divide en los
subcampos día, mes y año.

Registro
Registro (Record) es una colección de campos relacionados que pueden tratarse como
una única unidad por un programa de aplicación. Por ejemplo: un registro de empleados
va contener campos como nombre, número de seguro social, etc.
También dependiendo del diseño, los registros pueden ser de longitud fija o de longitud
variable. Un registro va a tener una longitud variable si algunos de los campos son de
tamaños variables o si el numero de campos es variable. Cada campo tiene un nombre
de campo.

Archivo (basado en los dos conceptos anteriores)


Es una colección de registros relacionados entre sí con aspectos en común y
organizados para un propósito específico.

Estructura de campos
Hay muchas formas de añadir estructura a los archivos para mantener la identidad de los
campos. Los tres métodos más comunes son:
• Forzar que los campos tengan una longitud predecible.
• Comenzar cada campo con un indicador de longitud, y
• Colocar un delimitador al final de cada campo para separarlo del siguiente.

Estructuras de registros
Al igual que un campo, un registro es otra herramienta conceptual. Es decir, es otro
nivel de organización que se impone sobre los datos para preservar su significado. Los
registros no necesariamente existen en el archivo en un sentido físico, sin embargo
constituyen una noción lógica importante incluida en la estructura del archivo.
Para organizar un archivo en registros existen varios métodos entre los cuales podemos
mencionar:
• Exigir que los registros sean de longitud predecible. Esta longitud puede
medirse en términos de bytes o en términos del número de campos.
Este método es análogo al primer método para reconocer campos, la diferencia
importante es que cuando se cuenta a lo largo de un registro se eligen las
unidades de conteo ya que se pueden contar bytes o campos.
2

o BYTES Æ Registros de longitud fija: un archivo con registros de


longitud fija es aquel cuyos registros contienen todos el mismo número
de bytes.
o Campos de conteo: en lugar de especificar que cada registro en un
archivo contiene un número fijo de bytes, se puede especificar que
contendrá un número fijo de campos.
• Comenzar cada registro con un indicador de longitud que señale el número de
bytes que contiene. En este caso la longitud es predeterminada, es decir, una
constante a lo largo del archivo.
• Usar un segundo archivo para mantener información de la dirección del byte de
inicio de cada registro. Este segundo archivo es el denominado archivo índice,
con el cual se mantiene la información sobre la distancia en bytes de cada
registro en el archivo original, y así facilitar el encontrar el registro buscado en
el archivo de datos.
• Colocar un delimitador al final de cada registro, para separarlo del siguiente.
Esta es la opción que a nivel de registro, es por completo similar a la solución
que se dio para distinguir los campos.

Mezcla de números y caracteres: representación hexadecimal


La mayoría de computadoras representan los bytes almacenados en un archivo de
manera hexadecimal, en donde, las longitudes de los campos de los registros son
almacenadas de esa manera. Esta forma nos ayuda a tomar una mejor idea de cómo
trabaja el sistema operativo la información almacenada.

Ejemplo:
Registro Æ Ames | John | 123
Representación Hexadecimal Æ
Intervalo Valores Hexadecimales
0 - F 2800416D 65737C4A 6F686E7C 31323320

En resumen: La mezcla de números y caracteres en una representación hexadecimal nos


ayuda a mostrar como una estructura de registros puede ser vista por el sistema
operativo con ayuda del subsistema Administrador de Archivos.

Formas de acceso a un archivo


Las formas de acceso a los datos almacenados en un archivo pueden ser varias entre las
cuales mencionaremos:
• Utilizar una función canónica de llaves: cuando se examina un registro
individual dentro de un archivo, es conveniente identificarlo con una llave que
se base en el contenido del registro. Por ejemplo, si se tiene un archivo de
alumnos una llave puede ser el nombre, pero ajustándose a la realidad es
necesario tener una regla o canon eficiente para que funcione como forma
exclusiva de identificar a un registro, a esto se le conoce como forma canónica
para una llave de búsqueda, lo cual es la representación única de esa llave,
entonces para este archivo de alumnos lo mejor es tener una llave de forma
canónica como el número de carné.
• Utilizar una búsqueda secuencial: esta forma de acceso se realiza por medio
de una búsqueda secuencial dentro del archivo, es decir, registro por registro,
buscando una llave en particular.
3

• Manejo de Registros en Bloques: esta es una mejora de la búsqueda


secuencial. Como vimos anteriormente el costo de desplazamiento y lectura de
un registro a otro es alto (costo de acceso a disco), pero el costo puede ser menor
si se tienen los registros almacenados en forma sucesiva, esto utilizando bloques
de registros. ES IMPORTANTE ACLARAR que el manejo de registros en
bloques no cambia el número de comparaciones que deben hacerse en memoria
RAM, al contrario es muy probable que el mismo se incremente debido a la
cantidad de datos transferidos, porque siempre se lee un bloque completo aun
cuando el registro que se busca sea el primero del bloque. Lo que hace este
manejo es AHORRAR TIEMPO, ya que disminuye el número de
desplazamientos del brazo de disco.
• Acceso Directo: se tiene acceso directo a un registro cuando es posible
colocarse directamente en el inicio del registro y leerlo. Esto se hace algunas
veces utilizando un archivo separado de índices, pero lo más recomendable es
realizar este acceso por medio de lo que se conoce como NRR (número relativo
de registro) en un archivo. La idea de un NRR es un concepto importante que
surge de la noción de ver a un archivo como un conjunto de registros, y no como
un conjunto de bytes. Si un archivo es una secuencia de registros, entonces el
NRR de un registro proporciona su posición relativa con respecto al principio
del archivo. Por ejemplo, el primer registro de un archivo tiene un NRR 0, el
siguiente tiene un NRR 1, y así sucesivamente. La utilización del acceso directo
por NRR implica el uso de registros de LONGITUD FIJA.
• Registros de Encabezado: este nos sirve para guardar información que puede
ser útil a la hora de realizar una búsqueda en un archivo. Por ejemplo, a veces
no es fácil saltar hasta el final de un archivo, pero una forma sencilla de
solucionar este inconveniente es colocar un registro de encabezado al principio
del archivo para guardar información como el contador del número de registros
del archivo que facilita esta acción. Los registros de encabezado son una
herramienta de diseño de archivos muy difundida e importante, por ejemplo,
cuando se desea construir un índice para un archivo generalmente se colocarán
registros de encabezado al principio de cada índice (identificado por una llave
según conveniencia) para mantener la información sobre datos como el NRR del
registro que es la base del índice.

Mantenimiento de archivos
El mantenimiento de archivos es necesario, ya que a medida que se hacen cambios en
los mismos, el desempeño de las aplicaciones o procesos se ven afectados
considerablemente.
En general el mantenimiento de archivos se basa en modificaciones que se hacen a los
mismos para su manejo y mejor administración. Las más generales son:
• Agregar un registro.
• Actualizar un registro.
• Eliminar un registro.
Una de las consecuencias de los cambios en los archivos es la FRAGMENTACION del
almacenamiento.
• Fragmentación interna: esta ocurre cuando existe espacio desperdiciado dentro
de un registro. Por ejemplo, en un archivo de registros de longitud fija, la
fragmentación interna puede ocurrir cuando se almacenan registros de longitud
variable en entradas de tamaño fijo (falta de espacio). También puede ocurrir en
4

un archivo de registros de longitud variable, cuando un registro se reemplaza por


otro de menor tamaño (desperdicio de espacio).
• Fragmentación Externa: esta ocurre cuando se crean espacios sin utilizar entre
registros, normalmente debido a eliminaciones.

Existen varias formas de combatir la fragmentación, la más sencilla es la compactación


del almacenamiento.

Compactación del almacenamiento


La técnica de compactación del almacenamiento implica trasladar todas las áreas
ocupadas de almacenamiento a algún extremo de la memoria secundaria. Esto deja un
gran espacio único de almacenamiento libre, en lugar de numerosos espacios pequeños
característicos de las particiones variables. Ahora todo el almacenamiento libre está
contiguo, así el trabajo en espera puede ejecutarse si sus necesidades de memoria son
satisfechas por el espacio disponible en la compactación. Algunas veces se le llama
"recolección de basura" (garbage collector).
Cuándo hacerlo:
• Periódicamente.
• Cuando queda poco espacio libre.
• Cuando no hay espacio libre.
Cómo hacerlo:
La técnica más sencilla y que normalmente funciona es colocar una marca
especial en cada registro eliminado, generalmente en el primer campo del registro, esto
con el afán de reconocer un espacio dejado por un registro y poder “saltarlo” y
encontrar la información de forma más rápida.
Desventajas
• Consume recursos del sistema que podrían utilizarse en forma productiva.
• El sistema debe atender todas sus actividades mientras tiene un funcionamiento
irregular para los usuarios que lo están usando y podría ser devastador en
sistemas de tiempo real.

Se ha identificado que la eliminación de registros es el factor principal que origina la


fragmentación, pero existen dos tipos de eliminación:
1. Eliminación de Registros de Longitud Fija
2. Eliminación de Registros de Longitud Variable

Eliminación de registros de longitud fija


Para cuando se hace una eliminación de registros es necesario garantizar dos cosas:
• Que los registros eliminados se marquen de alguna forma especial (como se vio
en la compactación), y
• Que se pueda encontrar el espacio que los registros eliminados ocupaban, para
reutilizarlo cuando se agreguen registros.
Existen varias formas de garantizar estas dos cosas en la eliminación de registros de
longitud fija:
Uso de Listas Ligadas: (esta es la 2da. Técnica de evitar la fragmentación)
Es una lista en la que se tiene todos los registros disponibles, donde la misma esta
compuesta por una estructura de datos en la que cada elemento o nodo contiene algún
tipo de referencia sobre su sucesor en la lista.
Cuando una lista esta compuesta de registros eliminados que se han convertido en
espacio disponible dentro del archivo, se llama comúnmente, lista de disponibles. Al
5

insertar un registro nuevo en un archivo de registros de longitud fija, cualquier registro


disponible es bueno. Es por ello que no hay razón para ordenar la lista en algún orden en
particular.
Uso de Pilas:
El modo más sencillo de manejar una lista es como si fuera una pila. Una pila es una
lista en donde todas las inserciones y eliminaciones de nodos se realizan en uno de los
extremos.

Eliminación de registros de longitud variable


Lista de disponibles de registros de longitud variable:
Al igual que la lista de disponibles en registros de longitud fija, podemos manejar de
igual manera una lista de disponibles con registros de longitud variable, con la
diferencia que con los registros de longitud fija no es necesario asegurarse de que una
entrada sea del tamaño correcto para almacenar el registro, cosa que para los de longitud
variable es importantísimo. La definición inicial de tamaño correcto se refiere
simplemente a que el espacio en donde se almacenará un registro debe ser lo
suficientemente grande. Esto es una función extra que se debe hacer para cada
inserción en un registro de longitud variable.

Fragmentación del almacenamiento


Como hemos visto la fragmentación que se desarrolla dentro de un archivo, es
consecuencia de la eliminación y la reutilización de registros. Ahora, algo importante
de recalcar es:
• La fragmentación puede ocurrir internamente cuando el espacio se pierde por
quedar encerrado dentro de un registro. Para evitarla se puede desarrollar un
procedimiento que divide una entrada grande de longitud variable en dos o más,
menores, usando exactamente el espacio necesario para un registro nuevo, y
dejando el resto en la lista de disponibles.
• Aunque el desarrollo de este procedimiento puede reducir la cantidad de espacio
desperdiciado, a la larga los fragmentos restantes son demasiado pequeños para
ser de utilidad. Cuando esto sucede, el espacio se pierde por fragmentación
externa. Para minimizar este tipo de fragmentación (como hemos visto), es
posible tomar varios caminos:
o COMPACTAR el archivo mediante procesamiento por lotes, cuando el
nivel de fragmentación se vuelve el excesivo;
o UNIR las entradas adyacentes (espacios) en la lista de disponibles para
formar segmentos más grandes y más útiles en general, y
o Adoptar una ESTRATEGIA DE COLOCACION para seleccionar las
entradas que se reutilizarán, de modo que se minimice la fragmentación.

Estrategias de colocación
Existen tres estrategias básicas de colocación o inserción de registros de longitud
variable, la cuales son:
• PRIMER AJUSTE, esta estrategia es la más sencilla, y consiste en que si la
entrada (espacio) es lo suficientemente grande, entonces es utilizado.
• MEJOR AJUSTE, se da cuando un registro nuevo se coloca en el espacio más
pequeño que sea lo suficientemente grande para almacenarlo. Esta es una
estrategia atractiva para archivos con registros de longitud variable donde la
fragmentación es interna, pero implica más gasto o costo en el rendimiento de
una aplicación que otras estrategias de colocación.
6

• PEOR AJUSTE, se da cuando un registro nuevo se coloca en la entrada más


grande disponible. La idea es que la porción que sobra del espacio sea lo más
grande posible.
Observaciones importantes:
9 Las estrategias de colocación tienen sentido sólo para archivos de registros de
longitud variable. Con registros de longitud fija, la colocación no importa.
9 Si el uso del espacio debido a la eliminación y reutilización de registros no es un
factor importante, porque hay bastante espacio o porque hay muy poca
eliminación, probablemente el primer ajuste es la estrategia apropiada, ya que
requiere el mínimo tiempo.
9 Si se pierde espacio debido a fragmentación interna, entonces la decisión esta
entre el primer ajuste y el mejor ajuste. Una estrategia del peor ajuste empeora
efectivamente la fragmentación interna.
Si se pierde espacio debido a fragmentación externa y no se utiliza el primer ajuste,
entonces se debe considerar cuidadosamente la estrategia del peor ajuste, la cual
requiere menos tiempo que el mejor ajuste y puede hacer que el grado de fragmentación
externa tienda a decrecer.

2.2 Introducción al acceso a la base de datos

Antes de iniciar una discusión acerca de las estructuras de almacenamiento en sí,


primero se considerará una introducción al proceso de acceso a la base de datos en
general. Localizar información en la base de datos y presentarla al usuario envuelve
varias capas del software de acceso de datos. Los detalles y la terminología de estas
capas varía considerablemente de sistema a sistema, pero los principios estándar
pueden ser explicados como sigue:
1. Primero el DBMS decide que registros almacenados son requeridos y pregunta
al “manejador de archivos” para recuperar estos registros.
2. El “manejador de archivos” decide que “página” contiene el registro deseado y
solicita al “manejador de discos” para que éste recupere la página. La página es
la unidad de I/O (input/output), esto es, la cantidad de datos transferidos entre el
disco y el almacenamiento principal en un único acceso a disco.
3. Finalmente, el “manejador de disco” determina la ubicación física de la página
deseada en el disco, y utiliza las operaciones necesarias de I/O sobre el disco.
(Nota: Algunas veces, la página requerida ya estará en un buffer en memoria
principal como el resultado de una recuperación previa, en este caso, obviamente
no será necesario recuperar de nuevo la información).
El DBMS tiene una vista de la base de datos como una colección de registros
almacenados, y esta vista es soportada por el “manejador de archivos” , éste tiene una
vista de la base de datos como una colección de páginas, y esta vista es soportada por el
“manejador de disco”; y éste último tiene una vista del disco como realmente es.

Manejador de disco
Es un componente del sistema operativo. Es el componente responsable por todas las
operaciones físicas de I/O (algunas veces se le llama componente básico de servicios de
I/O). Este componente, necesita darse cuenta de las direcciones físicas del disco. El
manejador de archivos ve el disco simplemente como una colección lógica de page sets,
cada uno de éstos consiste en un conjunto de páginas de tamaño fijo. Cada page set es
identificado por un identificador único de page set. Cada page es identificada por un
7

númerode página que es único dentro del disco, distintos page sets no se traslapan (no
tienen páginas en común). El mapeo entre números de página y las direcciones de disco
físicas es conocido y administrado por el manejador de disco. La mayor ventaja de la
existencia de este componente consiste en que todo el código específico para acceder
los dispositivos de almacenamiento puede ser concentrado dentro de un único
componente del sistema, y todos los componentes de niveles superiores
(particularmente, el manejador de archivos) puede ser independiente de éstos
dispositivos de almacenamiento.
Todo el conjunto de páginas en el disco está dividido en colecciones desconectadas de
subconjuntos llamadas page sets. Uno de estos page sets, el page set de espacio libre,
sirve como un pool de páginas disponibles ,los otros page sets son considerados para
contener información. El alojamiento y liberación de pages de y hacia los page sets es
desarrollado por el manejador de disco en demanda desde el manejador de archivos.
Las operaciones soportadas por el manejador dedisco sobre los page sets incluyen las
siguientes:
• Recuperar la page “p” desde el page set “s”
• Reemplazarla página “p” dentro del page set “s”
• Agregar una nueva página al page set “s”
• Remover la página “p” del page set “s”

Manejador de archivos
El manejador de archivos utiliza las capacidades del manejador de disco para facilitar
que el usuario (el DBMS) utilice el disco como una colección de archivos almacenados
(o tablas, donde son almacenadas todas las ocurrencias de un tipo de registro en
particular). Cada page set contendrá uno o más archivos almacenados (tablas). El
DBMS debe darse cuenta de la existencia de los page sets, aunque no es responsabe de
manejarlas en detalle. En particular, el DBMS necesita conocer cuando dos archivos
almacenados (tablas) compraten el mismo page set o cuando dos registros almacenados
comparten la misma page.
Cada archivo almacenado es identificado por un nombre de archivo o por un
identificador de archivo, el cual debe ser único por lo menos dentro del page set que lo
contiene, y cada registro almacenado, es identificado por un número de registro o
identificador de registro, único por lo menos dentro del archivo que lo contiene
almacenado.
En algunos sistemas el manejador de archivos es un componente del sistema operativo,
en otros es un paquete con el DBMS.
Las operaciones soportadas por el manejador de archivos incluye las siguientes:
• Recuperar el registro almacenado “r” del archivo “f”.
• Reemplazar el registro almacenado “r” dentro del archivo “f”.
• Agregar un nuevo registro almacenado al archivo “f” y retornar el nuevo
identificador de registro “r”.
• Remover el registro almacenado “r” del archivo “f”.
• Eliminar el archivo “f”.

Clustering
La idea básica detrás del clustering es almacenar y recuperar registros que están
lógicamente relacionados (y son frecuentemente utilizados juntos) y que se encuentran
físicamente cerca en el disco. El clustering físico de datos es extremadamente
importante en el rendimiento.
8

Un archivo (o conjunto de archivos) pueden estar en cluster físicamente en una sola


forma en un momento dado.
El DBMS puede soportar clustering, tanto interno como entre archivos, almacenando
registros lógicamente relacionados en la misma página cuando sea posible y en páginas
adyacentes cuando no sea posible. Cuando el DBMS crea nuevos registros, el
manejador de archivos debe permitir especificar que el nuevo registro será almacenado
cerca de otros registros existentes. El manejador de disco, hará su mejor esfuerzo para
asegurar que dos pages que son lógicamente adyacentes estén físicamente adyacentes en
el disco. Claro que el DBMS solo podrásaber el cluster requerido si el DBA es capaz de
proveerlo. Un buen DBMS permite al DBA especificar diferentes clases de cluster para
diferentes archivos. Deberá también permitir el actualizar el clustering para un archivo
dado (o para un conjunto de archivos) si los requerimientos de rendimiento cambian.

2.3 Page sets y archivos


Como se explicó en la sección anterior, la principal función del manejador de disco es
permitir que el manejador de archivos ignore los dealles del acceso físico al disco y los
visualice en términos de páginas lógicas de I/O. Esta función del manejador de disco se
conoce como administrador de páginas (page management). Se presentará la siguiente
secuencia de eventos para ejemplificar la forma en que se manejan los page sets y su
correlación con los archivos:

1. Inicialmente la base de datos no contiene datos. Esto es solamente un page set,


el page set de espacio libre, el cual contiene todas las páginas del disco –
excepto para la página cero, la cual es especial. El resto de páginas están
numeradas secuencialmente desde la página 1.
2. El manejador de archivos solicita la creación de page set para registros de
proveedores (S1, S2,…,S5) e inserta 5 registros para proveedores como se
muestra en la figura 2.1. El manejador de discos remueve las páginas 1-5 del
page set de espacio libre y lo etiqueta como el page set de proveedores.
3. De forma similar se pueden crear los registros de partes (P1, P2, …, P6) y de
pedidos (S1/P1, S1/P2, S1/P3, …,S4/P5). Ahora hay 4 page sets: El de
proveedores, el de partes, el de pedidos, y el de espacio libre (páginas 24, 25,
…). Esta situación se muestra en la figura 2.1.

Fig. 2.1
9

4. A continuación, el manejador de archivos inserta un nuevo registro de proveedor


(S6). El manejador de disco lo almacena en la primera página libre en el page
set de páginas libres (la página 24) y la agrega al page set de proveedores.
5. El manejador de archivo elimina el registro para el proveedor 2 (S2). El
manejador de disco devuelve la página para este proveedor (página 2) al page set
de páginas libres.
6. El manejador de archivos inserta un nuevo registro de partes (P7). El manejador
de disco lo almacena en la primera página libre del page set de espacio libre (la
página 2) y lo agrega al page set de partes.
7. El manejador de archivos eleimina el registro almacenado para el proveedor 4
(S4). El manejador de disco retorna la página 4 al page set de espacio
disponible.

Fig. 2.2
La situación se muestra en la figura 2.2. El punto acerca de esta situación radica en lo
siguiente: Después de que el sistema ha sido ejecutado por un tiempo, no se garantiza
que las páginas que están lógicamente adyacentes también están físicamente adyacentes.
Por esta razón, la secuencia lógica de las páginas en un page set dado debe
representarse, no por la adyacencia física, sino por punteros. Cada página contendrá un
page header que viene a ser un set de información de control que incluye la dirección
física de la página que le sigue inmediatamente en la secuencia lógica – ver la figura
2.3.

Fig. 2.3
10

• Los page headers (especialmente, el puntero de la siguiente página) son


administrados por el manejador de disco, éstos son completamente invisibles
para el manejador de archivos.
• Debido a que es deseable tener las páginas tanto lógica como físicamente
adyacentes, el manejador de disco normalmente almacena y devuelve páginas
hacia y desde page sets, no una a la vez como lo sugiere el ejemplo anterior, sino
a través de grupos contiguos físicamente o “extents” de 64 páginas a la vez.
• Cómo sabe el manejador de disco donde están almacenados varios page sets? O,
dicho de otra forma, Cómo sabe, para cada page set, dónde está almacenada la
primera página del page set? La respuesta es que algunas partes fijas de los
discos (típicamente el cilindro cero, track cero) es usada para almacenar una
página que da precisamente esta información. Esta página, también llamada
Tabla de contenidos del disco, Directorio del disco, Directorio de page sets, o
simplemente página cero) la cual contiene una lista de page sets que actualmente
existen en el disco, junto con punteros hacia la primera página de cada page set
(ver figura 3.4).

Fig. 3.4
Ahora, regresamos al manejador de archivos. Tal como el manejador de disco permite
que el manejador de archivos ignore los detalles del acceso físico a disco y poder ver la
mayor parte de la base de datos en términos de páginas lógicas, el manejador de
archivos permite al DBMS ignorar detalles de páginas de I/O y visualizar la base de
datos en términos de registros y archivos almacenados. Esta función del manejador de
archivos es conocida como administrador de registros almacenados (stored record
management).

Si una página puede acomodar múltiples registros almacenados (no uno como en el
ejemplo anterior) e interesa que los registros estén almacenados siguiendo el orden del
código, considere la siguiente secuencia de eventos:
11

1. Los primeros 5 registros almacenados de proveedores (S1-S5) son insertados y


son almacenados juntos en la misma página p, como se muestra en la figura 3.5.
Note que la página p todavía contiene una cantidad considerable de espacio
libre.

Fig. 3.5
2. Ahora el DBMS inserta un nuevo registro de proveedor (S9). El manejador de
archivo almacena este registro en la página p (porque todavía tiene espacio
libre), inmediatamente después del registro del proveedor S5.
3. El DBMS elimina el registro almacenado para el proveedor 2 (S2). El
manejador de archivo elimina el registro S2 de la página p, y corre los registros
de pos proveedores S3, S4, S5 y S9 para llenar el espacio libre.
4. El DBMS inserta un nuevo registro de proveedor (S7). De nuevo el manejador
de archivo almacena este registro en la página p, ubica el nuevo registro
inmediatamente después del proveedor S5, corriendo el registro del proveedor
S9 hacia delante. Esta ilustración se muestra en la figura 3.6.

Fig. 3.6
12

El punto en este ejemplo es que la secuencia lógica de los registros almacenados dentro
de una página dada, puede ser representada por una secuencia física dentro de la página.
El manejador de archivos correrá registros individuales hacia a tras o adelante para
lograr este efecto, manteniendo todos los registros de datos juntos al inicio de la página
y todo el espacio libre junto al final.
Como se explicó anteriormente, los registros almacenados se identifican internamente
por un ID de registro o RId, la figura 3.7 muestra una implementación típica de un RID.
El RID para un registro almacenado r consiste de dos partes: el número de página p que
contiene el registro “r”, y el byte offset desde el pie de la página p identificando un spot
que contiene, el byte offset del registro “r” desde el inicio de la página “p”.

Fig. 3.7

INDEXACIÓN O INDIZACIÓN
CONCEPTO DE INDICE
Un índice se puede definir como una estructura de datos que contiene una función,
donde el argumento de la función es una clave y el valor de la función es un número de
registro. En otras palabras, con un índice es posible encontrar un número de registro
asociado al valor de clave dado.

Mientras que el archivo por sí mismo podría considerarse como un índice, sería un
índice muy ineficiente si empleáramos algoritmos como los que se usan en búsquedas
secuénciales para encontrar el número de registro.
Por lo tanto, un índice es normalmente una estructura separada del archivo, no sólo
lógicamente, como en un archivo secuencial indizado, sino también físicamente
separada, como cuando el índice se localiza en un archivo aparte.

IMPORTANTE: La indización consiste en proporcionar varios caminos de acceso a los


registros de un archivo.

Igual que hay muchas formas de estructurar archivos, hay muchas formas de estructurar
índices, empezaremos por la más elemental, un índice sencillo o simple.
13

Indice sencillo con entradas secuenciales


Los índices simples son llamados así porque se representan mediante arreglos simples
de estructuras que contienen las llaves y los campos de referencia.

El índice de un archivo secuencial indexado está mezclado con los datos del archivo.
Normalmente, la mayoría de los bloques son usados para los datos, pero algunos son
usados para el índice.

La principal ventaja de un archivo secuencial indexado es que la búsqueda binaria del


archivo ordenado puede ser reemplazada por un árbol de búsqueda de índices, siendo
ésta una solución más eficiente que las búsquedas binarias.

Operaciones básicas en un archivo indizado con entradas secuenciales


El manejo y mantenimiento de un archivo con entradas secuenciales acoplado a un
índice simple requiere el desarrollo de procedimientos para el manejo de varias tareas u
operaciones elementales.
Entre ellas podemos mencionar:
• Crear los archivos vacíos originales de índices y datos Æ tanto el archivo de
índice como el archivo de datos se crean como archivos vacíos, con registros de
encabezado y nada más.
• Cargar el archivo de índices en la memoria antes de usarlo Æ se supone que el
archivo de índice es lo suficientemente pequeño para caber en la memoria
primaria. Generalmente se define una estructura parecida a un arreglo, para que
cada elemento del arreglo tenga una estructura de un registro de índice.
• Reescribir el archivo de índices de la memoria después de usarlo Æ esto se hace
cuando se termina el procesamiento de un archivo indizado, ya que puede haber
cambiado el arreglo en alguna forma, por lo que se deben considerar 2 factores
para asegurar que se ejecuta la reescritura:
o Debe existir un mecanismo que permita al programa o proceso saber
cuando el índice no está actualizado. Una posibilidad consiste en activar
una bandera de estado tan pronto como la copia del índice en la memoria
cambie. Esta bandera de estado se puede escribir en el registro de
encabezado del archivo de índices del disco en cuanto se ha leído el
índice en la memoria, y se puede desactivar después cuando el índice se
haya reescrito. Todos los programas podrían revisar que la bandera está
activa, entonces el programa podra saber si el índice no está actualizado.
o Si un programa detecta que un índice no esta actualizado, debe acceder a
un procedimiento que reconstruya el índice a partir del archivo de datos.
Esto debe suceder automáticamente, antes de cualquier intento de usar el
índice.
• Agregar registros al archivo de datos y al índice Æ cuando se agrega un registro
nuevo al archivo de datos se requiere también que se agregue un registro al
archivo de índices. El procedimiento preciso depende del tipo de organización
de registros de longitud variable que se use. En cualquier caso, cuando se
agrega un registro de datos se debe conocer la distancia inicial en bytes de la
posición física del registro respecto al inicio del archivo donde se escribió. Esta
información debe colocarse en el “arreglo” (definido para cargar el archivo de
índices en memoria) junto con la forma canónica de la llave de registro.
14

• Eliminar registros del archivo de datos Æ los métodos para esto los vimos en la
unidad anterior (uso de listas ligadas, uso de pilas). Por supuesto que cuando se
elimina un registro del archivo de datos también debe eliminarse el registro
correspondiente del archivo de índices. Como el índice está contenido en un
arreglo durante la ejecución del programa, la eliminación del registro de índice y
el desplazamiento de los demás registros para agrupar el espacio puede ser una
operación no muy costosa.
• Actualizar registros del archivo de datos Æ esta entra en dos categorías:
o La actualización cambia el valor del campo de llave: esta clase de
actualización puede traer consigo un reacomodo del archivo de índices,
así como del de datos. Puede implementarse un método de eliminar y
agregar, y dar al usuario del programa la impresión de que simplemente
está cambiando un registro.
o La actualización no afecta el campo de llave: aquí si se requiere
reacomodo del archivo de datos, pero no del archivo de índices. Si el
tamaño del registro no cambia, o si disminuye por la actualización, el
registro puede escribirse directamente en el espacio que tenía, pero si
aumenta por la actualización, se tendrá que encontrar una nueva entrada
para el registro.

Indices secundarios
Los índices secundarios, son índices que se aplican sobre uno o más campos de los
registros del archivo, que por su uso, se requiere poder localizar rápidamente los
registros a partir de éstos campos. Así en una biblioteca podríamos utilizar el catálogo
de la biblioteca con un Autor (llave secundaria) y un número de catálogo de tarjetas
(llave primaria).
Igual se pueden realizar:
• Adición de registros
• Eliminación de registros
• Actualización de registros

• ADICIÓN DE REGISTROS: cuando un índice secundario está presente, agregar


un registro al archivo significa agregar un registro al índice secundario. El costo
que implica esto es similar al que representa agregar un registro al índice
primario: se necesita mover los registros o reacomodar una estructura parecida a
un vector de apuntadores a los registros. Como con los índices primarios, el
costo disminuye mucho si el índice secundario puede trasladarse a la memoria
electrónica y modificarse allí. Una diferencia importante entre un índice
secundario y uno primario es que un índice secundario puede contener llaves
duplicadas.
• ELIMINACIÓN DE REGISTROS: la eliminación de un registro implica la
eliminación de todas las referencias a este registro en el sistema de archivos, de
modo que eliminar un registro del archivo de datos significa la eliminación no
sólo del registro correspondiente en el índice primario, sino también de todos los
registros de los índices secundarios que hacen referencia a este registro del
índice primario. La eliminación de un registro puede implicar el reacomodo de
los registros restantes, para cerrar el espacio abierto dejado por la eliminación.
• ACTUALIZACIÓN DE REGISTROS: se dan tres posibles situaciones:
15

o La actualización cambia la llave secundaria: si se cambia la llave


secundaria, probablemente habrá que reacomodar el índice secundario de
tal forma que permanezca en el orden de clasificación. Esto puede ser
una operación relativamente costosa.
o La actualización cambia la llave primaria: este tipo de cambio tiene
gran repercusión en el índice de la llave primaria, pero con frecuencia
sólo requiere que se actualice el campo de referencia afectado en todos
los índices secundarios. No se requiere la reclasificación de los índices
secundarios, a menos que la llave secundaria correspondiente aparezca
más de una vez en el índice.
o La actualización se restringe a los otros campos: las actualizaciones que
no afectan los campos de la llave primaria o secundaria no afectan el
índice de llaves secundarias, aunque la actualización sea considerable.
Listas invertidas
A los archivos que son como los índices secundarios, en los que una llave secundaria
lleva a un conjunto de una o más llaves primarias, se les llama listas invertidas. El
sentido el que se invierte una lista debe quedar claro si se considera que se trabaja
retrocediendo de una llave secundaria a la llave primaria y al registro mismo.
En resumen, el término lista invertida se refiere a los índices en donde una llave puede
asociarse con una lista de campos de referencia que apuntan a objetos que contienen la
llave.
La ventaja de este tipo de estructuras es que en el momento de agregar o insertar una
llave secundaria, únicamente se reacomoda la lista asociada a la llave primaria, la cual
puede llegar a tener una cantidad de registros grande.
Por supuesto, también existen desventajas, entre las cuales la más seria es que el archivo
demuestra menos localidad: es menor la probabilidad de que las listas de registros
asociados estén físicamente adyacentes. Un buen antídoto para este problema es
almacenar el archivo de listas ligadas en la memoria. Esto resulta más factible porque
un único archivo de referencias primarias puede ligar las listas para varios índices
secundarios.
Las listas invertidas proporcionan gran capacidad y flexibilidad para el uso de archivos
pequeños que contengan no más de algunos miles de registros.
Lo mejor es agregar un archivo que contenga las listas ligadas de referencias
(invertidas), ya que proporciona algunas ventajas sobre las estructuras consideradas
hasta este punto, las cuales son:
• El único momento en que se requiere reacomodar el archivo de índices
secundarios es cuando se añade una llave primaria o se cambia una existente.
• En caso de que sea necesario reacomodar el archivo de índices secundarios, la
tarea esa ahora más rápida, ya que existen menos registros y cada registro es más
pequeño.
• Puesto que hay menos necesidad de clasificaciones, es menor el precio que hay
que pagar por mantener los archivos de índices secundarios en el
almacenamiento secundario, por lo que queda más lugar en la memoria RAM
para otras estructuras de datos.
16

Indices con estructura de árbol


Un índice árbol es uno en el que hay una jerarquía de índices. La raíz del primer nivel
de índices apunta al segundo nivel de índices. Cada nivel de índices apunta a los niveles
menores hasta el más bajo o hasta que los nodos hoja son alcanzados. Los nodos hoja
tienen punteros al archivo de datos sólo. El índice usado con el archivo secuencial
indexado es un índice árbol.

El uso de un árbol es porque provee de las siguientes ventajas:

• Flexibilidad: Un árbol permite que datos almacenados sean procesados de


diferentes modos de manera relativamente eficiente, por ejemplo, directamente o
secuencialmente. Un árbol puede no ser la mejor estructura de datos para un
único propósito, pero su flexibilidad la hace a menudo la mejor para múltiples
propósitos.
• Eficiencia de búsqueda: Un árbol intenta la búsqueda eficiente de los datos, para
cuando una rama del árbol pueda ser podada en una búsqueda, esto significa que
todos los datos en esa rama no necesitan procesarse más tarde. Una estructura de
árbol puede a menudo usarse como un mecanismo de filtrado en localizar un
elemento de información deseado. Como procedemos a lo largo de la estructura
de árbol, filtraremos los datos no deseados.
• Naturalidad en la representación: Un árbol es normalmente una forma natural
de representar información. Lo que estamos describiendo puede tener relaciones
de padres, descendencia y hermanos que encajan fácilmente en una estructura de
árbol. Un problema se resuelve fácilmente si tenemos una representación
sencilla.
• Poder de representación: Un árbol hace a veces posible una aplicación, que de
otro modo no podría ser.
• Los árboles han sido siempre una estructura de datos importante, y es probable
que lo continúen siendo por las razones mencionadas.

Tipos de árbol
• Árboles heterogéneos y homogéneos.
• Índices Árbol-B

Arbol binario
Un árbol de búsqueda binario es un árbol binario en el que los nodos se usan tanto para
almacenar información como para proporcionar la dirección hacia otros nodos. La
información se organiza de manera que todas las claves menores que la del nodo actual
se encuentran en el subárbol izquierdo y aquellas mayores están en el subárbol derecho.

Arbol AVL
El árbol AVL toma su nombre de quienes lo originaron, Adelson-Velskii y Landis. Un
árbol AVL es un árbol de búsqueda binario en el que los subárboles de un nodo se
mantienen aproximadamente a la misma altura (o profundidad). Transformaciones en el
árbol binario mantendrán su altura equilibrada.

Arbol B
El árbol B es una de las estructuras de datos más importantes en informática por sus
características de versatilidad y rendimiento. Es una buena elección para el
17

almacenamiento de datos que deben ser accedidos tanto directamente como


secuencialmente.
La composición de un nodo de árbol B es similar a un bucket o bloque de registros en el
que se contiene además múltiples entradas. El número de registros que deben
almacenarse en un nodo es dependiente del orden de capacidad. El orden de capacidad y
otras restricciones en un árbol, B se especifican en su definición formal.

Arbol B* y B#
Un árbol B# es un árbol B en el que las operaciones de división e inserción se procesan
de un modo que pospone la división y como resultado posee una mayor utilización del
espacio y un rendimiento de recuperación más rápido que un árbol B. Todos los nodos
de un árbol B# son del mismo tamaño, de modo que es esencialmente un árbol B con un
algoritmo de inserción modificado.
Básicamente los B# y B* son bastante similiares, siendo la diferencia principal que el
nodo raíz en un árbol B* es mayor que los otros nodos en el árbol y puede contener
4d+1 registros

Arbol B+
Un árbol B+ es un árbol B en el que los registros de datos están contenidos en nodos
terminales, y los nodos no-terminales, que sólo contienen valores de claves, forman un
índice en los nodos de datos. Una ventaja es que es normalmente menos profundo que
un árbol B con los mismos datos, lo que significa que se necesitan menos pruebas para
un acceso directo.
18

Hashing (Hash-addressing)
Es una técnica para proveer un rápido acceso directo a un registro almacenado basado
en un valor almacenado para algún campo. El campo en cuestión es usualmente, pero
no necesariamente la llave primaria. En general, la técnica funciona de la siguiente
forma:
• Cada registro almacenado es colocado en la base de datos en una posición cuya
dirección (RID o solo el número de página) es calculada como alguna función
(la función de hash) de algún campo del registro (el campo hash, o la llave
hash). La dirección calculada es llamada la dirección de hash.
• Para almacenar inicialmente el registro, el DBMS calcula la dirección de hash
para el nuevo registro y da instrucciones al manejador de archivo para ubicar el
registro en esta posición.
• Para recuperar el registro posteriormente, se da el valor del campo de hash, el
DBMS realiza el mismo cálculo que utilizó para almacenar el registro y da
instrucciones al manejador de archivos para recuperar el registro en la posición
calculada.

Por ejemplo, suponiendo (a) que las llaves primarias de los proveedores son S100,
S200, S300, S400, S500, y (b) que cada registro de proveedor almacenado requiere una
página (page) entera para ser almacenado, y considere la siguiente función de hash:
Hash address (page number del ej.) = Residuo de divider la parte numérica de la
llave S# dentro de 13.
Este es unejemplo de una clase muy común de función de Hash llamada
“división/residuo” (normalmente se utilizan números primos para realizar la división).
Los números de página (pages) para los cinco proveedores son 9,5,1,10 y 6
respectivamente, lo cual se representa en la figura 3.8

Fig. 3.8

Como podemos observar, una diferencia notoria entre hashing y el uso de índices radica
en que un archivo almacenado puede tener cualquier número de índices, pero puede
tener a lo sumo una estructura de hash, en otras palabras, Un archivo puede tener
cualquier número de campos índices, pero un solo campo hash.

Adicionalmente, para mostrar como trabaja el hashing, el ejemplo también muestra por
qué la función de hash es necesaria. Podría teóricamente ser posible la utilización de
una función de hash de identidad – Ej. Usar el valor de una llave primaria numérica para
un registro almacenado directamente como la dirección hash. Esta técnica generalmente
es inadecuada en la práctica, porque el rango de posibles valores de llave primaria
usualmente es mucho mayor que el rango de direcciones disponibles, por esto, para
19

evitar un desperdicio considerable de espacio de almacenamiento, idealmente debemos


encontrar una función de hash que reduzca este rango de posibles valores de llave
primaria.

El ejemplo también muestra una de las desventajas del hashing: La secuencia física de
registros dentro del archivo almacenado casi con certeza no será la secuencia de la llave
primaria ni alguna otra secuencia que pudiera ser interpretada de forma lógica.

Otra desventaja del hashing en general es que en ella siempre existe la posibilidad de
colisiones – esto es, dos o más registros distintos que calculen la misma dirección hash.
Por ejemplo, si se incluyera el proveedor número S1400 al ejemplo anterior. La función
función de hash llega a ser inadecuada y requiere ser extendida con algún algoritmo que
resuelva el problema de las colisiones.

En términos del ejemplo original, una posible solución al problema de las colisiones
podría ser considerar el residuo de la división entre 13, no como la dirección de hash en
sí, sino más bien como el punto de inicio para una lectura secuencial. Entonces, al
insertar al proveedor S1400 se encontraría la página (page) 9 y se buscaría hacia delante
la primera página (page) disponible. Este método de búsqueda lineal puede ser
adecuado si múltiples registros son almacendados en cada página, lo cual es común en
la práctica, entonces, las primeras “n” colisiones de alguna dirección hash “p” serían
almacenadas en la página (page) “p”, y una búsqueda lineal completa podría ser
ejecutada dentro de esta página (page). Sin embargo, la siguiente (n+1)va colisión
tendría que ser almacenada en la siguiente página de sobrecarga y sería necesaria otra
operación I/O a disco.

Otra técnica para solucionar el problema de las colisiones, probablemente más utilizado
en sistemas reales, consiste en tratar la función de hash como la dirección de
almacenamiento no del registro de datos en sí, sino más bien como un “punto de
anclaje”. El punto de anclaje de una dirección de almacenamiento “a” es tomado como
el inicio de una cadena de punteros (una cadena de colisiones) enlazando juntos todos
los registros – o todas las páginas de registros – que colisionen en “a”. Dentro de una
cadena de colisión dada, la colisión típicamente podrá ser guardada en una secuencia del
campo hash, para simplificar búsquedas posteriores.

Hashing extendido
Otra desventaja del hashing visto anteriormente, es que de la misma forma que el
tamaño del archivo de datos se incremente el número de colisiones también tenderá a
incrementarse, y por consecuencia el tiempo promedio para acceder los datos se
incrementará directamente (porque más y más tiempo se utilizará buscando dentro de
conjuntos de colisiones). Eventualmente, llegará un momento en que será deseable
reorganizar el archivo, por ejemplo, descargando el archivo existente y recargandolo
utilizando una nueva función de hash.

El hashing extendido es una buena variación de la idea del hashing básico que alivia los
problemas anteriores. En efecto, el hashing extendido garantiza que el número de
accesos a disco necesarios para localizar un registro específico, nunca será mayor que
dos, y usualmente será un solo acceso y adicionalmente, garantiza que la reorganización
del archivo nunca será requerida.
20

Una característica importante del esquema de hashing extendido es que los valores del
campo hash deben ser únicos, lo cual significa que estos campos serán las llaves
primarias del archivo.

En general el esquema trabaja como sigue:


1. Si la función de hash básica es h, y el valor de la llave primaria de algún registro
r es k. Evaluando h(k) se obtiene un valor s llamado pseudollave de r. Las
pseudollaves no son interpretadas directamente como direcciones, pero apuntan
hacia direcciones de almacenamiento de forma indirecta.
2. El archivo almacenado tiene un directorio asociado, también almacenado en el
disco. El directorio consiste de un encabezado, conteniendo un valor d llamado
profundidad del directorio, junto con punteros secundarios. Los punteros
apuntan a páginas de datos, las cuales contienen los registros almacenados
(múltiples registros por página). Un directorio de profundidad d puede manejar
un archivo de tamaño máximo de 2d distintas páginas de datos.
3. Si consideramos el bit más importante d de una pseudollave como un entero
binario sin signo b, entonces el i-ésimo puntero en el directorio (donde 1 <= i <=
2d ) apunta a la página que contiene todos los registros para los cuales b toma el
valor i-1. En otras palabras, el primer puntero apunta a la página que contiene
todos los registros para los cuales b siempre es zero, el segundo puntero apunta a
la página para la cual b es 0…01, y así sucesivamente. Estos 2d punteros
normalmente no son todos distintos; esto es, son normalmente menores que 2d
distintas páginas de datos (Ver figura 3.9), entonces, para encontrar el registro
teniendo la llave primaria de valor k, aplicamos la función de hash k para
encontra la pseudollave s y tomamos los primeros d bits de esta pseudosllave; si
aquellos bits tienen el valor numérico i-1, vamos al i-ésimo puntero en el
directorio (primer acceso a disco) y lo seguimos a la página que contiene el
registro contenido (segundo acceso a disco).
(Nota: En la práctica, el directorio normalmente es lo suficientemente pequeño
para permanecer completo en la memoria principal la mayor parte del tiempo,
entonces estos 2 accesos a disco se reducen a 1 acceso a disco).
4. Cada página de datos también tiene un encabezado que da la profundad local p
de esta página (p<=d). Suponiendo, por ejemplo, que d es tres, y que el primer
puntero en el directorio (el puntero 000) apunta a la página para la cual su
profundidad local p es dos. La profundad local dos significa que esta página no
solo contiene registros cuya pseudollave empieza 000, sino que contiene todos
los registros cuya pseudollave empieza 00 (ejemplo, todos aquellos que
empiezan con 000 y 001), en otras palabras, El puntero 001 del directorio
también apunta hacia esta página. (Ver figura 3.9 de nuevo)
5. Continuando el ejemplo del párrafo 3, suponiendo ahora que la página de datos
000 esta llena y deseamos insertar un nuevo registro teniendo una pseudollave
que empieza 000 o 001. En este punto la página se rompe en dos; esto es, se
requiere una nueva página vacía y todos los registros 001 son movidos fuera de
la página antigua y son colocados en la nueva página. El puntero 001 del
directorio es cambiado para que apunte a la nueva página (el puntero 000 sigue
apuntando a la página antigua). La profundidad local p para cada página se
convierte ahora en tres (cambia de dos).
6. Ahora, suponemos que la página de datos para 000 se llena de nuevo y se debe
partir de nuevo. El directorio existente no puede manejar una nueva división,
porque la profundidad local de la página es igual a la profundidad del directorio.
21

Entonces se duplica el directorio, esto es, se incrementa d en uno y se reemplaza


cada puntero por un par de punteros idénticos adyacentes. Ahora la página de
datos puede ser dividida; los registros con pseudollave 0000 quedan en la página
antigua y los registros con pseudollave 0001 van a la nueva página; el primer
puntero en el directorio no se modifica (todavía apunta a la página antigua), el
segundo puntero cambia para apuntar a la nueva página. (Nota: duplicar el
directorio es una operación poco costosa, ya que no involucra acceso a alguna de
las páginas de datos)

Fig. 3.9
22

Cadena de punteros
Para realizar acceso directo a los datos, se puede utilizar una representación de
cadena de punteros, esta representación puede llegar a ser mejor que la utilización de
índices, pero no necesariamente esto siempre se cumple. Esta representación se ilustra
en la figura 3.10. Como se puede observar, el ejemplo involucra 2 archivos de datos, el
de proveedores y el de ciudades. En la representación de cadenas de punteros de la
figura 3.10, no es un archivo índice, sino más bien es referenciado como un archivo
maestro. El archivo de proveedores es referido como un archivo detalle, en general la
estructura es un ejemplo de una estructura conocida como organización maestro detalle.

Fig. 3.10 Ejemplo de una cadena de punteros

En el ejemplo, la estructura maestro/detalle se basa en los valores de ciudad de


los proveedores. El archivo maestro contiene un registro almacenado para cada ciudad
distinta contenida en el archivo de proveedores, almacenando el valor de la ciudad y
actuando como el inicio de una cadena o anillo de punteros enlazando todos los
registros del archivo detalle de proveedores en esta ciudad. Note que el campo ciudad
ha sido removido del archivo de proveedores. Para encontrar todos los proveedores en
Londres, por ejemplo, el DBMS puede buscar en el archivo de ciudades la entrada
Londres y luego seguir la correspondiente cadena de punteros.
La principal ventaja de la estructura maestro/detalle (cadena de punteros) es que
los algoritmos para insertar/eliminar son muy simples, y pueden ser considerablemente
más eficientes que sus algoritmos correspondientes en un índice; también, la estructura
probablemente ocupará menos almacenamiento que la estructura correspondiente de
índice, porque cada valor de ciudad aparece exactamente una vez en lugar de múltiples
veces. Las principales desventajas son las siguientes:
• La única forma de acceder a los registros del archivo detalle es seguir la cadena
de punteros, y si éstos registros (del detalle) no están almacenados correctamente
(en cluster), entonces, el tiempo de acceso puede llegar a ser considerable.
• Si se desea realizar la búsqueda conociendo la llave del archivo detalle, es
mucho más eficiente utilizar un índice o direcciones hash, en este caso la
estructura maestro/detalle no hace sentido. Además, cuando se localiza un
registro del detalle, todavía es necesario seguir la cadena para obtener el registro
maestro y así conocer el valor del archivo maestro.
• Normalmente, la estructura maestro/detalle requiere del auxilio de índices o
direccionamientos hash.
23

• Debido a que las cadenas de punteros existen dentro de los registros


almacenados, y a que datos relevantes de los archivos detalle son colocados en
registros del archivo maestro, se debe realizar la tarea para crear la estructura
maestro/detalle sobre un conjunto de registros existentes. En efecto, tal
operación normalmente requiere reorganización de la base de datos.

Variaciones posibles a la estructura básica de maestro/detalle:


• Utilizar punteros dobles para poder movilizarse en ambos sentidos dentro de las
cadenas de punteros.
• Incluir un puntero (un puntero al maestro) en cada registro del detalle.
• No remover los campos que asocian al detalle del maestro.

Técnicas de compresión
Las técnicas de compresión son formas para reducir la cantidad de almacenamiento
requerido para un conjunto dado de datos almacenados. Frecuentemente el resultado de
tal compresión será, no solamente el ahorro en espacio de almacenamiento, sino
también (y probablemente más importante), el ahorro en accesos a disco, ya que si la
información ocupa menos espacio, se requerirán menos operaciones a disco para
accederla. Por otra parte, operaciones extras de CPU serán necesarias para
descomprimir la información después de que ha sido recuperada.

Una técnica común de compresión consiste en reemplazar cada valor individual de los
datos por alguna representación de la diferencia entre éste y el valor que lo precede
inmediatamente, esta técnica es conocida como “compresión por diferencia”. Esta
técnica requiere que los datos sean accedidos en forma secuencial, ya que la
descompresión de un valor almacenado requiere el conocimiento del valor almacenado
inmediatamente antes. La compresión por diferencia puede aplicarse en situaciones en
que los datos normalmente se acceden en forma secuencial, como es el caso de los
índices simples. En el caso especial de los índices, los punteros pueden ser
comprimidos de mejor forma que los datos, además, si el orden lógico de los datos
impuesto por el índice es el mismo, o muy parecido, al orden físico del archivo
asociado, entonces los valores sucesivos de los punteros en el índice serán muy
similares unos de otros, y la compresión de punteros será muy eficiente y beneficiosa.
Efectivamente, los índices son grandes candidatos a utilizar técnicas de compresión.

Compresión jerárquica
Si un archivo almacenado es físicamente secuencial (en cluster) a través de valores de
algún campo F, y ocurre que para cada valor distinto de F ocurren en varios registros
consecutivos del archivo. Por ejemplo, el archivo de proveedores podría estar en cluster
por los valores del campo ciudad, en esta situación, todos los proveedores en la ciudad
de Londres estarían almacenados juntos, todos los de París, también estarían
almacenados juntos y así sucesivamente, entonces, el conjunto de todos los registros de
proveedores para una ciudad dada podrían estar comprimidos dentro de un simple
registro jerárquico, en el cual el valor de la ciudad en cuestión aparecería una sola vez,
seguido por los datos de los proveedores que pertenecen a la ciudad en mención (Ver
figura 3.11).
24

Atenas 1 XX 10

Londres 2 YY 20 5 MN 30

París 3 OP 10 4 YY 30

Figura 3.11 Ejemplo de compresión jerárquica

El ejemplo mostrado en la figura 3.11 consiste de 2 partes, una fija, que consiste
en el campo de la ciudad y una variable, que contiene el conjunto de proveedores que
pertenecen a la ciudad almacenada en la parte fija. El conjunto variable de entradas
dentro de un registro es llamado grupo de repetición (repeating group), de esta forma se
diría que el registro tipo jerárquico de la figura 3.11 consiste en el campo simple
“ciudad” y del grupo de repetición de la información del proveedor y este grupo está
formado por el campo que contiene el número de proveedor, el campo que contiene el
nombre del proveedor y el campo que contiene el estado, repetidos para cada proveedor
en la ciudad relevante.

La compresión jerárquica es particularmente apropiada en los índices, donde es


común encontrar el caso que muchas entradas sucesivas tienen el mismo valor de datos
(pero por supuesto punteros diferentes).

Código de Huffman
Es una técnica para codificar caracteres, poco usada en sistemas actuales, pero
que permite comprimir datos si diferentes caracteres ocurren en los datos con diferentes
frecuencias (lo cual es una situación normal). La idea elemental es la siguiente: Una
hilera de bits para realizar la codificación es asignada para representar caracteres, de tal
forma que caracteres distintos están representados por hileras de bits de diferentes
longitudes, y los caracteres más comúnmente utilizados, son representados por las
cadenas más cortas. Además, ningún carácter está codificado de tal forma que su
código de n bits sea idéntico a los primeros n bits de algún otro carácter codificado.
Como un ejemplo simple, suponiendo que los datos a ser representados
involucran únicamente los caracteres A,B,C,D,E y suponiendo también que lafrecuencia
relativa de estos cinco caracteres es la siguiente:

Carácter Frecuencia Código (hilera de bits)


E 35% 1
A 30% 01
D 20% 001
25

C 10% 0001
B 5% 00001

El carácter E tiene la mayor frecuencia, por lo tanto se le asigna el código más


corto, un único bit (1-bit). Todos los demás códigos deben empezar con un bit 0 y
deben tener como mínimo 2 dígitos de longitud (un bit 0 solo no es válido, porque sería
indistinguible). El carácter A sigue en la lista y se le asigna el siguiente código más
corto, en este caso 01, y así sucesivamente.

Dada la codificación anterior, la longitud promedio esperada para un carácter


codificado en bits es:
0.35*1 + 0.30*2 + 0.20*3 + 0.10*4 + 0.05*5 = 2.15bits,
En comparación, si a cada carácter se le asignara el mismo número de bits, como en un
esquema convencional de codificación de caracteres, serian necesarios 3 bits por
carácter para permitir la representación de las 5 posibilidades.

Вам также может понравиться