Sie sind auf Seite 1von 41

Bases de datos 2

TEMA 1 INTRODUCCIÓN A LOS SISTEMAS DE GESTIÓN DE BASES DE DATOS

1. FUNCIONALIDAD Y OBJETIVOS DE LOS SGBD


Tema 1
Introducción a los sistemas de Entre la funcionalidad que se espera de una base de datos encontramos:
gestión de bases de datos
1. Funcionalidad y objetivos de  Consultas no predefinidas y complejas: Se debe pedir a un sistema de
los SGBD
2. Arquitectura de 3 niveles de base de datos que permita a los usuarios hacer consultas de cualquier tipo y
los SGBD complejidad, sin que estén preestablecidas, sin que se tenga que compilar un
3. Modelos de BBDD
4. Modalidades de uso del
programa exclusivamente para ello y que sea sencillo y cómodo para el usuario.
lenguaje Consultas del tipo; “Quiero un listado ordenado por apellidos de los alumnos
nacidos entre 1965 y 1971, que estén matriculados de 3 o menos asignaturas y
que vivan en Barcelona capital”.
 Flexibilidad e independencia: Interesa obtener la máxima independencia
posible entre los datos y los procesos usuarios, para que cuando existan
cambios tecnológicos se puedan implementar con facilidad. En ese sentido nos
tiene que dar igual el Sistema operativo o el tipo de fichero en el que los datos
estén escritos (independencia física de los datos); pero es que además
queremos que diferentes usuarios tengan unas visiones distintas e
independientes de la base de datos (como hablábamos en el tema anterior de
la visión de una base de alumnos desde el punto de vista del profesor o de la
secretaría); a esto se le denomina independencia lógica de los datos.
 Problemas de redundancia: Es necesario eliminar la redundancia de datos,
dado que cuando se quiere consultar alguno de ellos, podemos estar basando
la consulta sobre datos anticuados o erróneos, lo cual revierte claramente en
una pérdida de integridad de los mismos. Además, cuando un dato es
calculado (o derivado) producto de dos o más datos; es el SGBD quien debe
servir ese dato calculado en el momento, pues al programador o al usuario
puede habérsele olvidado realizar el cálculo tras actualizar los nuevos datos.
 Integridad de los datos: Se requiere un mantenimiento de alta calidad de los
datos en cualquier circunstancia. Cuando se define una base de datos, se
definen sus tipos y también las reglas de integridad que debe cumplir; reglas
de dos tipos: las reglas de integridad del modelo (por ejemplo, no aceptar
datos duplicados) y reglas de integridad del usuario (por ejemplo no aceptar
alumnos de menos de 18 años en la universidad ni de más de 120). Además los
procesos de backup y restauración tras un accidente, deben estar
automatizados y ser transparentes al usuario.
 Concurrencia de usuarios: Cuando muchos usuarios concurren en la misma
base de datos en modo lectura, el único problema es el rendimiento; pero si un
usuario o más están variando datos, se pueden dar problemas de interferencia;
se minimizan estos problemas con la transacción de BD; consiste en un
conjunto de operaciones simples que se ejecutan de manera atómica, es decir
o se ejecutan por completo o no se ejecuta ninguna; nunca, en cualquier caso,
se ejecutará parcialmente. Así por ejemplo si realizamos una transferencia de
efectivo de la cuenta A a la B; primero nos quitan el dinero de A y antes de
ingresarlo en B sucede una caída de tensión; entonces ¿Dónde irá ese dinero?
Para evitar estos problemas se define una transacción de BD, que utilizará la
operación COMMIT para indicar que ya ha terminado; si no puede acabar la
transacción, no llega a esta COMMIT, se deshará todo lo realizado, con la
operación denominada ROLLBACK. Además mientras tiene lugar esta
transferencia, para que se ejecute felizmente, se aísla de las demás
operaciones con la técnica de bloqueo, que pone limitaciones a los accesos del
2 · Bases de datos 2

resto de las transacciones para que no interfieran; lo malo de esto es que


produce esperas, retenciones y, en consecuencia, el sistema se ralentiza. El
esfuerzo actual de los SGBD se centra en minimizar estos efectos negativos.
 Seguridad: No hacemos aquí referencia a los backups que ya habíamos
tratado anteriormente, sino a temas relativos a la confidencialidad,
autorizaciones, derechos de acceso, etc. Los datos manejados en bases de
datos están en España protegidos por ley; y los diferentes sistemas de gestión
de bases de datos utilizan técnicas de limitar las autorizaciones e incluso de
encriptación de datos.

2. ARQUITECTURA DE 3 NIVELES DE LOS SGBD

Encontramos dos niveles en toda base de datos: el nivel lógico y el nivel


físico; el comité conocido como ANSI/SPARC definió en 1980 otra definición de
estos niveles, denominados esquemas:

 Esquemas externos: Se sitúan las diferentes Esquemas y niveles


visiones lógicas que los usuarios tendrán de las
partes de las BD que utilizarán.
 Esquema conceptual: Es único y global y sirve de
referencia para todos los sistemas: se describen aquí
las entidades tipo, atributos, interrelaciones,
restricciones, reglas de identidad, etc. Así, los
esquemas externos se nutren en la parte que les
interese del esquema conceptual. Si por ejemplo en
el esquema conceptual tenemos los atributos de
alumno: nombre, apellido1, apellido2… quizá en
algún esquema externo aparezca el atributo persona,
que sea la refundición de
nombre+apellido1+apellido2.
 Esquema interno: Se corresponde completamente con el nivel físico del que
hablábamos anteriormente: caminos de acceso,
Independencia física
codificación de datos, gestión del espacio y del
tamaño de la página….

Con esta nueva arquitectura de los SGBD la


independencia de los datos está asegurada; así,
hablaremos de independencia física, cuando los
cambios en la organización física (esquema interno) no
afectan al mundo exterior (es decir, los esquemas
externos). Si cambiamos, como se ve en la figura lateral
unos datos de un soporte a otro, no se verán afectados
ni los programas ni los usuarios directos; pero tampoco
se tendrían que ver afectados por ejemplo si cambiamos
el método de acceso a un conjunto de registros
determinados; solo deben variar las correspondencias
entre el esquema conceptual y el nivel físico, pero nada
más.
La independencia lógica también está asegurada:
cuando existen cambios en el esquema conceptual,
dichos cambios no afectarán a los esquemas externos
que no hagan referencia a entidades o atributos
modificados; por otro lado cuando es efectúan cambios en un esquema externo,
solo debe afectar a los usuarios de dicho esquema, pero no a usuarios de otros
esquemas externos, ni al esquema conceptual ni, por supuesto al esquema interno.
Bases de datos 2 · 3

3. MODELOS DE BD

Todo modelo de base de datos debe proveernos de estructuras de datos para


construir la BD (tablas, árboles…), restricciones o reglas de identidad que deben
cumplir los datos introducidos y luego una serie de operaciones para trabajar con
los datos: borrado, consulta, inserciones, búsquedas…

Modelos de BD Existen 3 modelos principales de BD que


vamos a estudiar según su evolución histórica:
 Modelo Jerárquico: Sus estructuras son
registros interrelacionados en forma de árboles, son
propios de los años sesenta.
 Modelo en red: De principios de los 70, hay
registros e interrelaciones, aunque ya no obliga
como en el anterior, que un registro sea hijo de un
solo registro.
 Modelo relacional: Se basa en el concepto
matemático de relación, entendiéndola como tabla.
El modelo relacional se limita al nivel lógico (no hace
consideración alguna sobre las representaciones
físicas, por lo que nos da una independencia total),
mientras que los dos modelos anteriores
prerrelacionales sí.

En los últimos años se está extendiendo el


modelo de BD relacional con objetos, añadiendo
tipos abstractos de datos (TAD) a los tipos
reconocidos y manipulados por la BD; esto acerca los sistemas relacionales al
paradigma de la orientación a objetos.

4. MODALIDADES DE USO DEL LENGUAJE

Lenguaje hospedado Para poder utilizar el SQL desde un lenguaje de


programación, podemos utilizar el SQL hospedado y
para ello precisamos de un precompilador que separe
las sentencias del lenguaje de programación de las del
lenguaje de base de datos. Una alternativa interesante
son las tuinas SQL/CLI. El precompilador separa las
sentencias del SQL y las sentencias de programación;
así donde hay una sentencia de acceso a la base de
datos, tendremos una llamada a la interfaz del SGBD.
Todas las sentencias que hemos usado hasta
ahora son las mismas que se van a seguir usando pero
precedidas de la cláusula EXEC SQL.

Las SQL/Call-Level Interface, denominadas de


forma abreviada CLI permiten que aplicaciones
desarrolladas en un cierto lenguaje de programación
puedan incluir sentencias SQL mediante llamadas a
librerías; por ejemplo la interfaz ODBC define una
librería de funciones que permite a las aplicaciones
acceder al SGBD utilizando el SQL.
4 · Bases de datos 2

TEMA 2 TRANSACCIONES EN LAS BASES DE DATOS

1. VISIÓN EXTERNA DE LAS TRANSACCIONES

Una transacción es un conjunto de operaciones de lectura y/o Tema 2


Transacciones en las bases de
actualización de la BD que acaba confirmando o cancelando los cambios que se han datos
llevado a cabo. Ya conocemos de la asignatura Base de Datos 1 que una 1. Visión externa de las
transacción acaba con la instrucción COMMIT o bien con la instrucción ROLLBACK transacciones
2. Control de concurrencia
que anula todos los cambios. mediante reservas
3. Recuperación
4. Consideraciones con respecto
Toda transacción debe cumplir las 4 propiedades de atomicidad, al nivel de paralelismo
denominadas propiedades ACID (Atomicidad, Consistencia, Aislamiento – 5. Otras visiones de las
Isolated- y Definitividad): transacciones
6. Un caso de SGBD concreto:
Informix
 Atomicidad: La operación de transacción o se realiza toda ella o no se realiza
ninguno de los cambios, por tanto aplicaremos ROLLBACK o COMMIT según nos
interese.
 Consistencia: Toda transacción que parte de un estado consistente de la BD
la debe dejar también consistente tanto desde el punto de vista físico como del
lógico.
 Aislamiento: La transacción debe comportarse como si no hubiese más
usuarios accediendo a la BD, por tanto no debe verse afectada por otras
transacciones simultáneas.
 Definitividad: Los resultados de una transacción confirmada, tienen que ser
permanentes, con independencia de que se produzcan fallos o desastres.

Los tipos de interferencias que podemos encontrar si las transacciones no se


aíslan correctamente entre sí son:

 Actualización Perdida: Se pierde el cambio que ha efectuado una operación


de escritura. Puede suceder porque o bien una de las transacciones
simultáneas aborta la operación cuando la otra transacción ya ha leído el nuevo
valor, o bien a un orden de lectura inadecuado para dos transacciones
simultáneas. Veamos estos dos ejemplos:

T1 W(A) ABORT
T2 W(A) COMMIT

T1 R(A) W(A) COMMIT


T2 R(A) W(A) COMMIT

En la primera tabla al escribir en A (por ejemplo una cuenta bancaria) se puede


sumar una cantidad, en T2 le puede añadir una cantidad a la inicial pero al
abortar el proceso T1 esa cantidad de la que parte no es correcta. EN el
segundo ejemplo el orden de lectura inadecuada para dos transacciones que
realmente acaban tampoco es el adecuado

 Lectura no confirmada: Se produce cuando una transacción lee un dato que


ha sido modificado por otra transacción que después aborta. Realmente como
no hay aislamiento de las transacciones se lee un dato no confirmado que,
finalmente, no es el correcto.

T1 R(A) W(A) ABORT


T2 R(A) W(A) COMMIT

 Lectura no repetible: Tiene lugar cuando una transacción lee dos veces el
mismo dato y obtiene valores diferentes a causa de una modificación efectuada
por una segunda transacción simultánea.
T1 R(A) R(A) COMMIT
T2 R(A) W(A) COMMIT
Bases de datos 2 · 5

 Análisis inconsistente (fantasmas): Ahora el error se produce cuando se


producen interferencias respecto a un conjunto de datos (y no frente a un
único dato como hasta ahora). Cuando una transacción T1 lee unos datos,
mientras otra T2 actualiza una parte, se puede obtener un estado de los datos
incorrectos que nunca hubiese tenido lugar si T1 y T2 ase hubiesen ejecutado
una detrás de otra.

T1 R(A1) W(A1) R(A2) W(A2) COMMIT


T2 R(A2) R(A1) COMMIT

En este ejemplo de transferencia entre dos cuentas A1 y A2, los datos que
lee T2 no son correctos, corresponden a un estado intermedio que no
deberían haberse leido fuera de la transacción T1.

Para evitar estos problemas existe lo que se llama nivel de aislamiento.


Podríamos aislar completamente todas las transacciones y todos los problemas
desaparecerían, pero esta protección exigiría una sobrecarga tremenda en términos
de gestión de información de control, o de acceso a la base de datos. En SQL la
instrucción SET TRANSACTION permite relajar el nivel de aislamiento a uno de los
4 siguientes niveles:

Lectura no
repetible y
Actualización Lectura no análisis de
Fantasmas
Perdida confirmada inconsistencias
(excepto
fantasmas)
READ
Sí No No No
UNCOMMITED
READ
Sí Sí No No
COMMITEED
REPEATABLE
Sí Sí Sí No
READ
SERIALIZABLE Sí Sí Sí Sí

Estos niveles aparecen de menos a más estrictos y, por lo tanto, de menos


a más eficientes. La definición del SQL estándar establece que un SGBD tiene la
obligación de garantizar al menos el nivel de aislamiento que se haya solicitado,
pero puerde ser mayor, por lo que el único nivel que tienen la obligación de
implementar es el más alto, el serializable.

Se denomina nivel de paralelismo o concurrencia al grado de


aprovechamiento de los recursos de proceso disponibles según la ejecución de
transacciones concurrentes en la BD. Es decir, el objetivo del paralelismo es
aumentar el trabajo útil para los usuarios por unidad de tiempo, intentando
obviamente minimizar todo lo posible el coste de las tareas de control de la BD.

