Tema 11. Modelo en red

Anuncio
Tema 11. Modelo en red
Juan Ignacio Rodrı́guez de León
Resumen
Conceptos básicos. Diagramas de estructura de datos. El modelo
CODASYL DBTG
Índice
1. Introducción
1.1. Registros, tipos de registros y datos . . . . . . .
1.2. Conjuntos, Tipos de Conjuntos e Instancias . .
1.3. Restricciones de los miembros de un conjunto
1.4. Tipos especiales de conjuntos . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
2
2
3
4
5
2. Base de datos de ejemplo
6
3. Facilidades para la recuperación de datos
3.1. Área de trabajo de programa . . . . . . . . . . . . . . . . . .
8
8
4. Ordenes de recuperación (get) y navegación (find)
4.1. Acceso a registros individuales . . . . . . . . .
4.2. Acceso a registros dentro de un conjunto . . .
4.3. Predicados . . . . . . . . . . . . . . . . . . . . .
4.4. Inserción y modificación . . . . . . . . . . . . .
4.5. Ordenación . . . . . . . . . . . . . . . . . . . . .
1
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
9
9
10
11
11
11
1
INTRODUCCIÓN
1.
2
Introducción
El modelo de red es, actualmente, una de las tres formas de organizar
la información más utilizada en los sistemas comerciales de bases de datos.
Históricamente, las estructuras y el lenguaje del modelo fueron definidas
por el comité CODASYL por lo que, en mucha de la bibliografı́a existente, al modelo en red se le denomina CODASYL. Posteriormente, el ANSI
(American National Standards Institute) realizó algunas modificaciones y
recomendaciones sobre el lenguaje.
Como se verá a lo largo del desarrollo de este capı́tulo,el lenguaje de un
sistema en red no es como SQL, un lenguaje autónomo en sı́, sino que se
compone de una serie de funciones que habrá que usar de manera inmersa
dentro de un lenguaje anfitrión. Para este propósito, y debido a que es uno de
los lenguajes más difundidos, se utilizará PASCAL como lenguaje anfitrión,
(aunque, en función del lenguaje comercial en cuestión, el lenguaje puede
ser otro, como C, COBOL, etc...)
El nombre de las funciones de un sistema de red también varı́a en función del producto comercial con que se trabaje, aunque la función en si sea
la misma. Por ello, en este capı́tulo se nombrarán estas funciones de una
manera general y sin particularizar en un sistema concreto, pero teniendo bien claro que cualquiera de las funciones utilizadas aquı́ tendrá una
homólogo en el sistema comercial utilizado.
Visto esto, la idea que debe sacarse en claro es que lo importante de este
capı́tulo es asimilar el funcionamiento y la manera de trabajar de un sistema
en red.
Antes de pasar a describir y utilizar el lenguaje en sı́, se definirán de manera muy breve las estructuras básicas de datos que componen un sistema
en red.
1.1.
Registros, tipos de registros y datos
En el modelo relacional, los datos y las relaciones entre ellos se representan mediante una colección de tablas. En el modelo en red, los datos se
representan como colecciones de registros, y las relaciones entre los datos
se representan mediante enlaces.
Un registro es un conjunto de valores de datos relacionados. Se clasifican
en tipos de registros, donde cada tipo describe la estructura de un grupo de
registros que almacenan la misma información. Por ejemplo, un Tipo de
registro ESTUDIANTE podrı́a ser:
DNI
ESTUDIANTE
NOMBRE APELLIDOS
DIRECCION
Mientras que una instancia de este tipo de Registro podrı́a ser la siguiente:
1
INTRODUCCIÓN
81211871
3
Antonio
Garcı́a
Castellana, 2
A diferencia de las base de datos relacionales, cuyos registros se engloban dentro de la estructura de la tabla relacional, los sistemas en red
presentan un nuevo tipo de estructura denominada conjunto, que, como se
verá posteriormente, permite enlazar unos registros con otros.
1.2.
Conjuntos, Tipos de Conjuntos e Instancias
Un tipo de conjunto es una descripción de 1 : n relaciones entre dos tipos
de registros, Este tipo de estructuras se representan habitualmente por un
diagrama de Bachman, el cual se compone generalmente de:
Un nombre para el tipo de conjunto
Un tipo de registro propietario
Un tipo de registro miembro
Un ejemplo de un conjunto que representa la relación ente las asignaturas en las cuales está matriculado un alumno podrı́a representarse de la
siguiente manera:
DNI
ESTUDIANTE
NOMBRE APELLIDOS
DIRECCION
↓ ESTUDIA
REG-ASIG
ASIGNATURA
NOMBRE CARRERA
CURSO
Donde el tipo de registro ESTUDIANTE es el tipo de registro propietario, ASIGNATURA es el tipo de registro miembro y ESTUDIA, el tipo de
conjunto.
Los tipos de conjunto, al igual que los tipos de registros, presentan también instancias de conjuntos o, como aparece en gran parte de la bibliografı́a,
ocurrencias de conjuntos.
Una ocurrencia de conjunto está compuesta por:
Una instancia de registro propietario
Un número cualquiera de ocurrencias de un registro miembro
Una estructura de datos, generalmente del tipo de lista doblemente
enlazada
1
INTRODUCCIÓN
4
Una ocurrencia de conjunto podrı́a ser, por ejemplo, la representada en
la figura 1, en la que, como puede verse, aparece un registro propietario
(ESTUDIANTE) enlazado con tres registros miembros.
Este tipo de estructura de datos suele implementarse mediante listas
enlazadas o doblemente enlazadas, de manera que desde el registro propietario es posible acceder a cualquiera de las instancias de registro que
pertenecen a esa ocurrencia de conjunto.
Una base de datos, planteada según este modelo, consistirá en una
serie de tipos de conjuntos entrelazados entre si de manera que un tipo de
registro que en una ocurrencia de conjunto funciona como propietario, en
otra ocurrencia de otro tipo de conjunto funciona como miembro.
Figura 1: Ocurrencia de conjunto
1.3.
Restricciones de los miembros de un conjunto
En el modelo de red, existen ciertas restricciones que pueden especificarse sobre los miembros de un conjunto. Estas restricciones pueden ser de
dos tipos:
Restricciones de inserción
Restricciones de mantenimiento
Las restricciones de inserción especifican de que manera se deben insertar los miembros de un conjunto. A diferencia de otro tipo de base de datos,
aquı́ es posible especificar, cuando se definen los conjuntos, como queremos
que los nuevos registros se añadan a los existentes. Existen dos opciones:
Automática La ocurrencia del registro que se añade a la base de datos
queda conectada automáticamente a una ocurrencia del conjunto.
1
INTRODUCCIÓN
5
Manual Cuando se añade una ocurrencia nueva de registro a la base de
datos,esta no se conecta a ninguna ocurrencia de conjunto sino que,
mediante ciertas funciones que se verán posteriormente, el usuario lo
debe conectar de manera manual.
Las restricciones de mantenimiento especifican como deben existir los
registros miembros dentro de una base de datos, es decir, si pueden existir
sin un propietario o si, por el contrario, no tiene cabida en la base de datos
si no están ligados a una ocurrencia de conjunto. Existen entonces tres
opciones:
Opcional Un registro miembro puede existir en la base de datos sin estar
conectado a ninguna ocurrencia de conjunto. Estos tipos de registro
pueden conectarse y desconectarse de una ocurrencia de conjunto a
voluntad.
Obligatoria Un registro miembro no puede existir en la base de datos sin
un propietario, es decir, debe ser siempre miembro de una ocurrencia
de conjunto. Pueden ser reconectado de una ocurrencia de conjunto a
otra en un solo paso, utilizando para ello el comando RECONNECT.
Fija Un registro miembro no puede existir sin un propietario y, además, una
vez conectado por primera vez ya no puede reconectarse a ninguna
otra ocurrencia de conjunto.
1.4.
Tipos especiales de conjuntos
Existen tres tipos especiales de conjuntos en CODASYL.
Conjuntos sistema-propietario: son aquellos en los que no existe un
tipo de registro propietario como tal, sino que es el propio sistema el
que actúa como propietario del mismo. Este tipo de conjuntos tiene
dos funciones muy importantes dentro de un sistema de red:
• Proporciona un punto de entrada a la base de datos, mediante la
especificación de alguno de sus registros miembros.
• Pueden ser utilizados para ordenar las ocurrencias de un determinado tipo de registro usando las debidas condiciones de
ordenación.
Conjuntos multi-miembros: son aquellos en los que los tipos de registros miembro pueden ser más de uno.
Conjuntos recursivos: Son aquellos en los que el mismo tipo de registro
representa un papel de miembro y propietario a la vez, como en la
figura 2:
2
BASE DE DATOS DE EJEMPLO
6
Figura 2: Conjuntos recursivos
2.
Base de datos de ejemplo
Figura 3: Base de datos de ejemplo
Para los problemas del libro, y cuando ha salido este tema en el examen,
se ha usado la base de datos cuya representación gráfica es la de la figura 3,
que explicaremos a continuación:
La base de datos guarda información sobre los EMPLEADOS de una
empresa. Un empleado puede tener, mediante el subconjunto SUBORDINADOS, a un grupo de empleados a su cargo. También se almacena información sobre los DEPARTAMENTOS de la empresa, donde cada departamento tiene asociando a un conjunto de empleados mediante el conjunto
ESTA-EN.
A su vez, mediante en conjunto CONTROL, cada departamento se encontrará trabajando en unos determinados PROYECTOS, los cuales a través
de los conjuntos TRAB-PROY y TRABAJA-EN tendrán asignados un grupo
de empleados.
2
BASE DE DATOS DE EJEMPLO
7
Por último, existe un tipo de registro denominado SUPERVISOR, en el
cual se encuentran los DNI de los directores de la empresa. Este tipo de registro está asociado a dos conjuntos distintos: Por una parte es propietario
del conjunto SUPERVISA, lo cual significa que cada SUPERVISOR llevará asociado una lista enlazada de EMPLEADOS a sus ordenes. Además,
el tipo de registro SUPERVISOR es miembro del conjunto ES-SUPERV,
lo que significa que cada empleado llevará asociado una lista enlazada de
SUPERVISORES, los cuales son jefes suyos.
A la base de datos se entra mediante el conjunto DEPARTAMENTOS,
que es propiedad del sistema.
Un ejemplo de consulta a esta base de datos podrı́a ser:
Encontrar e imprimir el salario de todos los empleados que trabajan en
el departamento de nombre “ventas”.
departmento.nombre := ’ventas’;
find any departamento using nombre;
if DB-Status = 0 then
begin
find first empleado within trabaje-en;
while DB-Status = 0 do
begin
get empleado;
writeln(empleado.salario);
find next empleado within trabaja-en;
end;
end;
Mediante la función find any se encuentra el primer departamento cuyo
nombre sea “ventas” (Se supone que sólo habrá uno). Si el resultado es
satisfactorio (DB-Status=0), habremos localizado correctamente el departamento de ventas.
Lo que se hace a continuación es avanzar por la lista enlazada, de la cual
el es propietario ese departamento según el conjunto trabaja-en, obteniendo
por tanto todos los registros de empleados asignados al departamento.
Mientras vaya encontrado registros imprime los salarios correspondientes.
Cuando DB-Status sea distinto de cero significa que hemos terminado, y
salimos del bucle.
Veremos con más detalle las particularidades de las ordenes find y get
en la siguiente sección.
3
FACILIDADES PARA LA RECUPERACIÓN DE DATOS
3.
3.1.
8
Facilidades para la recuperación de datos
Área de trabajo de programa
Todo programa que se ejecute en un sistema consta de una secuencia de
ordenes; algunas son propias del lenguaje anfitrión utilizado, mientras que
otras serán sentencias de órdenes DBTG. Cada programa en ejecución se
denomina unidad de ejecución (run unit). Para cada programa, el sistema
mantiene un área de trabajo (Denominada en el modelo DBTG como área
de trabajo de usuario, user work area) que contiene las siguientes variables:
Plantillas de registro: Un registro (entendido como registro en el lenguaje anfitrión, por ejemplo, un registro Pascal) para cada tipo de
registro utilizado por la aplicación.
Punteros de actualidad (Currency pointers): Un conjunto de punteros
a diversos registros de la base de datos que apuntan al registro accedido más recientemente por el programa. Los punteros de actualidad
pueden ser de varios tipos:
• Punteros actual al tipo de registro: Un puntero para cada tipo de
registro T referenciado por el programa; cada puntero contiene
la dirección (localización en disco) del tipo de registro T accedido
más recientemente.
• Punteros actual al tipo de conjunto: Un puntero que, para cada
tipo de conjunto definido en el esquema de la base de datos,
especifica la última ocurrencia a la que se ha accedido. Como
cuando se accede a una ocurrencia de conjunto, a lo que se accede de verdad es a un registro, este puntero señalará al registro
accedido de esa ocurrencia de conjunto.
• Puntero actual de unidad de ejecución: Un único puntero, que
contiene la dirección del último registro (independientemente de
su tipo) accedido por la aplicación.
Indicadores de estado, que son un conjunto de variables que utiliza
el sistema para comunicar a la aplicación el resultado de la última
operación aplicada a la base de datos. La más usado con diferencia
es la variable DB-status, que valdrá 0 si la operación tuvo éxito o un
código de error en caso contrario. Por ejemplo, el resultado de una
operación puede ser la excepción FIN-DE-CONJUNTO (EOS, Endof-set), que indicarı́a que no existen más registros miembros dentro
de una ocurrencia de conjunto. Esta situación se produce cuando
cuando una orden DML que intenta encontrar el siguiente o el anterior
miembro de una ocurrencia de conjunto, encuentra que no existe
4
ORDENES DE RECUPERACIÓN (GET) Y NAVEGACIÓN (FIND)
9
ninguno más. Por lo tanto, es habitual comprobar esta variable como
condición de salida de un bucle.
Las demás variables (DB-set-name, DB-record-name, y DBdata-name)
se utilizan en caso de fallo, para obtener información adicional del
mismo.
4.
Ordenes de recuperación (get) y navegación (find)
Las dos ordenes más usadas en este tipo de sistemas son get y find.
find Localiza un registro en la base de datos, y actualiza los punteros correspondientes.
get copia el registro al que apunta el puntero de la unidad de ejecución en
el área de trabajo, en el registro patrón correspondiente.
4.1.
Acceso a registros individuales
La orden find se puede usar de diferentes formas, sólo se verán algunas
de ellas. Hay dos maneras diferentes de localizar un registro individual. La
forma más simple serı́a:
find any [record type] using [record-field]
Este mandato localiza un registro de tipo record type cuyo valor en
record-field sea el mismo que el valor de record-field que hubiera en el
registro patrón en el área de trabajo. Una vez que el sistema localiza el
registro buscado, ajusta los punteros de forma que:
el puntero de la unidad de ejecución actual apunta al registro buscado.
el puntero al tipo de registro actual apunta al tipo del registro buscado
(record-type).
el puntero de conjunto actual para cualquier conjunto en el que pueda
estar incluido dicho record type es actualizado, apuntando o bien a
un tipo propietario o bien a un tipo miembro.
Puede haber varios registros con el mismo valor especificado. La orden
find encuentra el primero, siguiendo una ordenación que ha sido previamente especificada. Para localizar el resto de registros, se usa la orden find
duplicate, como en el siguiente ejemplo:
find duplicate [record type] using [record-field]
4
ORDENES DE RECUPERACIÓN (GET) Y NAVEGACIÓN (FIND)
10
que localiza el siguiente registro (según la ordenación preasignada) cuyo
valor sea igual al especificado en el patrón. Los punteros que se enumeraron
antes se ven afectados consecuentemente.
Como ejemplo, veamos el siguiente fragmento de programa, que imprime los clientes que viven en la ciudad de Harrison.
customer.customer-city := "Harrison";
find any customer using customer-city;
while DB-status = 0 do
begin
get customer;
print (customer.customer-name);
find duplicate customer using customer-city;
end;
Se ha englobado parte de la búsqueda en un bucle, porque ignoramos el
número de clientes que encontraremos. Salimos del bucle cuando la variable
especial DB-status sea distinta de cero. Recuérdese que un valor distinto de
cero indica que se ha fallado en la búsqueda del siguiente cliente, lo que
significa que ya hemos recorrido todos los clientes de Harrison.
4.2.
Acceso a registros dentro de un conjunto
La sentencia find vista anteriormente busca cualquier registro del tipo
indicado. Veremos ahora como localizar registros dentro de un conjunto. El
conjunto en cuestión será el que esté referenciado por el puntero de conjunto
actual. Hay tres tipos diferentes de órdenes. La orden de búsqueda básica
es:
find first [record type] within [set-type]
Que localiza al primer registro de tipo record type en el conjunto actual
de tipo set-type.
para iterar sobre el resto de registros en el conjunto, se ejecuta repetidamente la siguiente orden:
find next [record type] within [set-type]
Es necesario especificar el tipo de registro porque el conjunto podrı́a
contener registros de diferentes tipos.
También podemos usar una orden find para encontrar al registro propietario de una determinada ocurrencia de conjunto:
find owner within [set-type]
4
ORDENES DE RECUPERACIÓN (GET) Y NAVEGACIÓN (FIND)
4.3.
11
Predicados
Para poder realizar una búsqueda que contemple un rango de valores,
y no un único valor, debemos obtener todos los registros pertinentes en memoria, y examinar cada uno de ellos separadamente para poder determinar
el valor de la condición de búsqueda.
Como ejemplo, considérese el siguiente fragmento de código, que obtiene el número total de cuentas en la sucursal de Perryridge con un balance
mayor que 10.000$.
count := 0;
branch.branch-name := "Perryridge";
find any branch using branch-name;
find first account within account-branch;
while DB-status = 0 do
begin
get account;
if account.balance > 10000 then count := count + 1;
find next account within account-branch;
end
print (count);
4.4.
Inserción y modificación
La creación y el borrado de nuevos registros se realiza mediante las
ordenes store y erase. Las modificaciones se realizan con el mandato modify.
Las primitivas connect, disconnect y reconnect permiten insertar o sustraer registros de una instancia de conjunto.
Cuando se define un conjunto, se debe especificar la manera en que
los registros deben ser insertados, y bajo que condiciones se permite que
puedan ser transferidos de una ocurrencia a otra. Un registro recién creado
puede ser añadido a una ocurrencia de conjunto bien explı́citamente o
implı́citamente. Esta distinción se especifica en el momento de definir el
conjunto, mediante la opción insertion is con los valores manual o automatic.
4.5.
Ordenación
Los registros miembros de un conjunto pueden ser ordenados de diferentes maneras. El tipo de ordenación a utilizar se especifica por el programador mediante la orden:
order is [order-mode]
Donde order-mode puede ser uno de los siguientes valores:
4
ORDENES DE RECUPERACIÓN (GET) Y NAVEGACIÓN (FIND)
12
first Al añadir un registro a un conjunto, se inserta el primero. El orden,
por tanto, es cronológico inverso.
last Al añadir un registro a un conjunto, se inserta el último. El orden, por
tanto, es cronológico.
next Si el puntero actual señala al registro x, el nuevo registro se inserta
justo a continuación de x
prior Si el puntero actual señala al registro x, el nuevo registro se inserta
justo antes de x
system default El orden es decidido de forma arbitraria por el sistema.
sorted Las inserciones se realizan de forma que el conjunto se mantenga
ordenado con respecto a los valores de un determinado campo, especificado por el programado a la hora de definir el conjunto. Se debe
indicar si se desea un orden ascendente o descendente.
Descargar