De momento nos interesa la serializabilidad de conflictos, en la que se


parte de una visión simplificada de las transacciones, que se considera formadas
por dos únicos tipos que ya vimos anteriormente, la lectura (R) y la escritura (W);
además estos métodos se implementarán sobre lo que denominamos gránulo que
es la unidad de datos controlada individualmente por el SGBD, que puede ser un
único dato, una página o un bloque de disco, según el gestor. Llamaremos horario
o historia a un determinado orden de ejecución de las acciones de
lectura/escritura de un conjunto de transacciones.

Un horario serial es aquel en el que no se produce ningún solapamiento


entre las acciones de las transacciones implicadas. Por ejemplo:
6 · Bases de datos 2

T1 R(A) R(B) W(C)


T2 R(A) W(A)

Y como no hay solapamiento, los 2 posibles horarios seriales podrían ser:

T1 R(A) R(B) W(C)


T2 R(A) W(A)

T1 R(A) R(B) W(C)


T2 R(A) W(A)

Dos acciones serán conflictivas si pertenecen a transacciones distintas y


el orden en que se ejecutan pueden afectar al valor del gránulo que haya leído una
de las transacciones o al valor final del gránulo; por tanto, estas acciones serán no
conmutables. Por el contrario, un horario se considera correcto o serializable si
el orden relativo de todos los pares de acciones es el mismo que en algún horario
serial. Un horario serializable siempre produce el mismo resultado que algún
horario serial. Veamos algunos ejemplos:

T1 R(A) W(A)
T2 R(A) W(A)

Horario no serializable, pues se pierde W(A) en T1 (Actualización perdida)

T1 R(A) R(A)
T2 W(A)

No serializable, lectura no repetible en R(A) en T1.

T1 R(A) W(B) R(E) W(E)


T2 R(C) R(D) W(A)

Es un horario serializable, ya que es equivalente a un horario serial en que T1 se


ejecuta antes que T2:

T1 R(A) W(B) R(E) W(E)


T2 R(C) R(D) W(A)

El grafo de precedencias es útil para encontrar interferencias en estos


horarios serializables. Para ello se construye el grafo siguiendo los siguientes
puntos:

 Los nodos denotan transacciones


 Los arcos se etiquetan con el identificador de gránulo siempre y cuando no
sean conmutables (se comprenderá mejor con el ejemplo). Dos operaciones no
son conmutables cuando pertenecen a transacciones diferentes y el orden de
ejecución puede afectar al valor leído o al valor final del gránulo.
 Cuando el grafo de precedencia tiene ciclos, existen interferencias y ello implica
que las transacciones no están correctamente aisladas.
 Para encontrar un horario serial equivalente, el nodo no debe tener ciclos y
entonces basta situarse en un nodo Terminal (al que no llegue ningún arco),
apuntar la transacción representada en el nodo, eliminar el nodo y todas las
flechas que salgan del nodo eliminado, y repetir el proceso hasta que el grafo
quede vacío.

Vamos a comentar todo este proceso del grafo de precedencias con un ejemplo
que encontramos al margen de la página siguiente. Al comenzar a procesar el
horario, vemos que las acciones 30 y 70 no son conmutables, dado que si se
efectúa antes W(C), la R(C) variará, por tanto dibujamos un primer arco en el
grafo, con el valor del gránulo afectado (C) y como nodos las transacciones, parte
Bases de datos 2 · 7

Horario no serializable
primero de T1 que es la primera que se realiza y la flecha llega a T2 que es la
# T1 T2
10 R(A) segunda.
20 R(B)
30 R(C)
40 R(B)
50 R(E)
60 R(C)
70 W(C)
80 W(B)
90 W(E) Si continuamos avanzando por el horario de ejemplo, llegamos a encontrar
100 W(A) mas acciones no conmutables, la 40-60, 80-110, 90-120 y 70-130, con lo que el
110 W(B)
120 R(E) grafo final nos queda de esta forma:
130 R(C)
140 Commit
150 Commit

De lo que se desprende que el horario no es serializable.

Horario de ejemplo serializable Ponemos ahora otro nuevo ejemplo, que vemos en la figura lateral y
# T1 T2 T3 T4 al desarrollar el grafo de precedencias, obtenemos:
10 R(A)
20 W(A)
30 R(A)
40 R(B)
50 W(B)
60 R(A)
70 R(B)
80 R(D)
90 W(D)
100 R(E)
110 W(E)
120 R(F)
130 R(D)
140 Commit
150 Commit
160 Commit Como el grafo es acíclico, no existe ninguna interferencia, por lo que
170 Commit ahora sí podemos encontrar los horarios seriales equivalentes. Debemos
comenzar con un nodo Terminal, en este caso, solo existe T1; lo
eliminamos, junto con las flechas que de él parten y nos queda:

Procedemos ahora igual con T2, y luego podemos escoger indistintamente T3 ó T4,
con lo cual los dos horarios seriales equivalentes serían: T1, T2, T3, T4 y también
T1, T2, T4 y T3.

La recuperabilidad hace referencia a las interferencias que se producen


al cancelar transacciones, referencia de la que se hacía caso omiso en la
serializabilidad en la que considerábamos que no existía la posibilidad de cancelar o
abortar una acción ya comenzada. Un horario, incluyendo las acciones COMMIT y
ABORT cumple el criterio de recuperabilidad, si ninguna transacción T1 que lee o
escribe un gránulo escrito por otra transacción T2, confirma sin que antes lo haya
hecho T2.

T1 W(A) ABORT
T2 W(A) COMMIT
8 · Bases de datos 2

Este horario anterior según es serializable, pero no es recuperable, dado


que ahora se puede cancelar una acción comenzada, esto se podría arreglar con el
siguiente orden horario:

T1 W(A) ABORT
T2 W(A) COMMIT

2. CONTROL DE CONCURRENCIA MEDIANTE RESERVAS

Hay diversas técnicas de control de concurrencia, pero sin duda la más


utilizada con diferencia en los sistemas comerciales es el control mediante reservas.
La idea básica es que una transacción tiene que obtener una reserva de un gránulo
antes de poder operar sobre el mismo. Existen dos tipos de reservas, las
compartidas (que permiten llevar a cabo lecturas de un gránulo) y las exclusivas
(permiten realizar lecturas y escrituras). En un momento dado, un mismo gránulo
puede estar reservado para n transacciones con modalidad S o para una única
transacción en modalidad X.
Una vez pedida la reserva, por ejemplo lock (granulo, modalidad) se
desbloquea con el comando unlock (granulo). Si una reserva no puede concederse,
se suspende la ejecución de la transacción, y cuando se libera esta reserva de
gránulo, el SGBD trata de reanudar la ejecución de alguna transacción que haya
quedado suspendida.
Si las transacciones reservan los gránulos justo antes de operar y los
liberan inmediatamente después, es evidente que podrían producirse exactamente
las mismas interferencias que si no se hace nada, por ello toda transacción debe
cumplir lo que se denomina protocolo de reservas en dos fases (PR2F): Si una
transacción reserva cualquier gránulo en la modalidad adecuada antes de operar,
nunca adquiere o refuerza una reserva después de haber liberado cualquier otra
antes. Con este protocolo conseguimos alterar horarios no serializables para
convertirlos en serializables. Por ejemplo:

T1 R(A) W(A)
T2 R(A) W(A)

Ante la posible interferencia de actualización perdida, al aplicar PR2F:

T1 L(A.X) R(A) W(A) UL(A)


T2 L(A,X) --- --- R(A) W(A)

Ahora ponemos otro ejemplo, frente a:

T1 W(A) ABORT
T2 W(A)

T1 L(A,X) W(A) UL(A) ABORT


T2 L(A,X) --- --- W(A) UL(A)

Observamos que ahora no hemos solucionado nada, y es que debemos


recordar que estre protocolo PR2F convertía en serializable los horarios, pero no en
recuperables, para ello debemos aplicar el PR2F estricto que no libera ninguna
reserva hasta que acaba con COMMIT o ABORT indistintamente. Ya con este nuevo
protocolo obtendremos y habremos solucionado el problema:

T1 L(A,X) W(A) ABORT (UL(A))


T2 L(A,X) --- --- W(A)
Con el PRF2 estricto conseguimos simplificar la implementación y el uso del
sistema, eliminamos la posibilidad de cancelaciones en cascada aunque como
contrapartida, el nivel de paralelismo que permite alcanzar es más bajo.
Bases de datos 2 · 9

Se dice que se produce un abrazo mortal cuando la ejecución de dos o


más transacciones queda suspendida porque todas necesitan que otra de las
transacciones implicadas en el abrazo libere alguna reserva ya obtenida. Por
ejemplo:

T1 L(A,S) R(A) L(B,S) --


T2 L(B,X) W(B) L(A,X) --- ---

T2 no puede continuar porque T1 tiene reservada en modalidad lectura el


gránulo A, pero no se puede compartir, mientras que T1 está esperando que T2
libere B que lo tiene reservado para escritura. Para saber cuando se puede producir
un abrazo mortal, podemos dibujar los grafos de espera, que conviene no
confundir con los grafos de precedencia aunque sobre el papel se parezcan
Horario
bastante. El grafo de espera se caracteriza por:
# T1 T2
10 LOCK(A,X)
20 R(A)  Evoluciona a lo largo del tiempo, a medida que las transacciones adquieren o
30 LOCK (B,X)
40 R(B) liberan reservas.
50 LOCK (C,S)  Los nodos denotan transacciones
60 R(C)
70 LOCK (B,X)
 Los arcos se etiquetan con un identificador del gránulo que interviene en la
80 W(B) operación.
90 LOCK (E,S)  Cuando en un grafo de espera existan ciclos, tenemos un abrazo mortal.
100 R(E)
110 R(C)
120 COMMIT En el primer ejemplo de la tabla lateral, si analizamos las operaciones desde la
# T1 T2 10 hasta la 70, encontramos que la 30 y la 70 son incompatibles, por lo que hasta
10 LOCK (A,X) ese momento el grafo tendrá la forma (recordemos que evoluciona a lo largo del
20 R(A)
30 W(A)
tiempo):
40 LOCK (B,X)
50 R(B)
60 W(B)
70 LOCK (B,X)
80 LOCK (A,X)

Línea 70 Hasta que T2 no consiga la reserva de B no puede continuar su ejecución, por


lo tanto solo T1 está activa, y esta liberación se consigue en 120 con el COMMIT
que libera todas las reservas. Por lo que en este horario no hay ningún problema,
es serializable y recuperable.
Línea 80
En cambio, en el ejemplo siguiente (de 80 líneas), en le momento de ejecutar
la acción de la línea 70 el grafo es igual al anterior, y lo tenemos justo debajo de la
tabla del ejemplo, pero en el momento de llegar a la línea 80 el grafo de espera es
el último con el que nos encontramos, tenemos un ciclo y por tanto un abrazo
mortal.

Para resolver estos abrazos, los SGBD pueden optar por una de las tres
posibilidades siguientes:

 Prevenirlos antes de que se produzcan.


 Definir un tiempo de espera máximo que al ser superado, haga que se cancele
automáticamente toda transacción.
 Detectarlos y resolverlos una vez que se hayan producido. Es la opción más
común, la búsqueda de estos ciclos de espera a su vez pueden hacerse:
o Siempre que una transacción pida una reserva y no la obtenga
inmediatamente, esto implica que algo sucede; es la mejor forma
pero implica una carga de trabajo excesiva a la BD.
o Cada cierto tiempo, que no debería ser demasiado largo.
o Cuando existen transacciones sospechosas (al menos dos) porque
están en espera desde hace más de un cierto tiempo.
En cualquier caso, una vez detectado lo único que puede hacerse es
romper el ciclo cancelando una o varias de las transacciones implicadas,
generalmente se cancela la que se vea implicada en más abrazos mortales o la que
lleve menos tiempo en ejecución para deshacer menos trabajo.
10 · Bases de datos 2

Jerarquía de composición de gránulos

Hay muchas veces que se dispone de múltiples niveles de Jerarquía de composición de gránulos
granularidad y esto afecta obviamente a los protocolos
implementados en el punto anterior. Pueden existir jerarquías de
gránulos donde gránulos de dimensiones mayores pueden contener
subgránulos, o gránulos más pequeños. Así una reserva S o X de un
gránulo puede permitir acceder a los más pequeños sin llevar a cabo
nuevas reservas.
Así, si una transacción tiene que acceder a todos o a una gran
parte de los gránulos elementales que contiene otro gránulo, puede
incrementar el rendimiento haciendo menos peticiones de reserva, si reserva el
gránulo completo. Para leer todos los datos de la tabla T1 lateral, la transacción
podría ser:

T1 L(T1,S) R(P1) R(P2) R(P3)

Para que este protocolo funcione perfectamente, cuando se pide una


reserva de un gránulo debe comprobarse que no haya ninguna reserva
incompatible por parte de ninguno de sus subgránulos, ni de ninguno de los
gránulos que lo contienen. Así para reservar cualquier gránulo en modo S, habrá
que reservar todos los gránulos que lo contienen, partiendo desde la raíz de la
jerarquía en modo IS (intención de lectura), de modo análogo existe la reserva en
modo IX; las liberaciones de las reservas se harán en orden inverso al de
adquisición. La tabla de compatibilidad entre estas nuevas modalidades puede
observarse en el lateral:
Tabla de compatibilidades
 Las reservas IS de un gránulo dan derecho a pedir reservas de tipo S o IS de IS IX S SIX X
IS Sí Sí Sí Sí No
los subgránulos, lo cual debe impedirse cuando otra transacción tenga IX Sí Sí No No No
reservado el gránulo para escritura (X). S Sí No Sí No No
SIX Sí No No No No
 Las reservas IX dan derecho a pedir reservas de tipo X o IX de los subgránulos, X No No No No No
lo cual debe impedirse si el gránulo ya ha sido reservado para lectura o
escritura.
 También existen las reservas SIX que no son estrictamente necesarios pero
pueden ser útiles pues permiten leer cualquier subgránulo (sin pedir reservas
particulares) o pedir reservas de escritura: vienen a sumar los derechos de las
reservas S e IX.

Niveles de aislamiento

El SGBD siempre gestiona las reservas de escritura con el máximo rigor,


esto implica que todas las reservas con modalidad X se mantienen hasta la
finalización de la transacción. No obstante, las reservas para lectura pueden variar:

 Nivel serializable: Igual al concepto anterior, las reservas se mantienen


siempre hasta que las transacciones finalizan.
 Nivel Repeatable Read: Las reservas S de lectura se mantienen hasta que la
transacción no necesite volver a leer cada gránulo.
 Nivel Read Committed: Las reservas de lectura se mantienen hasta justo
después de la lectura del gránulo. Garantiza que lo que se lee se ha
confirmado, ya que las reservas para cada actualización siempre se mantienen
hasta el final de la transacción.
 Nivel Uncommitted: No se efectúan reservas para la lectura, así que estos
datos pueden haber sido actualizados por una transacción todavía no
confirmada.
Bases de datos 2 · 11

3. RECUPERACIÓN

Los mecanismos de recuperación tienen que garantizar la atomicidad y la


definitividad de las transacciones. Su objetivo primordial es que nunca se pierdan
los cambios de las transacciones que ya han sido confirmadas y que no se
mantengan los cambios efectuados por transacciones que han sido canceladas.

El SGBD tienen que asegurar la cancelación voluntaria de las transacciones


a petición de la aplicación, la involuntaria a causa de fallos de aplicación,
violaciones de restricciones de integridad… integridad frente a una caida del
sistema o por la destrucción total de la BD.

Vamos a distinguir a su vez la restauración de la reconstrucción.

La restauración si es hacia atrás debe ser capaz de deshacer los cambios


de una transacción abortada y si es hacia delante debe rehacer los cambios de una
transacción confirmada. Para analizar estos cambios hay que tener en cuenta la
utilización de una memoria intermedia por parte del SGBD. No todas las peticiones
de lectura/escritura van directamente a la BD, en un momento determinado puede
haber acciones de escritura que no han llegado a la BD en memoria externa y otras
que sí lo han hecho, y suele ser independiente del hecho de que las transacciones
hayan confirmado o no: puede haber escrituras confirmadas que no hayan llegado
al disco.
Para deshacer y rehacer cambios, el SGBD utiliza una estructura de datos
con información de cambios el dietario, que guarda un identificador por cada
transacción, el estado anterior del gránulo modificado y el posterior; eso sí, para
que el dietario permita deshacer y rehacer transacciones, los registros de cambio
deben escribirse a partir de los datos existentes en las memorias intermedias, antes
de que éstos lleguen a la memoria externa en la BD y las transacciones se
confirmen.
Así, cuando una transacción aborta, se deshacen los cambios hechos hasta
ese momento. Sus registros de cambio en el dietario se recorren hacia atrás hasta
que se identifica el primer cambio y ahí se terminan de deshacer los cambios.
Cuando se produce una caída del servicio, hay que deshacer los cambios de todas
las transacciones activas y rehacer las de todas las confirmadas; el problema es
saber hasta qué cambio hay que deshacer y para eso existen los registros de
punto de control que identifican en qué último momento el SGBD llevó a la
memoria externa todos los cambios.
Todo este proceso puede simplificarse si:
 Antes de confirmar una transacción, el SGBD siempre lleva todos los cambios a
la memoria externa, así ante una caída nunca habrá que rehacer transacciones
confirmadas.
 El SGBD no lleva cambios de transacciones no confirmadas a la memoria
externa, entonces no será nunca necesario deshacer los cambios de
transacciones canceladas.

El inconveniente de todas estas simplificaciones es que pueden empeorar el


rendimiento o gastar demasiados recursos del SGBD.

Tras la restauración encontramos la reconstrucción: Para poder reconstruir


una BD después de una pérdida parcial habra que utilizar dos fuentes de
información: una copia de seguridad correcta aunque anterior de la BD y el
contenido del dietario a partir del momento en que se hizo la copia de seguridad.

4. CONSIDERACIONES CON RESPECTO AL NIVEL DE PARALELISMO

Hemos visto que con la utilización de reservas, unas transacciones pueden


quedar bloqueadas hasta que otras terminen lo que estaban haciendo pero ¿y si
esa transacción está esperando que el usuario introduzca algún dato? Entonces la
12 · Bases de datos 2

reserva puede alargarse un tiempo que podemos considerar infinito, pues el


usuario puede empezar a realizar otra tarea y olvidarse de la base de datos. En
estos casos se suelen hacer descomposición de transacciones posibilitando que
otras transacciones accedan a los datos entre la ejecución de las transacciones
resultantes de la descomposición.

Otro aspecto a tener en cuenta es que la utilización de herramientas


de desarrollo deba permitir al programador ajustar el uso de las transacciones a
gusto del programador y no conformarnos con utilizar el sistema por defecto que
utilice la herramienta.

Por último para prevenir abrazos mortales no es imprescindible la


utilización de reservas explícitas que disminuyen el nivel de paralelismo; también
podemos reorganizar las transacciones para que accedan a los datos en un mismo
orden y así evitar que se tengan que esperar con reservas unas a otras.

5. OTRAS VISIONES DE LAS TRANSACCIONES

Todo lo estudiado en este módulo se basa en que la mayor parte de las


transacciones tendrán una duración muy corta; en casos especiales esto no es así,
por motivos históricos o de rendimiento, grandes compañías implementan los
denominados monitores transaccionales que es un software que les permite
hacer convivir distintos tipos de SGBD y otras aplicaciones de manera concurrente,
mientras que el monitor coordina el funcionamiento de cada uno de los gestores
implicados en una transacción.
Para transacciones largas y persistentes pueden existir en su interior
transacciones convencionales que sí permitan reservas e incluso transacciones
anidadas que pueden ser canceladas de dentro a afuera sin afectarse unas con
otras en su cancelación.

6. UN CASO DE SGBD CONCRETO: INFORMIX

En Informix el control de concurrencia se basa en reservas, existiendo dos


tipos de BD: ANSI, que escribe siempre todos los cambios en memoria externa
antes de confirmarla y NO-ANSI que permite activar o desactivar este
comportamiento. Así para crear una BD:

CREATE DATABASE nombre [IN espacio_bd]


[WITH [BUFFERED LOG | LOG MODE ANSI]];

Se puede modificar el comportamiento de una transacción cuando no puede


obtener una reserve de la siguiente forma:

SET LOCK MODE TO [WAIT (segundos) | NOT WAIT]

Con No wait, no espera; con WAIT puede esperar los segundos que se indiquen
antes de abortar o, si no se han puesto segundos, intentará continuar
indefinidamente. Al crear una tabla puede especificarse el nivel del gránulo por
registros (row) o por páginas (page) con la siguiente sintaxis:

CREATE TABLE nombre_tabla (…) [LOCK MODE [ROW|PAGE]]


Bases de datos 2 · 13

TEMA 3 PROGRAMACIÓN CON SQL

Tema 3 1. INTRODUCCIÓN A LAS TÉCNICAS DE SQL PROGRAMADO


Programación con SQL
1. Introducción a las técnicas de
SQL programado El SQL es un lenguaje específico para definir y manipular BD pero se dice
2. Programación con SQL que es un sublenguaje especial para la gestión de BD y no un lenguaje de
hospedado
3. Programación con SQL/CLI programación completo dado que no permite declarar variables, ni construir bucles
4. SQL y Java ni comprobar condiciones.

En este sentido, para construir aplicaciones que puedan acceder a una BD,
se suele recurrir dentro del SQL a 3 aplicaciones:

 El SQL hospedado donde las sentencias de SQL se encuentran incorporadas


directamente dentro de la aplicación, mezcladas con las sentencias propias del
lenguaje.
 El SQL/CLI, donde la aplicación se comunica con el SGBD mediante una
interfaz.
 JDBC que constituye la evolución propuesta por Java al modelo SQL/CLI.

2. PROGRAMACIÓN CON SQL HOSPEDADO

Compilación en SQL hospedado La idea básica del SQL hospedado es


permitir la inserción de sentencias SQL dentro
de una aplicación desarrollada con un
determinado lenguaje de programación. Para
que esto ocurra felizmente, contamos con los
recursos siguientes:

 Un precompilador: Necesitamos una


herramienta capaz de separar las sentencias
SQL de las propias del programa anfitrión en el
archivo fuente. Como resultado de este proceso
se obtienen dos archivos: el programa fuente
original en el cual las sentencias de SQL se han
sustituido por llamadas a rutinas de la interfaz
del SGBD y un archivo que contiene las
sentencias de SQL. El primer programa fuente
sin las sentencias SQL es tratado por el
compilador particular del lenguaje de
programación, y a continuación el montador
produce el programa ejecutable. En cambio, el
archivo que contiene las sentencias SQL es
analizado por el módulo de procesamiento de consultas del SGBD.
 Mecanismos para definir y poder utilizar variables puente con el SQL, tanto
variables definidas y utilizadas por el programa fuente en una sentencia de SQL
hospedado, como variables especiales definidas en el programa fuente para
asignar y recuperar los valores nulos de la BD.
 La incorporación de nuevas sentencias y cláusulas de SQL que no existen en el
SQL directo para poder procesar fila a fila los resultados de las distintas
consultas de SQL y facilitar así el tratamiento de errores.

Las principales características que encontramos en un programa con SQL


hospedado son las siguientes:

 Las sentencias SQL se mezclan con las del programa anfitrión, indistintamente
en mayúsculas o minúsculas.
 Las sentencias SQL van precedidas de la clave EXEC SQL.
14 · Bases de datos 2

 Hay que marcar el final de las sentencias de SQL hospedado, en lenguaje C por
ejemplo con ;.
 Se declara el área de comunicaciones SQLCA que sirve para que el SGBD
informe al programa de los diferentes errores que pueden producirse en tiempo
de ejecución. Así se puede evaluar el éxito o fracaso de una sentencia SQL y
continuar el programa en consecuencia.
 Se declaran variables puente con SQL con BEGIN DECLARATE SECTION y END
DECLARATE SECTION; además se debe prefijar el nombre de la variable con
dos puntos :nombre_variable. Podemos declarar estas variables al comienzo del
programa o en estructura de bloques como el lenguaje C, donde entonces la
visibilidad de cada variable queda restringida al bloque en que se declaró.
 Hay que tener en cuenta además que el tipo de datos reconocido por el
lenguaje SQL y el lenguaje anfitrión puede ser distinto; amén del
reconocimiento de los valores nulos. Para evitar este último problema, cada
variable puente SQL tiene que tener una variable indicadora asociada si la
columna con la que está relacionada admite valores nulos. Así un valor
indicador igual a 0 significa que el valor no es nulo y que la variable puente
contiene el valor buscado; un valor indicador negativo significa que queremos
asignar un valor nulo para la columna que tratamos, con lo cual el valor real de
la variable puente es irrelevante; por último un valor indicador positivo indica
que la variable puente tiene un valor válido pero que puede haber sido
redondeado, truncado, etc.
 Gestión de errores: En SQL hospedado la gestión de errores es
responsabilidad de la aplicación. Los errores de código SQL son reconocidos por
el precompilador, pero los errores en tiempo de ejecución son tratados por dos
variables la SQLCODE y la SQLSTATE. Tenemos dos porque la variable inicial
para los errores era SQLCODE pero al no existir un acuerdo sobre el valor de
los distintos códigos en las diferentes SGBD, se optó por mantenerla de forma
histórica e inventar la SQLSTATE.
 SQLCODE: Cuando se ha ejecutado la sentencia de SQL hospedado, se fija el
valor de la sentencia SQLCODE para indicar el estado de finalización de la
misma, si SQLCODE vale 0, la sentencia se ha ejecutado con éxito; si vale
negativo, significa que se ha producido un error grave que impide la ejecución
correcta de la sentencia; mientras que si vale positivo se ha producido una
situación de aviso, típica del redondeo o truncamiento (por ejemplo
SQLCODE=100 significa que no se han encontrado datos que cumplan las
condiciones especificadas por la sentencia).
 SQLSTATE: Consta de cinco caracteres, los dos primeros de la cadena
identifican la clase de error y los 3 últimos la subclase.

Manipulación de una BD

 Inserción de filas en una tabla: Se lleva a cabo con la sentencia siguiente:


INSERT INTO nombre_tabla
VALUES ({INDICATOR: var_1_ind] | constante|NULL}…)
Así en el lenguaje C nos quedaría:

Void insertar_empleado()
{
Int estado;
Printf(“Introduce el DNI del empleado: “);
Scan f (“%s”, dni_empl);
….

 Borrado de filas en una tabla


DELETE FROM nombre_tabla [WHERE condiciones]

 Modificación de filas en una tabla


UPDATE nombre_tabla
SET col_k = … [WHERE condiciones]
Bases de datos 2 · 15

 Consulta de tablas: Este tipo de operación requiere sentencias añadidas que no


existen en el SQL directo, dado que habitualmente una consulta de este tipo
genera distintas filas de datos y los lenguajes de programación solo son
capaces de procesar una de estas filas cada vez. Por ello definimos dos tipos
distintos, las consultas que dan como resultado una fila (por ejemplo una
búsqueda de empleado por el DNI) y la que produce o puede producir más de
una fila de resultados.

 Consultas de una fila


SELECT [ALL|DISTINCT] {exp.|*}
INTO :var_1 [INDICATOR :var_1_ind]…
FROM tabla [{, tabla] [WHERE condiciones]
Hay que especificar con INTO tantas variables puente como columnas o
funciones de agregación hayan sido especificadas en la cláusula SELECT y
además en el mismo orden.

 Consultas con cursor


Creamos una nueva estructura, el cursor, por el que se podrá desplazar el
programa, y se define con las sentencias
DECLARE nombre_cursor CURSOR
FOR consulta 1 [UNION consulta2]
[ORDER BY col_k [, col_m]] [ASC|DESC]
La sentencia declare cursor define la consulta que se debe ejecutar y le asocia
un nombre de cursor; eso sí, la sentencia de declaración de un cursor concreto
debe preceder al resto de sentencias que puedan operar sobre ese mismo
cursor. Una vez creado y realizada la búsqueda, para abrir el cursor se utiliza
OPEN nombre_cursor, para desplazarse avanzando una fila se utiliza
FETCH nombre_cursor
INTO vr_1 [INDICATOR :var_1_ind]…
Y para cerrar el cursor se utiliza CLOSE nombre_cursor, no pudiéndose
volver a abrir o recuperar los datos de ese cursor de nuevo.

3. PROGRAMACIÓN CON SQL/CLI

El SQL/CLI permite que una aplicación desarrollado con un lenguaje de


programación como puede ser C, pueda incorporar sentencias de SQL mediante la
llamada de subrutinas predefinidas disponibles en librerías. Está muy relacionado
con la interfaz ODBC de Microsoft. Con el SQL/CLI no se precisa precompilador,
simplemente se monta la aplicación junto con la librería de subrutinas.

Las ventajas que nos aporta este tipo de programación son:

 EL código de aplicaciones solo incorpora sentencias de l lenguaje de


programación, ya que las sentencias SQL quedan escondidas.
 Permite desarrollar aplicaciones que no necesitan conocer de manera exacta las
sentencias de SQL antes de ser ejecutadas y aplicaciones además que no
dependen de las características propias de un SGBD concreto; así aunque
cambiemos de SGBD las aplicaciones continuarán siendo válidas.
 La gestión de errores se efectúa con las propias subrutinas de SQL/CLI y no del
SGBD.
 No se precisan variables puente ni variables indicadoras.

Estas subrutinas SQL/CLI se caracterizan por:

 Pueden ser una función o una acción.


 El nombre consta de un prefijo SQL y el nombre real de la subrutina.
16 · Bases de datos 2

 Cada rutina lleva asociados unos parámetros de entrada y salida y cada


parámetro un tipo de datos, existiendo concordancia entre el tipo de
parámetros y el tipo de datos que espera la subrutina.
 Las subrutinas siempre devuelven un código de error para indicar el estado en
que queda el programa después de ejecutarse.

Toda aplicación que utiliza subrutinas SQL/CLI establece primeramente una


conexión con el servidor, ejecuta las sentencias SQL y finaliza después la
conexión. Eso sí el entorno de ejecución que se requiere tiene un conjunto de
sentencias que suelen ser para obtener memoria para almacenar datos relevantes.
Para obtener la conexión las sentencias suelen ser:

 SQLAllocEnv: Busca memoria para almacenar datos de control global.


 SQLAllocConnect: Datos de control de las conexiones establecidas.
 SQLAllocStmt: Memoria para la información de control de las sentencias SQL.

Una vez tenida lugar la conexión generalmente se ejecutan las sentencias


SQLFreeStmt, SQLFreeDisconnect, SQLFreeConnect y SQLFreeEnv, que liberan los
recursos de memoria que habíamos reservado para la conexión.

La gestión de errores se lleva a cabo consultando los códigos de error


prefijados que devuelve toda sentencia SQL/CLI. En cuanto a los tipos de datos
no suele haber gran problema pues son derivados directamente del ODBC que
derivan directamente de los tipos de datos C. Por el contrario a lo que nos pasaba
en el SQL Hospedado, los valores nulos pueden ser perfectamente tratados por el
programa.

4. SQL Y JAVA
Tabla de compatibilidades
La solución propuesta por Java para el acceso y
manipulación de BD no parte de cero, sino que a partir de
SQL/CLI y de su implementación ODBC construye un sistema
fiel a los principios del lenguaje, es decir, simpleza y elegancia.
Java ofrece el JDBC que va más allá de lo que se
consigue con SQL/CLI que es ofrecer métodos para controlar el
posicionamiento de los cursores (previous, netxt…), métodos
para modificar el contenido de tablas sin utilizar SQL, permite la
realización batch de un conjunto de modificaciones, etc.

Los drivers
Es necesario contar con drivers que son una
implementación para poder trabajar con SGBD. Encontramos 4
tipos de drivers distintos (podemos ver los 4 tipos en la imagen
lateral):

 Tipo 1: Puente JDBC-ODBC más un driver ODBC: Con ese


driver Java llama al driver ODBC y se encarga de ocultar
toda su complejidad; eso sí el rendimiento no es todo lo
bueno que podía esperarse y obliga a que en la máquina
cliente estén instalados los drivers ODBC correspondientes.
 Tipo 2: API Nativo: Es un driver Java Parcial, convierte las
llamadas al JDBC en llamadas específicas del API del SGBD
cliente; se puede entender como una simplificación del tipo
anterior que mejora bastante el rendimiento; requiero que
parte del driver esté cargado en la máquina cliente.
 Tipo 3: JDBC Red: Es un driver Java puro que convierte las
llamadas al API JDBC en llamadas a un servidor de red
intermedio. Es una implementación muy flexible.
 Tipo 4: JDBC Nativo, también es un driver Java puro que
Bases de datos 2 · 17

permite llamadas directas al protocolo nativo de red del SGBD sin una capa de
software intermedio.

Los tipos 1 y 2 se plantearon e implementaron como modelos transitorios hasta


que la industria suministrase drivers Java puros; de hecho el puente JDBC-ODBC no
soporta las especificaciones JDBC 2.0 y el hecho de que la máquina cliente dependa
de un sistema propietario le resta portabilidad. Una aplicación Java siempre tendrá
que contar con la existencia de una instalación previa, mientras que con los tipos 3
y 4 el driver es descargable, al igual que la propia aplicación o applet.

Estructura de un programa con JDBC


Una aplicación que utilice el JDBC ha de seguir un esquema similar al siguiente:
 Localización y carga del driver
 Conexión con el SGBD
 Operaciones de acceso y gestión de excepciones
 Desconexión del SGBD

Para localizar y cargar el driver recordemos que debemos definir un PATH con
la ruta del mismo, el driver es ifkjdbc.jar y por supuesto el programa tendrá que
importar explícitamente el API del JDBC, a través de import java.sql.*. Hechas
estas dos cosas, ya estamos en condiciones de escribir las primeras líneas del
programa. Normalmente todo el código lo introduciremos en un bloque try-catch
para evitar errores de programa:

 Conexión con el SGBD: conn = DriverManager.getConnection (url, Login,


Password). Más sencillo es inmposible. Esta expression peude variar al tratarse
de un tipo de driver y otro. Nosotros de aquí en adelante, actuaremos sobre el
tipo 4. Para cerrar simplemente es necesaria la orden conn.close, sin necesidad
de liberar recursos, pues ya lo hará Java por nosotros; comparemos este
método con el del SQL/CLI en cuanto a complejidad.
 Operaciones de acceso y gestión de excepciones: Las sentencias se
envían precedidas de stmt.executeUpdate y entre paréntesis por ejemplo Insert
Into….
 Sentencias de modificación: Por ejemplo para actualizar datos en una tabla
podremos usar: stmt.executeUpdate (UPDATE Empleados….) para crear tablas
por ejemplo Strip cmd = “CREATE TABLE…”
 ExecuteQuery: Es el comando que utilizaremos cuando queramos realizar una
consulta; en este caso al ser una consulta devuelve un valor o un conjunto de
ellos a través del objeto JDBC resultSet (conjunto de filas obtenidas al realizar
la consulta). Además JAVA nos permite desplazarnos por cualquiera de estas
filas y no obligatoriamente una a una y en orden; podemos ir al siguiente next,
anterior, previous, una fila absoluta absolute(5) la 5ª fila en este caso, una
realtiva relative (-2) iríamos ahora a la 3ª pues estábamos en la 5ª, etc.
 Control de las transacciones: Las transacciones se realizan
automáticamente en Java, pero quizá nos convenga que tengan lugar en
momentos determinados, o tras realizar todo un conjunto de comandos, en
este caso deberemos comenzar el bloque try con conn.setAutoCommit (False) y
luego realizar un conn.commit cuando queramos aceptar todo el conjunto de
sentencias introducidas.
 Sentencias preparadas: Se pueden preparar sentencias que luego se
ejecuten de manera continuada a travñes de PreparedStatement.
 Procedimientos almacenados: Es parecido al ejemplo anterior, si bien las
sentencias preparadas se utilizan más para tareas reiterativas, los
procedimientos almacenados son una agrupación de sentencias que suelen
formar una tarea lógica y se pueden crear a traves de CREATE PROCEDURE e
invocar a través de CallableStatement.
 Modificaciones por lotes: Al igual que en DOS, es posible almacenar en una
matriz interna de un objeto, una serie de sentencias de modificación para que
sean ejecutadas en lote, se consigue a través de stmtaddBatch (para ir uniendo
18 · Bases de datos 2

sentencias) y se ejecutan con stmt.executeBatch. Como podemos observar, el


mecanismo no puede ser más sencillo a la par que muy práctico.
Bases de datos 2 · 19

TEMA 4 COMPONENTES LÓGICOS DE UNA BASE DE DATOS

Tema 4 1. FUNCIONALIDAD Y OBJETIVOS DE LOS SGBD


Componentes lógicos de una
base de datos
1. Componentes lógicos de datos Los principales componentes lógicos de una base de datos son dos: las
2. Componentes lógicos de tablas y las vistas. Además de los componentes lógicos anteriores que serían los de
control
3. Catálogo datos, tenemos los componentes lógicos de control que pueden ser entre otros, los
procedimientos y los disparadores.
Para un SGBD, una base de datos es un conjunto definido y relacionado de
componentes lógicos de datos y de componentes lógicos de control.
Recordemos que para crear una base de datos tenemos la orden CREATE
DATABASE <nombreBaseDeDatos> El nombre debe ser único. El inicio del trabajo
lo marcaremos con BEGIN WORK y lo finalizaremos con COMMIT o con ROLLBACK.
Para borrar una base de datos contamos con DROP DATABASE y para conectarnos
a ella y comenzar a trabajar con CONNECT TO <nombreBD>.

Tablas
Este es el componente lógico principal de la BD, y para crearla utilizaremos
la sentencia CREATE TABLE <nombreTabla> (definicionColumnas,
definicionRestricciones).
La definición de columnas incluye la definición del conjunto de columnas
que incorpora la tabla, separada por comas. Definiremos para la columna el
nombre, el tipo de datos, la definición por defecto y la restricción de columnas. El
tipo de datos puede ser byte, carácter, date…, la definición por defecto, si
queremos permiten especificar los valores que se asignan a cada columna por
omisión; mientras que las restricciones de columna están limitadas a una sola
columna no a todas las que forman una tabla determinada, y pueden ser NOT
NULL, DISTINCT, UNIQUE, PRIMARY KEY y CHECK.
Podemos borrar tablas mediante la sentencia DROP TABLE y podemos
modificarla añadiendo, eliminando columnas o restricciones mediante la sentencia
ALTER TABLE.

Vistas
Es el segundo componente lógico de datos de las BD. Una vista realmente
es una tabla derivada, su esquema y contenido derivan de otras tablas e incluso
de otras vistas, mediante una consulta.
Partiendo de ello podemos pensar que dado que las vistas realmente son
tablas, se deberían poder consultar y actualizar mediante sentencias SQL, y puesto
que son derivadas, su existencia no existe físicamente en la BD como las tablas
sino que se genera cada vez que se hace una petición a esa vista.
Para crear la vista tenemos la orden CREATE VIEW <nombreDeVista>,
columnas as <sentenciasSelect> [WITH CHECK OPTION], y para borrar la vista
DROP VIEW.
Por ejemplo sobre una tabla de departamentos podemos crear la vista:
CREATE VIEW DeptRicos AS
SELECT * FROM Departamentos WHERE presupuesto>240000

Esta vista contendrá los departamentos de la tabla departamentos cuyo


presupuesto es mayor de 240.000.
Una vez creada la vista podremos consultarla como si fuese una tabla
cualquiera de forma que para el usuario final este hecho es completamente
transparente. Ahora bien, existen problemas con los cambios de contenidos. Los
cambios de contenido en una vista pueden suceder por dos razones:

 Cambia el contenido de las tablas que intervienen en la definición de la vista.


 Se ejecuta una petición de cambio directamente sobre la vista, y que el SGBD
tiene que traducir a un cambio sobre la tabla de la que parte.
20 · Bases de datos 2

Este segundo aspecto puede ser fuente de problemas porque a veces el SGBD
dispone de diferentes alternativas para propagar un mismo cambio, y por ello no
sabe cual elegir y muchas vistas no son actualizables. Solo serán actualizables estos
dos casos:
 La operación que queremos realizar en una operación de selección del álgebra
relacional sobre una única tabla o vista actualizable.
 La operación es una selección + proyección de álgebra relacional siempre que
la proyección incluya todas las columnas clave (primaria o alternativas) y todas
las columnas que incorporen la restricción NOT NULL.

Así pues aquellas vistas que, por ejemplo, incluyan operaciones de combinación
de dos o más tablas o que incorporen funciones de agregación o la cláusula GROUP
BY no serán actualizables.

2. COMPONENTES LÓGICOS DE CONTROL

Los componentes lógicos de control que vamos a estudiar son los


procedimientos almacenados, los disparadores y los privilegios.

2.1. Procedimientos almacenados

Un procedimiento almacenado es una acción o función definida por un


usuario que proporciona un determinado servicio. Una vez creado el procedimiento
se guarda en la BD y se trata como un objeto más de la misma. La utilidad de estos
procedimientos es para simplificar el desarrollo de aplicaciones, mejorar el
rendimiento de la BD y para encapsular un conjunto de operaciones que se
efectúan en una BD.
En Informix para escribir procedimientos almacenados podemos utilizar dos
tipos de sentencias: las propias del SQL (que no es un lenguaje
computacionalmente completo) y sentencias propias del SPL (Stored Procedure
Language que lo complementa).
El conjunto de sentencias que forman el procedimiento se sitúan entre la
sentencia inicial CREATE PROCEDURE nombreProcedimiento (parametrosEntrada) y
la sentencia final END PROCEDURE. Luego para ejecutar el procedimiento bastará
con EXECUTE PROCEDURE NombreProcedimiento (parametrosEntrada).
En principio, un procedimiento almacenado devuelve un conjunto de
valores único como resultado de su ejecución; es decir, en términos de SQL, una
única fila. Destacan entre estas sentencias los siguientes valores:

 Parámetros: Un procedimiento puede recibir un conjunto de parámetros de


entrada y devolver un conjunto de parámetros de salida como resultado de su
ejecución. Y también podemos tener parámetros tanto de entrada como de
salida. Para cada parámetro de entrada habrá que darle un nombre y asociarle
un tipo de datos y para los parámetros de salida es suficiente con indicar su
tipo de datos en la cláusula RETURNING.
 Variables: Se definen con la cláusula DEFINE y debe tener asociado un
nombre y un tipo de datos; eso sí, debe dársele un valor a las variables antes
de poderlas utilizar. Tenemos por un lado variables locales (opción por
defecto) cuyo ámbito de visibilidad queda restringido al procedimiento en el
que se hayan definido; y variables globales (se utiliza para ello la cláusula
GLOBAL). La diferencia entre ambas es que los valores de las variables locales
quedan descartadas una vez finalizada la ejecución del procedimiento
almacenado en el que se han definido, mientras que las globales se guardan y
evolucionan mientras está activa la conexión a la BD; se suelen utilizar éstas
últimas para permitir que un conjunto de procedimientos almacenados
intercambien valores, pero hay que evitar su utilización pues no son una buena
práctica de programación.
Bases de datos 2 · 21

 Sentencias condicionales: La sentencia IF sirve para establecer condiciones


en el flujo de un procedimiento almacenado y se pueden establecer distintos
niveles de anidamiento con la sentencia ELIF.
 Sentencias iterativas: Además del FOR y el WHILE (el primero cuando se
sabe a priori el número de iteraciones que deben ejecutarse) añadimos el
FOREACH que se utiliza en bucles que pueden seleccionar y manipular más de
una fila. Ésta es la sentencia más frecuente.
 Gestión de errores: Podemos distinguir dos tipos de errores: los errores
predefinidos y los específicos del procedimiento. Podemos a su vez en cada uno
de ellos actuar de dos formas: o no capturamos el error dentro del
procedimiento almacenado y dejamos que el mismo procedimiento cancele su
ejecución de manera inmediata (el error se reporta al nivel superior) o
capturamos el error y el mismo procedimiento se responsabiliza de gestionarlo.
En este último caso, además el procedimiento puede no cancelar su ejecución o
cancelarlo.
 ON EXCEPTION: Esta sentencia permite especificar las acciones que hay que
llevar a cabo en cado de que se produzcan errores y debe especificarse dentro
del procedimiento almacenado.
 RAISE EXCEPTION: Permite generar nuestros propios errores, es decir, los
específicos dentro del procedimiento almacenado.

2.2. Disparadores

Los componentes vistos hasta ahora no son suficientes para modelar todo
lo que puede ocurrir en el mundo real. Si imaginamos una tabla de stocks de
productos y queremos aplicar una regla para que cuando un producto quede por
debajo de 50 unidades se produzca una petición de 100 unidades más, podemos
hacer dos cosas:
 Añadir esta regla a todos los programas que actualizan el stock de los
productos. No es una solución muy convincente pues todo el código se
encontraría desperdigado por todo el programa, replicada y por lo tanto es
difícil de localizar y de cambiar.
 Realizar un programa adicional que haga un sondeo periódico de la tabla
comprobando la regla. En este caso aunque la regla está concentrada en un
único punto, si el sondeo se hace ocasionalmente pierde su razón de ser y si se
hace muy a menudo se pierde eficiencia.

Para evitar esto la solución correcta es poder incorporar a la BD una regla del
tipo: “Cuando se modifique el stock de un producto y pase a ser menor que 50, hay
que pedir 100 unidades nuevas” y esto es realmente un disparador.

Un disparador debe utilizarse para:


 Implementar una regla de negocio como la que hemos visto antes.
 Mantenimiento automático de una tabla de auditoría de la actividad en la BD,
como registro de los cambios que se hacen en la misma.
 Mantenimiento automático de columnas derivadas, que se recalculan cuando se
cambian las columnas a las que hacen referencia.
 Comprobación de restricciones de integridad no expresables mediante CHECK

Eso sí, los disparadores no deben utilizarse cuando se pueden resolver


fácilmente mediante otros mecanismos, como restricciones de clave primaria ni de
integridad referencial…

Para crear un disparador se utiliza la siguiente sintaxis:


CREATE TRIGGER <nombreDisparador> <acontecimiento> ON <nombreTabla>
[REFERENCING referencia] [BEFORE ListaAcciones] [FOR EACH ROW listaacciones]
[AFTER ListaAcciones]
22 · Bases de datos 2

Para cada tabla solo se puede tener un solo disparador para INSERT, uno
para DELETE y otro para UPDATE de cada una de las columnas. Las acciones
especificadas como BEFORE se ejecutarán una sola vez antes que la sentencia que
activa el disparador; las de AFTER después de ejecutada la sentencia que la activa.
Las acciones FOR EACH ROW se ejecutarán una vez por cada fila afectada por la
sentencia que activa el disparador e inmediatamente después de haberla
modificado, borrado o insertado.

Cuando se ejecuta una sentencia SQL contra una BD puede pasar que se
activen disparadores y que se violen restricciones de seguridad a la vez. Frente a
esto, el sistema debe decidir qué hay que hacer en primer lugar e Informix retrasa
la comprobación de las restricciones de seguridad hasta después de la activación de
los disparadores asociados, lo que permite añadir disparadores que reparen
restricciones de integridad

2.3. Privilegios

En una base de datos hay muchos usuarios y también muchos


componentes y objetos y por supuesto, no todos los usuarios deberán acceder a
todos los objetos, para ello existen las autorizaciones. Una autorización es un
privilegio que se otorga a un usuario o grupo de usuarios para realizar una
determinada operación sobre un cierto objeto de la BD. Permite la BD efectuar tres
tipos de privilegios: de bases de datos, tablas y de procedimientos almacenados.

Privilegios de BD
Cuando un usuario crea una BD tiene todos los privilegios sobre la misma y
será inaccesible a los demás usuarios hasta que lo autorice. Los privilegios que se
pueden conceder son:

 CONNECT: Permite al usuario conectarse a la base de datos, ejecutar select,


insert, update y delete (siempre que tenga los privilegios necesarios a
posteriori), crear vistas, tablas temporales, otorgar privilegios sobre una tabla
(siempre que sea propietario o haya recibido el privilegio adecuado) y ejecutar
alter o drop de una tabla (siempre que tenga los privilegios adecuados sobre la
misma).
 RESOURCE: Puede hacer todo lo que hace el usuario connect y además crear
tablas nuevas, índices nuevos, procedimientos almacenados nuevos y crear
disparadores.
 DBA: Permite todo lo anterior y otorgar cualquier privlegio de BD, borrar y
acceder a cualquier objeto de la BD y ejecutar DROP DATABASE

Para la concesión de privilegios se utiliza la expresión:


GRANT <privilegio> TO <ListaUsuarios>, como puede ser GRANT CONNECT TO
“Maria”; y para revocar privilegios tenemos la sentencia
REVOKE <privilegio> FROM <ListaUsuarios>

Privilegios de Tabla

Cuando un usuario crea una tabla será inaccesible para los demás hasta
que les conceda privilegios sobre ella. Existen 7 privilegios sobre las tablas:
 Insert
 Delete
 Select o bien Select de un conjunto de columnas
 Update o bien Update de un conjunto de columnas
 Referentes o bien Referentes de un conjunto de columnas, que permite realizar
borrados en cascada.
 Alter: Da derecho a añadir columnas y eliminarlas, cambiar el tipo de una
columna….
Bases de datos 2 · 23

Para conceder todos los privilegios se pude utilizar la palabra clave All; además en
la sintaxis de privilegios de una tabla:

GRANT <listadeprivilegios> ON <nombreTabla> TO <usuarios [WITH GRANT


OPTION

La última sentencia WITH GRANT OPTION añadida a un privilegio determinado no


solo la concede, sino que permite al receptor transferirlo.

Igualmente cuando se revocan privilegios se utiliza la expresión:

REVOKE <privilegios> ON <tabla> FROM <usuarios> [CASCADE|RESTRICT]

Si se especifica CASCADE (por defecto) el SGBD eliminará en cascada todos los


privilegios que el usuario revocado haya concedido usando el privilegio revocado.

Privilegios de Procedimientos Almacenados

Cuando se crea un procedimiento hay que especificar de entre los dos


siguientes, que tipo de privilegios tendrá:
 DBA-privileged: pueden crearse si el usuario tiene privilegio DBA y para
ejecutarlos sólo es necesario disponer del privilegio EXECUTE.
 Owner-privileged: Pueden ser creados por usuarios RESOURCE y para
ejecutarlos hayq ue tener el privilegio EXECUTE.

La sintaxis para conceder estos privilegios y para revocarlos es igual a la


conocida hasta ahora:

GRANT EXECUTE ON <procedimiento> TO <usuarios [WITH GRANT OPTION]


REVOKE EXECUTE ON <procedimiento> FROM <usuarios>

Para crearlo: CREATE PROCEDURE <nombre>


Si queremos que un usuario no pueda acceder a todas las columnas de una
tabla sino solo a algunas de ellas (por ejemplo a los nombres teléfonos y
direcciones de los empleados, pero no al sueldo), lo mejor es crear una vista y
darle al usuario sólo privilegios sobre la vista
Con todo lo visto anteriormente es muy complejo darle a todos los usuarios
los privilegios adecuados para cada uno de los objetos que componen la BD; para
facilitar este trabajo se crean roles, un rol es una agrupación de privilegios sobre
algunos de los componentes de una BD, de forma que se crea el rol y luego se
asignan usuarios a esos roles:

CREATE ROLE “lector”;


GRANT SELECT ON Tabla1 TO “lector”;
GRANT “lector” TO JUAN WITH GRAND OPTION;

Creamos el rol lector para poder leer en la tabla 1 y luego le asignamos ese
rol a Juan, además pudiendo él también conceder este privilegio al resto de
usuarios si lo desea.

Catálogo de una BD
3. CATÁLOGO

El catálogo de una BD es una metabase de


datos; una BD sobre una BD y también se suele
denominar diccionario de datos.
Hemos de tener en cuenta que una BD contiene
no solo las tablas, son también los usuarios,
procedimientos, privilegios, roles, etc. todo ello
conforman tablas consultables que se pueden ver en
informix con SELECT tabname FROM informix.systables;
24 · Bases de datos 2

pero a pesar de que son consultables desde aquí, no son actualizables


directamente, para ello se requieren mecanismos de más alto nivel para acceder a
las tablas del catálogo.
Bases de datos 2 · 25

TEMA 5 COMPONENTES DE ALMACENAJE DE UNA BASE DE DATOS

Tema 5 1. LA ARQUITECTURA DE LOS COMPONENTES DE ALMACENAJE


Componentes de almacenaje de
una base de datos
1. La arquitectura de los Como las BD son un conjunto de datos persistentes y esta persistencia se
componentes de almacenaje manifiesta porque los datos no han de desaparecer entre ejecuciones sucesivas del
2. El nivel lógico
3. El nivel físico programa, necesitamos almacenar todos estos datos en algún lugar no volátil, que
4. El nivel virtual es habitualmente un disco magnético.
5. Otros componentes de
almacenaje
La arquitectura de los componentes de almacenaje se divide en tres niveles
que estudiaremos a continuación:
Niveles de los componentes de almacenaje
 Nivel lógico: Se corresponde a los
componentes conocidos y manipulados por el
programador, tal como vemos en la figura lateral.
 Nivel Físico: Las tablas persistentes que se
almacenan en un soporte no volátil.
 Nivel Virtual: Se encuentra entre los dos
niveles anteriores.

2. EL NIVEL LÓGICO

Encontramos dos tipos de componentes el


lógico y la Bd. Los componentes lógicos a su ve
zpueden ser componentes de datos (tablas y
vistas) y componentes de control (restricciones,
disparadores, índices…).
La BD, en cambio, es un concepto un poco
más complicado de definir, dado que es una
herramienta específica del SGBD que sirve como
unidad administrativa para agrupar un conjunto de
otros componentes: Podemos tener una BD
comercial, otra financiera, otra de datos
personales, dentro del mismo conjunto del SGBD.

3. EL NIVEL FÍSICO

Los sistemas operativos gestionan los datos en los discos magnéticos a


partir de unas unidades globales denominadas ficheros. Normalmente la cantidad
de espacio de este fichero va creciendo a medida que lo necesita (extensión); pero
esta extensión no toma cualquier valor, sino que es un múltiplo de una unidad
mínima que es la página; con ella comenzaremos, de menor a mayor, el estudio del
nivel físico.
Estructura de una página
Una página es la unidad mínima de acceso
y de transporte del sistema de entrada/salida de un
SGBD, lo cual la hace ideal para ser a la vez la
unidad de organización más importante de los datos
almacenados. Bien es verdad que cuando se trae una
página de la memoria externa a la principal, no se
transporta una única página, pero sí se transporta
siempre un múltiplo del valor de una página. Eso sí,
la página internamente como podemos ver en la
figura lateral también tiene su estructura propia.:
 Encabezamiento: Con información de control.
 Filas: Corresponde a las filas de las tablas de
nivel lógico, puede variar su número con el paso del tiempo e incluso ser 0
26 · Bases de datos 2

(inicialmente). Tiene un encabezamiento y luego los campos de los que se


compone cada fila. En el encabezamiento se pueden guardar datos de control y
cuando una fila es más larga que una página, se puede partir en trozos.
 Campos: Son las unidades que conforman las filas, se componen también de
un encabezado que suele contener información sobre si el campo admite el
valor nulo o no y también la longitud del campo, y del contenido que es el
valor del campo en sí.
 Espacio libre: Siempre en el centro de la página.
 Vector de direcciones de fila: que tiene tantos elementos como filas hay en
la página, además se disponen en orden decreciente. El último elemento
apunta a la primera fila y así sucesivamente, de forma que el espacio libre de la
página siempre queda en el centro.

Existen otros tipos de páginas como son la página de índice, que aunque
lo hemos incluido en los elementos de control, realmente son componentes de
rendimiento para acelerar la búsqueda de filas determinadas dentro de la BD; eso
sí esta página de índice sigue la misma estructura que la estudiada hasta ahora.
Otro tpo de página es la de objeto grande muy en boga últimamente por la
irrupción de los elementos multimedia en la informática de consumo y se suelen
almacenar en otro tipo de estructuras diferentes dado su tamaño.

Gestión de páginas
Las principales operaciones que se utilizan son las siguientes:

 Formateado de una página: Cuando el SGBD necesita más espacio se


adquiere una nueva extensión y se formatea la página, es decir, se prepara
para recibir datos, escribiendo el encabezamiento y dejando el resto del espacio
libre.
 Carga inicial de filas: Se coloca la primera fila justo detrás del encabezado y
se crea un elemento del VDF al final justo de la página que apunta al inicio de
esta primera fila; a partir de aquí se repite el proceso, quedando el espacio
libre en el centro de la página y reservándose un porcentaje determinado
según el SGBD para las operaciones que veremos a continuación.
 Alta posterior de una nueva fila: Una vez seleccionada la página candidata
donde hay que añadir la fila, se utiliza el espacio libre existente para
introducirla, si no quedase espacio suficiente, la fila es colocada en otra página.
 Baja de una fila: Consiste básicamente en liberar el espacio ocupado por la
fila y el elemento del VDF; ya en ese mismo momento o más adelante se
producirá un desplazamiento de filas y elementos VDF para que la estructura
de la página continúe siendo la de siempre.
 Cambios de longitud de una fila: Puede ser por liberar espacio con lo que el
mecanismo es igual a la operación anterior; puede ser porque la fila aumente,
mientras que haya espacio en la misma página no hay problema; o si el
aumento de espacio no se puede servir en la misma página, se hace en otra y
en la original se crea una dirección que apunte a la nueva posición de la fila.

La extensión
Es un número entero de páginas, en principio consecutivas, que el sistema
operativo adquiere a petición del SGBD cuando detecta que necesita más espacio
para almacenar datos. Así el fichero aumenta de tamaño porque aumenta el
número de extensiones que lo forman. Las páginas de una extensión tienen que ser
físicamente consecutivas, pues así mejora el rendimiento general de la BD.

El fichero
El fichero es la unidad que utiliza el sistema operativo para gestionar el
espacio e los dispositivos periféricos (también es un conjunto de extensiones). El
sistema de gestión de los ficheros viene a ser parecido al sistema de entrada/salida
tradicional que se realiza por medio de bloques, pero tiene algunas diferencias. Así
cuando el SGBD necesita cargar en su memoria principal unos datos que se
encuentran en una página que está en la memoria externa, se lo pide al sistema
Bases de datos 2 · 27

operativo, que toma esa página, y generalmente las circundantes por si las
necesita, y este número de páginas es pasado a la memoria intermedia.

Además para optimizar el rendimiento como hemos dicho se lleva a la


memoria más de una página a la vez en el mismo
Funcionamiento del sistema operativo y del SGBD en la proceso de entrada/salida, e incluso se avanza en el
entrada/salida de una página
tiempo leyendo una página cuando se prevé que se
necesitará próximamente a la par que se realizan
otras operaciones, para que así ya esté la página
cargada en memoria.

4. EL NIVEL VIRTUAL

El nivel virtual requiere su existencia porque


cada tabla como la hemos estudiado no se almacena en un fichero. Por ejemplo:
hay tablas grandes que hay que fragmentar y almacenar cada fragmento en más
de un fichero; hay tablas muy pequeñas que pueden compartir un mismo fichero;
hay tablas cuyos campos multimedia son tan grandes que cada uno de ello se
almacena en un fichero independiente, etc. Por todo ello el nivel virtual
proporciona un grado elevado de independencia entre los niveles lógico y físico;
llamaremos espacio virtual al componente que implemente esta funcionalidad.

Correspondencia entre páginas virtuales y reales El espacio virtual es una visión diferente de
las páginas del nivel físico. Es otra forma de ver los
datos pero sin duplicarlos realmente; así el espacio
virtual es una secuencia de páginas virtuales que se
corresponden una a una con las páginas reales del
nivel físico pero ordenadas secuencialmente y sin
saltos en medio. Así en las páginas virtuales todos
los datos referentes a un mismo registro se
encuentra de forma contigüa pudiendo no ser así
en el nivel físico.
Cuando el SGBD necesita una fila
determinada (unidad mínima de información a la
que accede), lo que hace realmente es encontrar
las filas en el espacio virtual, el direccionamiento
del SGBD es pues del nivel lógico al virtual.
Posteriormente el sistema operativo hace una
relectura de ese espacio virtual al espacio físico
donde se hallan los datos. Es necesario hacer una serie de acotaciones ahora:
Una fila dada de alta y mientras permanezca viva, no puede cambiar de
página. Si otra fila se da de baja, puede reorganizar el espacio libre y cambiar el
apuntador de dentro de la página, pero sin cambiar de página. Si aumenta de
tamaño y hay que trasladarla a otra página, se mantiene un apuntador en la página
que señala la nueva dirección; de esta forma la BD seguirá teniendo un buen
rendimiento.

Los tipos de espacios virtuales que podemos encontrar son:

 Espacio de tablas: Las tablas que no son tan grandes que las queramos
controlar por partes, ni tan pequeñas que puedan compartir un espacio común,
suelen tener un único espacio virtual de tablas; eso sí puede perfectamente
estar repartido en varios ficheros.
 Espacio fragmentado: Cuando una tabla es tan grande que debemos partir
su espacio virtual se establecerá un criterio por el cual las diferentes filas de la
tabla irán a parar unívocamente a uno y otro fragmento, lo cual mejorará el
tiempo de acceso a los datos pues se “espera” donde poder encontrarlos.
 Espacio de agrupación: Cuando una tabla se relaciona tanto con otra u otras
que normalmente el acceso a la primera viene unido del acceso al resto, nos
28 · Bases de datos 2

interesará que se encuentren físicamente tan cerca como sea posible para
minimizar el tiempo de acceso global y aumentar el rendimiento de la misma.
 Espacio de objetos grandes: Ya hemos hablado de elementos multimedia,
entre otros, que ocupan un excesivo espacio. Estos objetos por ejemplo cuando
sus leídos por la entrada/salida del sistema operativo desplazarían todo el resto
de las páginas que se tienen cargadas en memoria y no interesa
evidentemente. Así el espacio que apuntan si por ejemplo es un fichero MP3 se
guarda en una página objeto, mientras que en la original solo se guarda un
apuntador a este objeto aparte.
 Espacio de índices: Los índices son estructuras de datos de longitud muy
pequeña y muy referenciada, por lo que interesa gestionarlo por separado de
las filas de las tablas. Estructuralmente los espacios de índices son muy
similares a los espacios de tablas aunque contienen páginas de índices en vez
de páginas de filas de tablas.

5. OTROS COMPONENTES DE ALMACENAJE

Una de las tareas del administrador de BD es calcular las necesidades de


espacio del disco de una determinada BD. Los cálculos sencillos no suelen servir; es
decir, si pretendemos calcular el espacio multiplicando el número de registros
máximo que esperamos tener por la ocupación de cada uno de esos registros, el
resultado será claramente insuficiente y distante de la realidad.

Debemos tener en cuenta otro tipo de espacios:

 El catálogo es el espacio ocupado por los metadatos: definición de los


componentes lógicos como tablas vistas, índices, restricciones…
 Tablas temporales: Que se crean generalmente invocadas indirectamente por
cláusulas tipo order by, select o distinct y que “viven” hasta que han servido el
dato final, pero que ocupan un espacio real.
 El dietario con los cambios efectuados en la base de datos para poder
recuperarlos como consecuencia de un desastre.

Hay que calcular el espacio necesario teniendo en cuenta el espacio ocupado


por los datos y por todos los aspectos vistos en este apartado.
Bases de datos 2 · 29

TEMA 6 IMPLEMENTACIÓN DE MÉTODOS DE ACCESO

Tema 6 1. LOS MÉTODOS DE ACCESO A UNA BASE DE DATOS


Implementación de métodos de
acceso
1. Los métodos de acceso a una En este módulo cuando hablemos de páginas, nos referiremos a las páginas
Base de Datos virtuales que ya habíamos nombrado en el módulo anterior; cuando se haga
2. Implementación de los
accesos por posición referencia a páginas reales se explicitará directamente. Dicho esto, los métodos de
3. Implementación de los acceso los vamos a dividir en 3 grupos, que estudiaremos detenidamente:
accesos por valor
4. Implementación de los
accesos por diversos valores  Accesos por posición: Puede ser acceso directo o secuencial por posición. El
5. Índices del sistema Informix acceso directo pro posición consiste en obtener una página que tiene un
número de página determinado dentro de un espacio. Por ejemplo INSERT INTO
empleados VALUES (25, ‘Juan’, 150, 2000), en este
Accesos por posición: Directo y secuencial
caso accedemos directamente a la página que
contiene el valor 25. El acceso secuencial por
posición implica obtener las páginas de un espacio
siguiendo el orden definido por el SGBD, por ejemplo
SELECT * FROM empleados. Donde accedemos desde el
primer al último empleado sin un orden predefinido,
sino directamente en el que estén almacenados los
datos.
 Accesos por valor: También puede ser directo
o secuencial. El acceso directo por valor consiste en
obtener todas las filas que cumplen un criterio
determinado (SELECT * FROM empleados WHERE
num_despacho = 150). Los accesos secuenciales por
valor consiste en obtener diversas dilas por el orden de los valores de un
atributo (SELECT * FROM empleados ORDER BY num_despacho o SELECT * FROM
empleados WHERE num_despacho>=100 and num_despacho<300 quizá este segundo
ejemplo sea más difícil de ver pero el SGBD debe devolver los empleados
organizados por el número de despacho).
 Accesos por diversos valores: Podemos querer acceder poniendo
condiciones a varios atributos y no solo a uno de ellos. En este caso también
tenemos acceso directo (SELECT * FROM empleados WHERE num_despacho=150 and
SUELDO=2000), y acceso secuencial (SELECT * FROM empleados ORDER BY
num_despacho, sueldo); e incluso contamos con accesos mixtos por diversos
valores, es decir, se combina el acceso directo por los valores de algunos
atributos y el acceso secuencial por los valores de otros atributos (SELECT *
FROM empleados WHERE sueldo=2000 ORDER BY num_despacho)

2. IMPLEMENTACIÓN DE LOS ACCESOS POR POSICIÓN

Los SGBD se basan para estos accesos casi completamente en el sistema


operativo, las rutinas de gestión de entrada/salida permiten obtener una página
real dada su dirección y por ello podemos decir que el sistema operativo
implementa el acceso por posición a las páginas reales.

3. IMPLEMENTACIÓN DE LOS ACCESOS POR VALOR

Si el SGBD se basara como en el caso anterior en el sistema operativo para


implementar los accesos por valor, no se obtendría un buen rendimiento, por ello el
SGBD dispone de mecanismos especializados que los implementan de manera
eficiente y esos mecanismos son los índices.
Si nosotros quisiéramos ejecutar la cláusula SELECT * FROM empleados WHERE
num_despacho = 150, deberíamos leer todas las páginas de la tabla empleado, leer el
valor del atributo num_despacho y seleccionar los que fuera igual a 150.
30 · Bases de datos 2

Lógicamente esto supondría un esfuerzo brutal si tuviésemos un elevado número


de empleados, quizá para luego extraer 2 ó 3 nada más; o más complicado todavía,
ejecutar la cláusula SELECT * FROM empleados ORDER BY num_despacho; es este caso
nos interesaría que la tabla estuviese guardada en el espacio virtual ordenada por
el número de despacho, pero cuando quisiésemos obtener los empleados
ordenados por sueldo, lo anterior no nos serviría.
Para evitar toda esta problemática tenemos los índices, que son como el
índice de un libro: son estructuras de datos auxiliares que facilitan la búsqueda
debido además por su reducido tamaño. Un índice contienen parejas de datos
llamadas entradas, formadas por un valor y un RID (número de página y número
del elemento del VDF). Cuando se busca mediante un índice primero se localizan
los valores en el índice con el fin de conocer su RID, y disponiendo ya de éste, se
utiliza un acceso directo por posición para conseguir la página que contiene la fila
de los datos que se busca.
Lógicamente, un índice debe estar organizado de modo que facilite la
búsqueda de los valores que contiene. Hay muchas formas de organizar un índice,
pero solo estudiaremos dos: los árboles B+ y la dispersión.
La estimación del coste de ejecución de estos métodos los calcularemos
considerando solo el coste de las entrada/salida pues suponen el componente
dominante en el coste de la operación total.

Árboles B+
Los árboles B+ son un tipo particular de árbol de búsqueda cuyo objetivo
primordial es el de intentar conseguir que éstas se efectúen con un número
pequeño de entrada/salida.
Todo árbol B+ tiene un número de orden d, que indica la capacidad de
sus nodos, así si un árbol tiene orden d, entonces sus nodos contienen como
máximo 2d valores.
Los nodos internos tienen como objetivo dirigir la búsqueda de la hoja
que tiene la entrada correspondiente a un valor determinado, por ello el acceso
directo por valor consistirá en trazar un recorrido del árbol que empezará en la raíz
y que irá bajando por los nodos del árbol hasta llegar a la hoja adecuada. Todo
nodo interno contiene valores y apuntadores hacia sus nodos hijo.
Los nodos hoja están conectados por apuntadores, sirviendo así para
facilitar el acceso secuencial por valor, pero además contienen todas las entradas
del índice, es decir, las parejas de valor y RID. Además todos los valores de un
nodo hoja son más pequeños que los valores del nodo hoja siguiente y todos los
valores de algún nodo interno del árbol están repetidos en algunas de sus hojas,
así que las hojas contienen todos los valores del árbol.

Cuando se quiere Estructura de un árbol B+


llevar a cabo un acceso
directo por valor, primero
hay que localizar la hoja que
contiene la entrada del valor
buscado y después utilizar el
RID de la entrada para
encontrar los datos a los que
se quiere acceder.
Para localizar la hoja
en cuestión, se comienza
desde el nodo raíz (por ejemplo buscamos el valor 8), como el nodo raíz es 20 nos
desplazamos por la hoja de la izquierda pues contiene los valores menores. En esta
hoja como 8>6, seguimos el segundo apuntador y ya hemos localizado el nodo
hoja que contiene el valor de entrada que buscamos.
Si la búsqueda fuese un acceso secuencial por valor, el mecanismo es el
mismo, lo único que debemos hallar el valor más bajo, y una vez encontrado nos
desplazamos por los nodos hoja (que recordemos están todos conectados), yendo
hacia la derecha buscando los valores más altos, hasta que se acabe la cadena de
hojas.
Bases de datos 2 · 31

Existen una serie de propiedades destinadas a mejorar el rendimiento


de los árboles B+, que básicamente consisten en que todos los nodos del árbol
(excepto la raí) deben estar llenos al menos hasta un 50% de su capacidad (esto es
así para reducir el número de nodos y evitar dar saltos entre nodos que están
vacíos) y además los árboles B+ deben ser equilibrados (todas las hojas están al
mismo nivel).

Para el cálculo del coste de localización de una entrada, es importante


haber sabido elegir correctamente el tamaño adecuado para los nodos. Nos
interesa que el árbol tenga una altura pequeña, así que los nodos serán grandes
pero sin sobrepasar el tamaño de una página, dado que de lo contrario no se
podrían consultar con una única operación de entrada/salida. En consecuencia, el
tamaño habitual de los nodos de un árbol B+ coincide con el de las páginas y así
cada nodo se almacena en una página virtual diferente. Así en un árbol de altura h
son necesarias h operaciones de entrada/salida para localizar una entrada del árbol.

Al insertar un nodo debemos reorganizar el árbol B+ para que siga


cumpliendo las propiedades destinadas a mejorar el rendimiento. Si al inserta el
nodo hoja, esta hoja tiene espacio libre, no hay problema. Si en cambio no lo tiene,
es necesario dividir ese nodo e incluso ayudarse del nodo hermano de la derecha
para distribuir los nodos hoja y seguir cumpliendo los criterios del árbol B+. La
división del nodo hoja, puede crear la obligación de crear un nodo padre, si éste no
tiene espacio suficiente para acogerlo.

Al suprimir un nodo hoja puede ocurrir que la hoja quede con menos
valores de los necesarios para cumplir los criterios de eficiencia, en este caso se
echará mano del nodo hermano de la derecha, y si no lo hay de la izquierda,
repartiéndose los valores y suprimiendo una entrada en el nodo padre; incluso
puede ocurrir que esto acarreé la necesidad de suprimir un nivel completo en el
árbol, lo cual sólo puede ayudar a ser más eficientes en las búsquedas.

Los índices que permiten implementar los accesos secuenciales por valor
(como los árboles B+) pueden ser índices agrupados o no agrupados. Un índice
agrupado es aquel en el que los datos que indexa están ordenados físicamente
según el acceso secuencial por valor que proporciona el índice. Para una misma
tabla podemos tener varios índices, pero solo uno de ellos puede ser agrupado. Por
ejemplo en la tabla empleados podemos indexar por el apellido. De forma que
cuando hagamos una búsqueda ordenada por apellidos, los RID que se obtendrán
apuntarán consecutivamente a filas contiguas, y así se podrán hacer muchos
accesos seguidos a filas de una misma página con una única entrada/salida.

Dispersión

Los índices basados en la dispersión consiguen un rendimiento ligeramente


superior al de los índices basados en árboles B+ siempre que se trate de accesos
directos por valor; en cambio no implementan los accesos secuenciales, por ello
muchos SGBD solo implementan árboles B+.

La dispersión básicamente trata de colocar las entradas en las páginas


según una función de dispersión h determinada. Así para hallar en qué página se
encuentra el valor x, se aplica la función de dispersión h y directamente devuelve
un valor h(x)=página. Hay muchas funciones de dispersión diferentes y aplicables;
además en cada página caben evidentemente más de un valor. Aquellos valores
que una vez aplicada una función de dispersión devuelven el mismo número de
página, se denominan sinónimos y sus entradas lógicamente comparten la misma
página. Los valores que caben en una página son N y los sinónimos L. El problema
tendrá lugar cuando L>N, es decir, hay más sinónimos de los que caben en una
página. En este caso, se crea una página excedente donde se van guardando los
sinónimos excedentes de esa página y se crea un apuntador en la página primaria
32 · Bases de datos 2
Páginas excedentes

que apunta a la página excedente. Si por cualquier


causa o porque la función de dispersión no es muy
buena se llena la página excedente, se crea una
segunda página excedente que es apuntada desde
la primera página excedente.

Así, en el ejemplo lateralr, se ha creado


una función de dispersión h(x9=(x mod 5)+1,
quizá no muy bien elegida, dado que N=3 y
tenemos varias páginas excedentes.

Es fácil darse cuenta que el coste de


localizar una entrada depende directamente de si la entrada es un excedente o se
encuentra en la página primaria. Si se encuentra en este último caso el coste es
una sola entrada/salida, en cambio si es excedente habrá 2 ó más entrada/salida.
Por tanto para conseguir un buen rendimiento, interesa que haya pocas
páginas excedentes y esto se consigue modificando el factor de carga.

Este factor es igual al número de entradas que se espera tener dividido por
el número de entradas que caben en las páginas primarias:

C = M / (N*L)

Cuanto más bajo sea el factor de carga (C), menos excedentes habrá y
menos entrada/salida serán necesarias; en contrapartida si el factor de carga es
muy bajo, habrá desaprovechamiento de espacio. Si el factor de carga es por
ejemplo C=0,5, se malgastará la mitad del espacio.

4. IMPLEMENTACIÓN DE LOS ACCESOS POR DIVERSOS VALORES

Implementación de los accesos directos

Si por ejemplo quisiésemos ejecutar la cláusula SQL:


SELECT * FROM empleados WHERE num_despacho = 150 AND sueldo=1200;

Podríamos utilizar el índice del atributo num_despacho, para localizar


aquellos empleados cuyo num despacho es igual a 150; después localizar a través
del índice de atributo sueldo los que cumplen el criterio de sueldo igual a 1200 y
después hacer una intersección de los dos conjuntos. Con esta estrategia
aprovechamos los índices que ya tenemos, pero tiene un mal rendimiento en el
caso de que haya muchos empleados que cumplan el primer y segundo criterios,
pero pocos que cumplan los dos a la vez.
Para solventar este problema existen los índices de valores
compuestos, son índices que contienen valores de dos atributos; así por ejemplo
si creamos el índice de valores compuestos [num_despacho, sueldo], se
organizarían en nodos de árbol B+ ordenados primero por num_despacho y
después por sueldo, así [150, 1000] < [150, 1500].

Implementación de los accesos secuenciales y mixtos

En este caso se sigue el mismo método visto anteriormente, con la


problemática de que si la búsqueda fuese primero por sueldo y después por
número de despacho, no nos serviría el índice creado en el apartado anterior.

5. ÍNDICES DEL SISTEMA INFORMIX

El sistema informix pone al alcance del diseñador los índices estudiados en este
tema; así para crear un índice con el valor del número de despacho:
Bases de datos 2 · 33

CREATE INDEX indice_num_despacho ON empleados (num_despacho);

Para crear un índice agrupado:

CREATE INDEX CLUSTER indice_num_despacho ON empleados (num_despacho);

Para crear un índice por diversos valores:

CREATE INDEX indice_num_despacho ON empleados (num_despacho, sueldo);

Finalmente recordar que estos índices tienen por defecto un orden ascendente, si
por el contrario se prefiere o necesita un orden descendente:

CREATE INDEX indice_num_despacho ON empleados (num_despacho DESC);


34 · Bases de datos 2

TEMA 7 BASES DE DATOS DISTRIBUIDAS Y CLIENTE/SERVIDOR

1. VISIÓN GENERAL DEL ACCESO A BASES DE DATOS POR RED

Una aplicación de acceso a bases de datos debe distribuir las funciones que Tema 7
Bases de datos distribuidas y
han de ejecutar los diferentes ordenadores que están conectados: cliente/servidor
1. Visión general del acceso
 Almacenamiento de datos: Puede haber uno o más ordenadores con acceso a a bases de datos por red
2. Bases de datos cliente/servidor
los dispositivos físicos de almacenamiento. 3. Bases de datos distribuidas
 Ejecución del código: Tanto el código de la aplicación con el de los SGBD, una 4. Ejemplo de aplicación
parte debe ejecutarse en el ordenador del cliente y otra en los servidores de cliente/servidor y distribuida

datos.
 Almacenamiento del código: Normalmente se almacena el código necesario en
cada parte donde se ejecuta, sea el cliente o sea el servidor.

El procesamiento se distribuye de la siguiente manera:

 Entrada/salida básica: Controla la pantalla, teclado, ratón a nivel muy


elemental.
 Gestión interfaz usuario: Presenta y captura los datos de la aplicación
 Lógica de la aplicación: Efectúa las actualizaciones y consultas necesarias de
acuerdo a las peticiones de los usuarios.
 Gestión de acceso a datos: Servicios de alto nivel para hacer consultas y
actualizaciones.
 Acceso básico a los datos: Leer y escribir los datos en la memoria externa.

Descomposición en capas de una aplicación de acceso a una base de datos

Hablaremos por tanto de aplicaciones de BD cliente/servidor siempre


que una parte de la aplicación se ejecute en un ordenador cliente, y el acceso a los
datos almacenados tenga lugar en uno o más ordenadores servidores, con los
cuales se comunica el cliente. Ahora bien, las posibilidades de que el procesamiento
anterior se realice en mayor medida en el cliente o en el servidor son las siguientes
(la barra marca la posición de la red):

 a/bcde: El cliente solo accede a los dispositivos de interacción básicos con el


usuario, en el servidor se ejecuta todo el resto de la aplicación (un ejemplo son
las aplicaciones basadas en X-windows).
 ab/cde: Todos los aspectos de interacción con el usuario se realizan en el
cliente mientras que en el servidor toda la lógica de la aplicación y acceso a
datos (monitores transaccionales por ejemplo).
 abc/de: La lógica de la aplicación también se hace en el cliente y el servidor
atiende peticiones del cliente para realizar consultas y actualizaciones de alto
nivel.
 abcd/e: El cliente controla casi todos los aspectos de la aplicación, a excepción
del acceso físico a los datos almacenados (no se puede ir más lejos).

Se denominan bases de datos distribuidas a aquellas en que los datos


almacenados se encuentran en más de un ordenador; si todos los datos que
requiere la aplicación se hallan en el mismo ordenador, entonces hablamos de BD
centralizadas. Diferenciar esto de una aplicación cliente/servidor. Una aplicación
cliente/servidor puede ser centralizada si los datos se hallan todos en el mismo
Bases de datos 2 · 35

Niveles de distribución ordenador o distribuida si se hallan en almacenamientos distintos. Encontramos dos


grandes tipos de bases de datos distribuidas:

 Los SGBD puros o fuertemente acoplados: suelen ser el resultado de un


desarrollo descendente, mediante el cual se diseña una aplicación por decisión
expresa de los desarrolladores desde cero y según eso se desarrolla el modelo
de datos. Esto mejora el rendimiento, la fiabilidad y la posibilidad de compartir
datos, aunque la aplicación se vuelve compleja.
 Los SGBD federados o levemente acoplados: No suelen ofrecer un acceso
totalmente integrado de los datos y es que su origen suele estar en un
desarrollo ascendente, mediante el que se desarrolla una aplicación que intenta
gestionar un conjunto preexistente de bases de datos.

Los niveles de distribución que podemos encontrar en estas BD son:

 Nivel de petición remota: Cada petición efectuada en el servidor es una única


transacción.
 Nivel de unidad de trabajo remota: Se pueden enviar al servidor varias
sentencias desde un mismo ordenador que son tratadas como una única
transacción.
 Nivel de unidad distribuida de trabajo: Permite acceder a más de un servidor
distinto en la misma transacción, aunque cada petición se tiene que ejecutar
exclusivamente en un único servidor.
 Nivel de petición distribuida: Una misma sentencia puede ser ejecutada al
mismo tiempo por varios servidores, que han de colaborar para obtener el
resultado final.

Entre los aspectos críticos que se pueden encontrar en la construcción de


aplicaciones encontramos:

 Impacto del tráfico de red en el rendimiento: Tanto en las LAN (Redes de


área local, utilizadas en todo un edifico o en edificios adyacentes) como en las
WAN (Wide Area Network, utilizada en zonas más amplias pero menos rápida y
flexible que las LAN) el acceso datos por red puede convertirse en un cuello de
botella para el rendimiento general.
 Gestión de transacciones: La concurrencia y la recuperación son
imprescindibles por tanto hay que evitar fallos en las comunicaciones que
puedan violar la atomicidad y definitividad de las transacciones.
 Acceso integrado a los datos: Debemos poder acceder a tablas, vistas y
procedimientos igual que si de un proceso centralizado se tratase.
 Seguridad e integridad de los datos: Deben existir herramientas que sin
imponer excesivas limitaciones a los usuarios puedan controlar la integridad de
los datos. Tanto con disparadores, restricciones de integridad y roles podemos
conseguirlo.

2. BASES DE DATOS CLIENTE/SERVIDOR

En una aplicación BD cliente servidor, hay una parte cliente que recibe las
peticiones de la aplicación y una parte servidor que lleva a cabo el acceso a los
datos; ambas partes se comunican por medio de la red como vemos en la figura
lateral.
Hay dos tipos básicos de arquitectura:

Comunicación entre cliente y servidor  Cliente ligero/servidor pesado: La


mayor parte de la funcionalidad del SGBD
está en el servidor. El cliente hace poco más
que enviar al sevidor peticiones de la
aplicación y devolver las respuestas. Se
suele utilizar en arquitecturas del tipo
36 · Bases de datos 2

ab/cde y abc/de. La utilización de un servidor pesado permite disminuir el


tráfico de la red consiguiendo que solo se envíe información útil al cliente.
 Cliente pesado/servidor ligero: Todo el procesamiento se hace en el
cliente. La parte servidor atiende únicamente peticiones de lectura y
actualización de páginas de disco. Este enfoque encaja con el esquema abad/e
y lo siguen SGBD pensados para uso personal (Ms. Access) y pocos usuarios.
Cuando el acceso a datos es pequeño, hay poco tráfico de red, este tipo de
esquema puede ser interesante.

Los SGBD con servidor pesado, permiten dos tipos de arquitecturas de


aplicación: arquitectura de dos capas: la aplicación del cliente trabaja directamente
con las estructuras de almacenamiento de la BD; y la más interesante la
arquitectura de tres capas: El cliente hace peticiones de ejecución de
procedimientos almacenados en el servidor y son sólo estos procedimientos los que
acceden a las estructuras de datos. Esto tiene varias ventajas:
 Los procedimientos almacenados se pueden optimizar estáticamente y no
durante la ejecución.
 No todas las consultas y actualizaciones tienen que pasar por la red, con lo que
se reduce el tráfico.
 Se mejora la seguridad pues los usuarios solo pueden utilizar los
procedimientos, evitándose así operaciones no previstas.
 Los cambios en la aplicación se pueden llevar a cabo cambiando el
comportanmiento de los procedimientos sin tener que modificar los clientes.

3. BASES DE DATOS DISTRIBUIDAS

Hay 12 reglas fundamentales que debe cumplir Comunicación entre cliente y servidor
todo SGBD que trabaje con datos distribuidos:
 Máxima autonomía local.
 Igualdad entre servidores
 Operación continuada
 Transparencia de localización
 Transparencia de fragmentación
 Transparencia de replicación
 Procesamiento distribuido de consultas
 Gestión distribuida de transacciones
 Independencia del hardware
 Independencia del sistema operativo
 Independencia de los protocolos de red
 Independencia del SGBD

En general estas doce reglas se pueden resumir en


dos ideas básicas:
 El conjunto de BD distribuidas debe verse como
una sola BD centralizada. Únicamente para los
diseñadores o administradores del sistema debe
ser visible el modo distribuido.
 Hay que evitar limitaciones en el trabajo a causa
de caidas de los servidores o fallos en las
comunicaciones.

Arquitecturas

Las arquitecturas que encontramos son de 4 tipos y se


pueden ver en la tabla lateral:

 Conexiones independientes: Se establecen


conexiones separadas para cada uno de los
servidores que se quieren utilizar. La aplicación es la que debe gestionar todas
Bases de datos 2 · 37

las relaciones entre los datos con lo cual el rendimiento y la integridad de los
datos es deficiente.
 Capa intermedia de gestión de datos: Esta capa proporciona un acceso
más o menos integrado a la gestión de datos. Esta forma de trabajar suele ser
viable para aplicaciones de consulta con pocas exigencias de rendimiento e
integridad de los datos.
 Distribución en el cliente: Es un acceso más integrado que los anteriores y
ofrece un rendimiento aceptable aunque si el cliente es ligero normalmente hay
que acceder a cada uno de los servidores por separado.
 Distribución en el servidor: Es la solución más común y así se alcanza el
máximo grado de acoplamiento.

Para acceder a los elementos de una base de datos que se encuentran en


otro servidor, se suelen referenciar con un link: CREATE DATABASE LIND deptpers
USING <Info.Conexion>, si además se crea un sinónomo: CREATE PUBLIC SYNONIM
empleados FOR empleados@deptpers; ya se podrá acceder a la tabla empleados
desde cualquier servidor.

Las transacciones distribuidas una vez iniciadas en un servidor, deben


propagarse al resto de los que intervienen y mantener las opciones de seguridad tal
si se tratasen de transacciones centralizadas. Para ello contamos con el protocolo
de confirmación en dos fases y la prevención de abrazos mortales.

El protocolo de confirmación en dos fases es el mecanismo que siguen los


servidores implicados en una transacción para garantizar que si una transacción se
confirma en un o de los servidores implicados, suceda lo mismo en todos los
demás. Tiene dos fases como su nombre indica:
 En la primera fase el servidor coordinador (que puede ser el que inicia la
transacción o se elige el más estable) pregunta a los otros servidores si están
dispuestos a confirmar la transacción. Los servidores que responden
afirmativamente son anotados y si todos responden que sí, el coordinador
decidirá confirmar la transacción.
 En la segunda fase se hace efectiva la decisión anterior y el coordinador envía
un mensaje a todos los participantes para comunicarles si tienen que confirmar
o cancelar la transacción.
Este protocolo es muy sensible a caídas de la red, pues si la red cae y el
coordinador no puede comunicarse con los demás, éstos dejarán las transacciones
bloqueadas.

La detección distribuida de abrazos mortales se complica más que en las


aplicaciones centralizadas, es posible un abrazo mortal global a causa de un ciclo
de espera entre diversos servidores, sin que exista o se detecte un abrazo mortal
local. Para evitar los abrazos globales, los servidores tienen que enviarse
periódicamente información sobre las relaciones de espera entre las transacciones,
lo cual supone un coste alto en red, u otra solución más sencilla que consiste en
permitir sólo un tiempo máximo de espera, lo cual puede dar al traste con
transacciones correctas aunque lentas.

Existen mecanismos de distribución de datos cuya finalidad es mejorar el


rendimiento del SGBD distribuida a través de un decremento del uso de la red, para
ello cuenta con 3 mecanismos: fragmentación, replicación y cachés persistentes.

 Fragmentación horizontal: Consiste en repartir el almacenamiento de filas


de una tabla entre diversos servidores. Así si una entidad de una gran empresa
utiliza más los datos relativos a la población a la que da cobertura, es normal
que en la base de datos local de la empresa se encuentren los datos asociados
a esos clientes, a los que desde otras sedes se puede acceder pero se hace
menos veces.
 Fragmentación vertical: Consiste en repartir el almacenamiento de columnas
de una tabla en distintos servidores. Por ejemplo si en el departamento de
38 · Bases de datos 2

contabilidad trabajan mucho con los sueldos de los empleados, se pueden


cambiar estas columnas a este departamento. Eso sí, la fragmentación vertical
obliga a pasar también las claves primarias de esa tabla.
 Replicación: Consiste en el almacenamiento de copias idénticas de tablas o de
fragmentos de tablas en distintos servidores. Como nos podemos imaginar el
problema estriba en la coordinación de los datos. Existe para ello la
replicación síncrona en las que las actualizaciones en un servidor se
propagan inmediatamente al resto que tenta réplicas (lo cual requiere un
entorno de red robusto) o replicación asíncrona en la que los datos se
actualizan en todos los servidores cada período de tiempo; este último modelo
tiene menos requerimientos pero debemos saber que podemos estar usando
durante un lapso de tiempo ciertos datos ya obsoletos.
 Cachés persistentes: Consiste en almacenar en un servidor una copia de una
parte de los datos almacenados en otro; la parte que se guarda es la que tiene
más posibilidades de que se vuelva a acceder a ella; así si un cliente consulta
uno de estos datos en la caché no será necesario pedirlo de nuevo al servidor
central.

4. EJEMPLO DE APLICACIÓN CLIENTE/SERVIDOR Y DISTRIBUIDA

En la tabla lateral podemos observar un Aplicación cliente/servidor y distribuida


ejemplo de aplicación cliente/servidor y a la vez
distribuida. Se trata de una empresa de
distribución de aguas que tiene una sede central y
diversas delegaciones. Cada sede internamente se
comunica por una LAN y entre sedes por una WAN
(es más lento). Los datos se hallan todos en el
servidor central y los cambios se propagan asíncro
y automáticamente por la noche (las delegaciones
van con retraso pero lo aceptan) Se utiliza un
modelo de cliente pesado y servidor ligero, por lo
tanto la mayor parte de las funciones se
desarrollan en el cliente. Se utilizan cachés
persistentes en los servidores locales, ello hace
que los datos se actualicen poco pero se consulten
bastante.

Dado que los datos se hallan en el servidor


central, todas las noches tras propagar los cambios a las delegaciones, se hace
copia de seguridad de los datos.

Esta arquitectura soporta la caída del servidor local de una delegación sin
que las demás se afecten (porque no usa replicación síncrona ni protocolo de
confirmación en dos fases), pero no así el servidor central que provocará una
parada general, por lo cual éste es más robusto y fiable que los de las
delegaciones.
Bases de datos 2 · 39

TEMA 8 OTROS TEMAS DE BASES DE DATOS

Tema 8 1. OPTIMIZACIÓN DE CONSULTAS


Otros temas de bases de datos
1. Optimización de consultas
2. Herramientas de Dada una consulta en SQL es posible encontrar diversas consultas
administración equivalentes expresadas en álgebra relacional. Cada una de estas consultas se
puede representar gráficamente y además tendrá un coste asociado distinto según
Representación gráfica de el orden en que se hayan realizado sus cláusulas; la misión por tanto del SGBD es
las operaciones de álgebra determinar cómo tiene que ejecutarse la consulta para que el coste asociado sea
relacional
mínimo. Este coste asociado que busca un gasto de recursos mínimos se va a basar
Unión Proyección
Diferencia Selección sobre todo en el número de accesos a disco que debe realizar.
Intersección Combinación Nat.
Producto Cartesiano
El objetivo de la optimización de consultas es encontrar el plan de
acceso a la consulta que tiene asociado un coste mínimo (intervalo de tiempo
necesario para encontrar la respuesta a la consulta formulada por el usuario).

Para verlo con facilidad, pondremos un ejemplo: Tenemos una tabla de


empleados, otra de proyectos y otra de asignaciones de proyectos debidamente
cumplimentadas, y queremos llevar a cabo la consulta siguiente, teniendo en
cuenta que la cantidad de empleados (CARD) es 100, proyectos 20 y asignaciones
400 y que un 30% de los empleados dedican más de 200 horas al proyecto:

SELECT empleados.nombre_empl, empleados.num_empl, asignaciones.num_proy


FROM empleados, asignaciones
WHERE empleados.num_empl=asignaciones.num_empl AND asignaciones.dedic > 200

En este caso encontram os las tres estrategias diferentes implementadas en


el árbol sintáctico de la consulta:

Representación gráfica de las operaciones de álgebra


relacional
40 · Bases de datos 2

Podemos observar que cada estrategia tiene un coste diferente, por lo que
el orden de ejecución de las operaciones formuladas dentro de una consulta,
repercute directamente en el coste de ejecución de la consulta.

 La optimización sintáctica de una consulta es el proceso que determina un


orden de ejecución razonablemente adecuado de las operaciones que incluye
una consulta. Comienza con la traducción de la consulta original en un árbol
sintáctico equivalente y finaliza cuando se ha encontrado el árbol óptimo.
Generalmente el SGBD intenta ejecutar las operaciones de álgebra relacional
que decrementen la cardinalidad de los resultados intermedios lo antes posible,
a la par que intenta retrasar al máximo las que lo incrementan.
 La optimización física de una consulta evalúa el coste total de ejecución del
árbol sintético óptimo asociado a una consulta, para ello el SGBD debe conocer
las estadísticas de la BD para considerar el tamaño de los resultados
intermedios y las estructuras de almacenaje del esquema interno que pueden
acelerar las búsquedas como dónde se encuentran los ficheros, si se han
definido índices de agrupación, etc.
 La optimización semántica de la consulta intenta simplificar las consultas
realizadas por los usuarios teniendo en cuenta las reglas de integridad y la
lógica que se han definido sobre la BD. Así por ejemplo si en el ejemplo
anterior intentásemos hacer una búsqueda de los empleados cuyo salario es
mayor que el de su jefe, de existir optimización semántica (que no está
implementado en los SGBD actuales) ni se llegaría a realizar la operación, pues
es una regla de integridad que los empleados no pueden ganar más que sus
jefes.

2. HERRAMIENTAS DE ADMINISTRACIÓN

Consisten en software que incorporan los SGBD para facilitar las tareas de
gestión y administración de la base de datos. Actualmente estas herramientas han
mejorado mucho, permitiendo una interfaz de usuarios y ventanas y paneles
desplegables que facilitan mucho la tarea del administrador de bases de datos.

Vamos a encontrar dos grandes tipos de herramientas de administración:


las herramientas de administración central y las herramientas de edición y
manipulación de BD.

Las herramientas de administración central son capaces de ejecutar


las siguientes operaciones:

 Operaciones relacionadas con el servidor de la BD: Puesta en marcha y


desconexión del servidor.
 Llamada a otras herramientas de administración: Herramientas de gestión de
espacios de almacenaje, gestión de esquemas, recuperación y copias de
seguridad frente a casi todo tipo de desastres.
 Supervisión del funcionamiento del servidor: Proporciona información sobre las
sesiones de trabajo activas de los distintos usuarios, el estado de las
actividades destinadas a garantizar la recuperabilidad de los datos, posibilidad
de controlar las situaciones de emergencia y dispositivos para generar informes
de incidencias varias.

Las herramientas de edición y manipulación de las BD en el informix


personal edition se encuentran centralizadas en el SQL editor, y desde él es
posible:

 Crear, recuperar y modificar documentos de SQL, que en realidad no son más


que ficheros de texto con la extensión SQL.
 Introducir nuevas sentencias SQL, hacer comprobaciones sintácticas de las
mismas e incluso guardarse en documentos independientes.
Bases de datos 2 · 41

 Ejecutar pedidos SQL, cuyos resultados salen en ventanas adicionales.

Las herramientas que se encuentran por tanto en Informix y que nos ayudan a
realizar todas estas tareas son: Command Center, Schema Knowledge, Informix
Server Administrador, Control Center, SQL Enterprise Manager.

Texto elaborado a partir de:


Bases de datos II
Jaume Sistac Planas, Rafael Camps Paré, M. Elena Rodríguez González, Toni Urpí Tubella,
Ramón Segret i Sala, Dolors Costal Costa, Pablo Costa Vallés
Febrero 2006