0% encontró este documento útil (0 votos)
13 vistas14 páginas

Fundamentos de Bases de Datos y SQL

El documento proporciona una introducción a las bases de datos, cubriendo niveles de esquemas, el modelo relacional, lenguajes SQL y álgebra relacional, así como componentes lógicos y procedimientos. Se detallan conceptos clave como la independencia lógica y física, reglas de integridad, operaciones de álgebra relacional y transformaciones de asociaciones. Además, se abordan procedimientos y disparadores en bases de datos, junto con ejemplos de sintaxis SQL.

Cargado por

Jaume Alos
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
13 vistas14 páginas

Fundamentos de Bases de Datos y SQL

El documento proporciona una introducción a las bases de datos, cubriendo niveles de esquemas, el modelo relacional, lenguajes SQL y álgebra relacional, así como componentes lógicos y procedimientos. Se detallan conceptos clave como la independencia lógica y física, reglas de integridad, operaciones de álgebra relacional y transformaciones de asociaciones. Además, se abordan procedimientos y disparadores en bases de datos, junto con ejemplos de sintaxis SQL.

Cargado por

Jaume Alos
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd

Bases de Datos

Tema 1 - Introducción
Nivel externo → Lo que ve el Esquema externo → Contiene los datos
Esq. Ext 1 Esq. Ext 2 … Esq. Ext n que el usuario puede ver (pueden no ser
usuario
todos)
Nivel conceptual → Estructura
de la base de datos Esquema conceptual → Describe los
Esq. Conc.
(Ej: Edad → int) atributos, clases asociaciones y
restricciones
Nivel interno → Esquema interno → Métodos de acceso y
Esq. Int.
Almacenamiento de datos organización de los archivos que almacena
la BD
Independencia lógica:
- Cambios en el esquema conceptual no afectan a los esquemas externos que no hagan referencia a las
clases, atributos o asociaciones modificadas (Ej: añadir un atributo no afecta a la vista).
- Cambio en un esquema externo no afectan a los otros esquemas, ni a los esquemas conceptual ni interno
(Ej: añadir/eliminar vistas no afecta a las vistas independientes a esta).
Independencia física:
- Cambios en el esquema interno no afecta a ninguno d ellos otros dos esquemas (Ej: cambio en el tamaño
de las páginas, métodos de acceso).

Tema 2 – Modelo Relacional


Tupla → Fila (Cardinalidad = nº tuplas)
Atributo → Columna (Grau = nº atributs)
Nombre de la
Se denota: N(A1, A2, ... , An)
Esquema de relación (N)
la relación
Atributos (A)
Relación Tabla
Estensión de la Conjunto de tuplas que siguen
relación (cuerpo) un esquema de la relación
Dominio → Conjunto de valores atómicos (Ej: int, string…)
En BD cuando un valor es NULL significa que el valor inexistente, es desconocido.
Nombre de la Relación Atributos

EMPLEADOS DNI Nombre Teléfono


40.444.255 María Domínguez NULL
33.567.711 Pere Roca NULL Tupla
77.232.144 Elena Pla 934452435

Dominio: char(n) Dominio: integer


Dominio: Numeros_de_DNI
Conjunto atómico definido por el usuario
EMPLEADOS(dni, nombre, telefono)

Reglas de integridad
- Regla de integridad de entidad: claves primarias únicas y sin valor NULL.
- Regla de integridad referencial: no puedes tener un valor en una foreign key (atributo de una tabla que
referencia a otro de otra tabla) que no exista en la tabla.
- Restrict → No permite borrar o modificar la clave primaria referenciada en alguna foreign key.
- Cascade → Cuando se borra o modifica una clave primaria referenciada en alguna foreign key se
borran o modifican todas las referencias.
- Anulación → Al borrar o modificar una clave primaria referenciada en alguna foreign key, se
ponen a NULL todas las referencias.
- Regla de integridad de dominio: respetar el tipo de valor (Ej: integer → introducir un int).

1
Bases de Datos

Tema 3.1 – Lenguajes: SQL


Unión → R = TABLA1 ∪ TABLA2
Se aplica a relaciones que sean compatibles (tienen esquemas con un conjunto de atributos idéntico y
los dominios de cada pareja de atributos son los mismos). La unión resulta en una tabla con las tuplas
de TABLA1 y TABLA2.
Renombramiento → R = TABLA {atributo1 -> atributoA, atributo2 -> atributoB}
La relación resultante no cambia solo cambian el nombre de los atributos.
Intersección → R = TABLA1 ∩ TABLA2
Se aplica a relaciones compatibles y como resultado obtenemos las tuplas que tienen en común
TABLA1 y TABLA2.
Diferencia → R = TABLA1 – TABLA2
Se aplica a relaciones compatibles y como resultado tenemos las tuplas de TABLA1 que no están en
TABLA2.
Producto cartesiano → R = TABLA1 × TABLA2
El resultado es una tabla que tiene los atributos de TABLA1 y TABLA2 combinando las tablas haciendo
que haya tuplas de TABLA1 × tuplas de TABLA2.
Selección → R = TABLA(condiciones)
Resulta una tabla que cumple las condiciones de TABLA.
Proyección → R = TABLA[atributo1, atributo2]
Resulta una tabla que contiene solo los atributos seleccionados de TABLA.
Combinación → R = TABLA1[condiciones]TABLA2
Resulta una combinación entre TABLA1 y TABLA2 cumpliendo las condiciones dadas, útil cuando se
quiere obtener una tabla a base de hacer combinaciones de la misma pero modificada.
Secuencias de operaciones de algebra relacional ejemplo:
A = TABLA1(condición)
B = A{atributo1 -> atributoA}
C = TABLA2 * B
R = C[atributo1, atributo2]

Tema 3.2 – Lenguajes: Álgebra relacional


CREATE TABLE <nombre_tabla>
(<nombre_columna> <tipo_dato> [<restricciones_col>] [<val_por_defecto>]
[, <nommbre_columna> <tipo_dato> [<restricciones_col>] [<val_por_defecto>]...]
[<restricciones_tabla>]); Ej: int, string …
INSERT INTO <nombre_tabla> [(<columnas>)]
( VALUES {<valor1> | NULL}, ..., {<valorN> | NULL} ) | <consulta> ;
DELETE FROM <tabla>
WHERE <condiciones>;

UPDATE <tabla>
SET <col> = {expressión/ NULL} [,<col> = {expressión/ NULL}...]
WHERE <condiciones> ;
No repite atributo (Solo poner si se repiten las consultas)
SELECT [DISTINCT | ALL] <columnas_que_seleccionar> [,<funciones_de_agregación>]
FROM <tabla_que_consultar>
[ WHERE <condiciones> ]
ORDER BY <columna> [ DESC | ASC ], … Si tienen el mismo primer
atributo repetido ordena
GROUP BY <columnas_segun_las_que_agrupar>
HAVING <condiciones_para_grupos>; según el criterio seleccionado

2
Bases de Datos

val_por_defecto: DEFAULT {<literal> | NULL}


restricciones_col:
- UNIQUE: la columna no puede tener valores repetidos
- PRIMARY KEY: la columna es la clave primaria de la tabla
- REFERENCES <tabla> [<col>]: columna foreign key que refenrencia a la tabla indicada
- CHECK (<condiciones>): columna que debe cumplir las condiciones especificadas
- NOT NULL: la columna no puede tener valores nulos
restricciones_tabla:
- UNIQUE (<cols>)
- PRIMARY KEY (<cols>)
- FOREIGN KEY (<cols>) REFERENCES <tabla> [<cols>]
- CHECK (<condiciones>): La table debe cumplir las condiciones especificadas, la condición puede
referirse a una o más columnas de la tabla
Operadores:
- aritméticos: *, +, -, / SELECT(*) selecciona todo
- de comparación: =, <, >, <=, >=, <> →(diferente)
- lógicos: NOT, AND, OR
- otros:
• <columna> BETWEEN <límite1> AND <límite2>
• <columna> IN (<valor1>,<valor2> [....,<valorN>])
• <columna> LIKE <característica>
• <columna> IS [NOT] NULL
funciones_de_agregación:
- COUNT(*)
- COUNT(DISTINCT <columna>)
- COUNT(<columna>)
- SUM(expressión)
- MIN(expressión)
- MAX(expressión)
- AVG(expressión)
Sustitutos del WHERE
SELECT e.num_empl, p.num_proj, p.nom_proj
FROM empleats e, projectes p
WHERE e.num_proj = p.num_proj;
SELECT e.num_empl, p.num_proj, p.nom_proj
FROM empleats e INNER JOIN projectes p ON e.num_proj = p.num_proj;
SELECT e.num_empl, p.num_proj, p.nom_proj
FROM empleats e NATURAL INNER JOIN projectes p;
UNION → Tiene como a resultado la unión de dos selecciones diferentes y no repite resultados, no se necesita
poner DISTINCT
Diferencia:
WHERE … NOT IN (selección) → Da el valor del atributo si no está en la selección (subconsulta)
WHERE NOT EXISTS (selección) → Da el valor del atributo si no existe en la selección

Tema 4 – Componentes lógicos de una base de datos


Esquemas: sirven para centralizar tareas administrativas como encender, apagar o otorgar privilegios de un
conjunto de componentes lógicos a un usuario
CREATE SCHEMA [[nombre_catalogo]nombre_esquema] [AUTHORIZATION id_usuario]
[lista_elementos_esquema];
DROP SCHEMA nombre_esquema [RESITRICT | CASCADE]
- RESTRICT: borra un esquema solo si este está completamente vacío.
- CASCADE: borra un esquema, aunque contenga elementos.

3
Bases de Datos

Aserciones: restricciones de integridad que afectan a más de una tabla


CREATE ASSERTION nombre CHECK (condición);
Vistas: es una tabla virtual cuyo contenido está definido por una consulta
CREATE VIEW nombre_vista AS SELECT (nombre_columna, …)
FROM nombre_tabla
WHERE (condicion)
[WITH CHECK OPTION]; → No deja actualizar la vista
Actualizar vista → UPDATE nombre_vista SET … WHERE …;
SELECT * FROM nombre_vista;
Privilegios → Conceden y quitan autorización de hacer según que cosas en una base de datos.
Da permiso para dar y
GRANT privilegios ON objetos TO ususarios [WITH GRANT OPTION]; quitar permisos que ese mismo usuario tiene
REVOKE [GRANT OPTION FOR] privilegios ON objetos FROM usuarios {CASCADE |
RESTRICT} Quita el permiso de dar permiso
- CASCADE: Se revocan todos los privilegios concedidos por ese usuario
- RESTRICT: No se revoca ningún otro privilegio
Privilegios que se pueden dar sobre una vista (para conceder privilegios con SELECT) o una tabla: SELECT,
INSERT, UPDATE, DELETE.
ROLS → Es una agrupación de privilegios definida para un grupo de usuarios específicos.
CREATE ROLE nombre_role -- Crea ROLE
GRANT privilegios ON objetos TO nombre_role -- Asigna privilegios del ROLE
GRANT nombre_role TO usuario -- Dar privilegios a un usuario del ROLE

Tema 7 – Introducción al diseño de bases de datos relacionales


Asociaciones: es la representación de una relación entre dos o más objetos
Asociaciones binarias:
min .. max min .. max 1 Tiene asignado *
A B Departament Empleado
o
Transformación de asociaciones binarias: caso uno a
muchos (0 .. 1 a *) → Añadir la foreign key a la relación
A(atributoa_primary_key, …) Mismo
que corresponde a la clase del extremo “muchos” (*).
B(atributob_primary_key, … , atributo_ref) nombre
Transformación de asociaciones binarias: caso uno a uno donde {atributo_ref} referencia A
(0 .. 1 a 0 .. 1) → Añadir a cualquiera de las dos relacione
una foreign key que referencie a la otra.
A(atributoa_primary_key, …)
Transformación de asociaciones binarias: caso muchos a B(atributob_primary_key, … , atributo_ref)
muchos (* a *) → Se define una nueva relación donde se NUEVA_RELACION(atributoa_primary_key, atributob_primary_key)
referencian las claves primarias de ambas relaciones donde {atributoa_primary_key} referencia A y
{atributob_primary_key} referencia B

Asociaciones ternarias:
min .. max min .. max 0 .. 1 0 .. 1
A B Aula Se hace clase Grupo

min .. max *
C Horario

A(atributoa_primary_key, …)
B(atributob_primary_key, … )

4
Bases de Datos

C(atributoc_primary_key, … )
NUEVA_RELACION(atributoa_primary_key, atributob_primary_key, atributoc_primary_key)
donde {atributoa_primary_key} referencia A,
{atributob_primary_key} referencia B y
{atributoc_primary_key} referencia C
Transformaciones de asociaciones ternarias: muchos-muchos-muchos → La foreign key de la nueva relación
esta formada por las claves de las tres clases.
Transformaciones de asociaciones ternarias: muchos-muchos-uno → La foreign key de la nueva relación está
formada por las claves de las dos clases de los “muchos” (*) de la asociación.
Transformaciones de asociaciones ternarias: muchos-uno-uno → La foreign key de la nueva relación está
formada por la clave de “muchos” y una de las otras dos claves (escoger la que se quiera).
Asociaciones recursivas:
A Persona 0 .. 1 esposa
*
0 .. 1 0 .. 1 Persona Fecha
min .. max min .. max madre Es madre de hijo Se ha casado con
0 .. 1 esposo

Transformaciones de asociaciones recursivas


PERSONA(cod_pers, …)
FECHA(fecha)
CASAMIENTO(cod_esposo, cod_esposa, fecha)
PERSONA(codigo_persona, … , codigo_madre) o
donde {codigo_madre} referencia PERSONA CASAMIENTO(cod_esposo, cod_esposa, fecha)
donde {cod_esposo} referencia PERSONA,
donde {cod_esposa} referencia PERSONA y
donde {fecha} referencia FECHA,
Asociaciones de clases asociativas Transformación de clases asociativas
HORARIO(dia-sem, hora)
AULA(cod_aula, …)
GRUPO(gr, …)
0 .. 1 0 .. 1 PROF(prof, …)
Aula Grupo
CLASE(dia-sem, hora, cod_aula, gr, duracion, prof)
* 1
Clase o
* Imparte Profesor CLASE(dia-sem, hora, cod_aula, gr, duracion, prof)
Horario duración donde {dia_sem, hora} referencia HORARIO,
{cod_aula} referencia AULA,
{gr} referencia GRUPO y
{prof} referencia PROFESOR
Generalización/especificación Transformación de la generalización/especialización
Persona
dni PERSONA(dni, nombre)
nombre EMPLEADO(dni, sueldo)
donde {dni} referencia PERSONA
ESTUDIANTE(dni centro)
donde {dni} referencia PERSONA
Empleado Estudiante
sueldo centro

La multiplicidad (min .. max) de clase dentro de una asociación indica cuántas instancias de esa clase pueden
asociarse con las otras clases de la asociación.
- 0 .. 1 → Sin instancia o sólo una (opcional)
- 1 → Una y siempre una instancia (obligatorio)
- * → Cero o múltiples instancias (opcional)
- 1 .. * → Múltiples instancias, pero al menos una (obligatorio)

5
Bases de Datos

Tema 5 – Procedimientos y Disparadores


-- PROCEDIMIENTO QUE DEVUELVE UNA ÚNICA TUPLA
CREATE FUNCTION nombre_procedimiento(param_entrada tipus)
RETURNS tipo_retorno AS $$
DECLARE
-- Variables que declarar, si no se inicializan por defecto son NULL
nombre_variable [CONSTANT] tipo [NOT NULL] [{DEFAULT | :=} expression];
-- Específica el tipo de variable manualmente
variable_retorno tipo_var;
/* Específica el tipo de variable idéntico al de un determinado atributo de una
tabla */
var tabla.atributo%TYPE;

BEGIN
-- Sentencia de asignación
nombre_variable := (SELECT atr FROM tabla WHERE condicion);

-- Asignamos tuplas de un atributo a una variable


SELECT atributo INTO variable_retorno
FROM tabla
WHERE condicion;

RETURN variable_retorno;
END;
$$LANGUAGE plpgsql;

-- PROCEDIMIENTO QUE DEVUELVE UN CONJUNTO DE TUPLAS


CREATE TYPE conjunto AS (
var1 tipo_var,
var2 tipo_var,
var3 tipo_var);

-- OPCION 1
-- El SETOF devuelve un conjunto de tuplas especificadas en el CREATE TYPE
CREATE FUNCTION nom_proc(param_entrada tipus) RETURNS SETOF conjunto AS $$
...
/* Va devolviendo a cada ejecución los valores de la variable.
El procedimiento acaba cuando se ejecuta un RETURN sin NEXT o llega al final */
RETURN NEXT variable;
...
END;
$$LANGUAGE plpgsql;

-- OPCION 2
CREATE FUNCTION nom_proc(param_entrada tipus) RETURNS conjunto AS $$
DECLARE
conj conjunto;
var tipo_var;

BEGIN
...
conj.var1 := var;
...

RETURN conj;
END;
$$LANGUAGE plpgsql;

-- SENTENCIAS CONDICIONALES
IF (condicion) THEN Bloque de sentencias;
ELSE IF (condicion) THEN Bloque de sentencias;
ELSE THEN Bloque de sentencias;
END IF;

6
Bases de Datos

/* - FOUND es un booleano con valor inicial False, pero cambia a true si


en un SELECT ... INTO ... encuentra una tupla
- UPDATE, INSERT o DELETE, FOUND cambia a true si almenos una fila se ve
afectada por la sentencia
- En una sentencia FOR, FOUND cambia a true al acabar el FOR se ha iterado
alguna vez */
IF FOUND THEN Bloque de sentencias;

-- SENTENCIAS ITERATIVAS
-- Por cada statement ; al final
FOR var IN sentenciaSQL
LOOP statements END LOOP;

WHILE sentenciaSQL LOOP statements END LOOP;

-- GESTIÓN DE ERRORES
CREATE FUNCTION proc() RETURNS tipo_var AS $$
DECLARE
missatge missatgesExcepcions.texte%TYPE;
BEGIN
IF (condicion_error) THEN
SELECT texte INTO missatge FROM missatgesExcepcions WHERE num = 1;
RAISE EXCEPTION '%', missatge;
END IF;

EXCEPTION
WHEN raise_exception THEN RAISE EXCEPTION '%', SQLERRM;
WHEN others THEN -- Gestiona otros errores
SELECT texte INTO missatge FROM missatgesExcepcions WHERE num = 2;
RAISE EXCEPTION '%',missatge;
END;
$$ LANGUAGE plpgsql;

-- DISPARADORES
CREATE FUNCTION nomFunc() RETURNS trigger AS $$
DECLARE
var var_type;
BEGIN
-- Ejemplo de cómo usar NEW (válido para OLD) para consultar el nuevo/viejo atributo
SELECT * INTO var FROM table WHERE atr = NEW.atr1;
...
RETURN {NEW | OLD | NULL};
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER nombre {BEFORE | AFTER} {INSERT | DELETE | UPDATE [OF columna, ...]}
ON tabla [FOR [EACH] {ROW | STATEMENT}]
EXECUTE PROCEDURE nomFunc;
/* FOR EACH ROW -> Se ejecuta para cada tupla de una tabla en una sentencia SQL
FOR EACH STATEMENT -> Se ejecuta 1 vez por cada sentencia SQL */

ROW STATEMENT
RETURN NEW → INSERT, UPDATE → Se ejecuta la
sentencia con el valor modificado
RETURN OLD → DELETE, UPDATE (sin el cambio hecho RETURN NULL → Ignoramos
BEFORE
en la sentencia) el valor devuelto
RETURN NULL → No ejecuta la sentencia que activa el
disparador
RETURN NULL → Ignoramos
AFTER RETURN NULL → Ignoramos el valor devuelto
el valor devuelto

7
Bases de Datos

Tema 8 – Transacciones y concurrencia


El objetivo de los SGBD es permitir un acceso simultáneo de múltiples usuarios a la misma BD preservando su integridad. Para ello se usan transacciones, estas son un conjunto
de operaciones de lectura y/o actualización de la BD que acaban confirmando o cancelando los cambios hechos.
Interferencias entre transacciones: se producen cuando las transacciones no se aíslan adecuadamente entre sí.

Actualización perdida: se Lectura no confirmada: se Lectura no repetible: se produce Análisis inconsistente: cuando a Fantasmas: una transacción lee
produce cuando intentamos produce cuando una transacción si una transacción lee 2 veces el mitad de una ejecución de una un conjunto de datos
escribir/actualizar mediante una lee un dato que se ha modificado mismo dato y obtiene valores transacción, otra transacción relacionado y existe otra
operación, pero esta no se por otra transacción que después diferentes, debido a una cambia el estado de una variable. transacción que añade nuevos
produce. aborta. modificación efectuada por otra datos que pertenecen a ese
transacción. conjunto.
T1 T2 T1 T2 T1 T2 T1 T2 T1 T2
RU(A) RU(A) R(A) R(A) R(IC)
RU(A) W(A) RU(A) RU(B) R(C1)
W(A) RU(A) W(A) W(B) R(C2)
W(A) W(A) R(A) R(B) RU(C3)
COMMIT COMMIT COMMIT RU(A) W(C3)
COMMIT ABORT COMMIT W(A) RU(IC)
COMMIT W(IC)
COMMIT R(IC)
R(C1)
R(C2)
R(C3)
A A A IC
T1 T2 T1 T2 T1 T2 T1 T2 T1 T2
A A A B IC, C3

READ UNCOMMITED READ UNCOMMITED READ UNCOMMITED READ UNCOMMITED READ UNCOMMITED
READ COMMITED READ COMMITED READ COMMITED READ COMMITED READ COMMITED
REPEATABLE READ REPEATABLE READ REPEATABLE READ REPEATABLE READ REPEATABLE READ
SERIALIZABLE SERIALIZABLE SERIALIZABLE SERIALIZABLE SERIALIZABLE

8
Bases de Datos

La teoría de la serializabilidad define las condiciones que se han de cumplir para que las transacciones estén
aisladas entre sí correctamente.
- Gránulos: las transacciones están formadas por acciones (operaciones) sobre datos elementales llamados
gránulos (página (bloque) del disco, un registro (una tupla), etc). Operaciones sobre gránulos:
• R(G): Lectura del gránulo G. (Sentencia SQL: SELECT)
• RU(G): Lectura con intención de modificación posterior del gránulo G. Sentencias SQL:
• W(G): Escritura del gránulo G. INSERT/UPDATE/DELETE
- Horario o historia: dónde se guarda el orden de las acciones dentro de cada transacción.
- Horario serial: cuando las transacciones se ejecutan completamente una detrás de otra sin solaparse.
- Acciones conflictivas o no conmutables: dos acciones serán conflictivas cuando 2 transacciones distintas
operan sobre el mismo gránulo y al menos una de las acciones es de escriptura.
- Grafo de precedencias
- Horario serializable: es un horario serializable aquel que al construir el grafo no tiene ciclos.
Técnicas de control de concurrencia: permite resolver las interferencias entre transacciones de dos maneras:
- Cancelando automáticamente las transacciones problemáticas y deshaciendo sus cambios.
- Suspendiendo la ejecución temporalmente y volviéndola a ejecutar cuando no haya peligro de
interferencia.
Control de concurrencia con reservas: se reserva un gránulo con una cierta modalidad antes de efectuar una
acción.
T1 T2
- LOCK(G, S): permite al gránulo G lecturas (modalidad compartida)
LOCK(A, S)
- LOCK(G, X): permite al gránulo G hacer lecturas y escrituras (modalidad
R(A)
exclusiva: ninguna otra transacción pueda hacer un LOCK del gránulo G
hasta que este no se libere). LOCK(A, X)
- UNLOCK(G): liberamos la reserva sobre el gránulo G. LOCK(B, S) ·
R(B) ·
En ciertos momentos es conveniente baja el nivel de aislamiento y dejar
que se produzcan interferencias: UNLOCK(A) ·
RU(A)
- READ UNCOMMITED: evita que cualquier otra transacción se actualice
W(A)
hasta que acabe la transacción.
- READ COMMITED: impide que otra transacción lea datos que aún no se UNLOCK(B)
han confirmado. UNLOCK(A)
- REPEATABLE READ: hasta que no acabe la transacción, impide que otra COMMIT
transacción un dato ya leído. COMMIT
- SERIALIZABLE: aislamiento total excepto fantasmas.
Recuperación:
- Restauración: garantiza que la base de datos cumplan la atomicidad de las transacciones.
- Reconstrucción: recuperan el estado de la BD cuando se produce un pérdida total o parcial.
• Reconstrucción hacia delante: implica deshacer los cambios de una transacción abortada.
• Reconstrucción hacía atrás: implica rehacer los cambios de una transacción confirmada.

9
Bases de Datos

Tema 9 – Almacenamiento y métodos de acceso


Hay 2 tipos de memoria:
- Memoria externa: es más lenta, pero más barata.
- Memoria interna: más rápida, pero más cara, es volátil y su capacidad es reducida.
Dado que no existe un estándar para los ficheros de las bases de datos, aprenderemos el patrón que siguen. La
arquitectura de una BD tiene tres niveles, que sirven para comprender la relación entre los datos tal y como los
ve el programador o el usuario final y tal y como están almacenadas.
- Nivel físico: los datos se almacenan en discos magnéticos controlados por el SO, que es el que realmente
efectúa las lecturas y escrituras, ahora bien, es la SGBD la que decide cuando hacer estas operaciones y el
que conoce como están físicamente estructurados los datos y como interpretarlos.

Ficheros: es la unidad global a partir de la cual el SO gestiona los datos en los discos magnéticos.
Es un conjunto de extensiones.

Extensión: es la unidad de adquisición de espacio por cada fichero. (es un múltiplo entero de la
página). Es el nombre de páginas consecutivas que el SO adquiere a petición de la SGBD cuando esta
detecta que necesita más espacio para un fichero determinado

Página: es el componente físico más pequeño, contiene y almacena los datos a nivel lógico. Hay 2
formas de ver el concepto de página:
- Unidad discreta de tranporte de datos (E/S) entre la memoria externa (disco) y la memoria
interna. En SO normalmente bloque.
- Unidad de organización de datos almacenados. El espacio de disco se estructura en un
nombre múltiple de páginas, y cada página se puede direccionar individualmente.
La estructura física sigue una longitud fija (2K, 4K, 8K)

Estructura física de una página:


Cabecera Fila 1 Fila 2
Fila 3 Fila 4
Fila 5

Espacio libre

5 4 3 2 1

Vector de direcciones de fila


Estructura física de una fila:
Cabecera Campo 1 Campo 2 Campo 3 …
contiene: la longitud de la fila y el
identificador de la tabla a la que pertenece.
Estructura física de un campo:
Cabecera Contenido (el valor de un int, float, char, etc)

nos dice si es null / not null (si el campo admite valores nulos)
y contiene la longitud del campo.

- Nivel virtual: hace de intermediario entre el nivel físico y el lógico, ya que:


• Si las tablas son muy grandes → Hay fragmentos en distintos dispositivos → Se asocia un fragmento
a un fichero diferente.
• Si las tablas son muy pequeñas → Hay que agruparlas en un fichero.
• Por los objetos grandes, que se almacenan separadamente.
• Por los índices, disparadores, restricciones…

10
Bases de Datos

A nivel virtual también existe un sistema de paginación que se hace de manera paralela a la física.
Correspondencia entre páginas reales y páginas virtuales:
a. Nivel virtual
Núm. página 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
b. Nivel físico

Extensión 1 Extensión 1

Fichero 1 Extensión 2
Fichero 2 Extensión 2

- Nivel lógico
Los métodos de acceso nos permiten la lectura o actualización de una tabla, dado que cuando leemos o
actualizamos un dato accedemos a la paginación virtual y de esta a la física. Los siguientes métodos de acceso:
- Acceso por posición:
• Directo
INSERT INTO x VALUES (a, b, c, d);

1 2 3 4 5 6 7 8 9 10
• Secuencial
SELECT * FROM x

1 2 3 4 5 6 7 8 9 10

- Acceso por valor:


• Directo
▪ SELECT * FROM tabla WHERE atr = x;
▪ DELETE FROM tabla WHERE atr = x;
▪ UPDATE tabla SET atr2 = y WHERE atr1 = x;
• Secuencial
▪ SELECT * FROM tabla ORDER BY atr;
▪ SELECT * FROM tabla WHERE atr > x AND atr < y;
▪ UPDATE tabla SET atr2 = y WHERE atr1 = x;
▪ DELETE FROM table WHERE atr > x AND atr < y;
- Acceso por diversos valores: cuando se acceden a las filas por varios atributos
• SELECT * FROM tabla ORDER BY atr1, atr2
• SELECT * FROM tabla WHERE atr1 = x AND atr2 < y;

Se usan índices para una implementación más eficiente, porque ocupan menos espacio que los datos.
Funcionan de manera similar a los índices de los libros. Y hacen el acceso por valor vía acceso por
posición.
Ínidce (valor, RID)
Datos
fila

Árboles B+: es una de las maneras de estructurar los índices. Un árbol de orden d (d-ario) tiene como mucho 2d
valores y 2d + 1 apuntadores. Ejemplo:

11
Bases de Datos

Acceso directo por valor


14
Nodos internos: dirigen la
𝑥 < 14 14 ≤ 𝑥
búsqueda
6 18 Índices B+
Hojas: contienen todos
𝑥<6 6 ≤ 𝑥 < 14 14 ≤ 𝑥 < 18 18 ≤ 𝑥 los índices (valor, RID)
que llevan a los datos
2 3 6 8 14 18
(filas) correspondientes

Acceso secuencial por valor

Fichero de datos / datos indexados

mejor rendimiento:
- Todos los nodos han de estar llenos como mínimo al 50%, menos la raíz.
- Todas las hojas han de estar al mísmo nivel.
Cada nodo se almacena en una página → Para acceder a una hoja harán falta n niveles.
Ejercicio: quantas filas/registros se podrían indexar en un árbol de orden 𝒅 y lleno al 𝒙 %:
- Nivel 1: 1 nodo con 𝑥 valores y 𝑥 + 1 apuntadores.
- Nivel 2: 𝑥 + 1 nodos con 𝑥 valores y 𝑥 + 1 apuntadores cada uno.
- Nivel 3: (𝑥 + 1)2 nodos con 𝑥 valores y 𝑥 + 1 apuntadores cada uno. (si parasemos → (𝑥 + 1)2 ∗ 𝑥 filas)
- Nivel 4: (𝑥 + 1)3 nodos con 𝑥 entradas → (𝑥 + 1)3 ∗ 𝑥 filas/entradas/registros.
Para saber la altura de un árbol: log 𝑥+1 𝑛º 𝑓𝑖𝑙𝑎𝑠/𝑒𝑛𝑡𝑟𝑎𝑑𝑎𝑠/𝑟𝑒𝑔𝑖𝑠𝑡𝑟𝑜𝑠
Índices agrupados (clústers): es aquel en que los datos que indexa estan ordenados físicamente a partir del
acceso secuencial por valor que proporciona. Esto supone que hay que mantener un orden físico, para ello se
deja un % de espacio libre en las páginas, si se llenan se llenan páginas excedentes encadenadas y en el caso de
haber un % elevado de éstas, se regrupan.
Accesos por diversos valores: accesos directos
- Estrategia de intersección de RIDs: uso de estructuras de árboles B+, para crear conjuntos con las
condiciones y devuelve la intersección de los conjuntos.
- Estrategia de índice multi-atributo: uso de estructura de árboles B+, el resultado lo llamamos lista y
establecemos un orden lineal entre las listas, de esta manera se ordenan según la primera condición, de las
que cumplen la primera condición se ordenan según la segunda…
Accesos por diversos valores: accesos secuenciales y mixtos:
[x, y]
- Estrategia de índice multi-atributo (rango)
- Estrategia de índice multi-atributo multi-dimensional: no sigue un
<< <>= >=< >=>=
orden lineal
Creación de un índice CREATE INDEX nom_indice ON tabla(atr)
Para un índice descendiente CREATE INDEX nom_indice ON tabla(atr DESC)
Índice agrupado CREATE INDEX CLUSTER nom_indice ON tabla(atr)
Índice sin valores repetidos CREATE UNIQUE INDEX nom_indice ON tabla(atr)
Índice multi-atributo CREATE INDEX nom_indice ON tabla(atr1, atr2)

Coste acceso secuencial por valor:


- Índice árbol B+, no agrupado:
Coste = coste acceso índice + coste acceso fichero de datos = (ℎ + 𝐹) + |𝑅(𝑎 ≥ 𝑋)|
- Índice árbol B+, agrupado:
Coste = coste acceso índice + coste acceso fichero de datos = ℎ + 𝐷 = ℎ + [𝑅(𝑎 ≥ 𝑋)/𝑓]
Coste acceso directo por valor:
- Índice árbol B+, agrupado/no agrupado, sin valores repetidos:
Coste = coste acceso índice + coste acceso fichero de datos = ℎ + 1
- Índice árbol B+ no agrupado, con posibilidad valores repetidos:
Coste = coste acceso índice + Coste acceso fichero de datos = (ℎ + 𝐹) + |𝑅(𝑏 = 𝑌)|

12
Bases de Datos

- Índice árbol B+ agrupado, con posibilidad valores repetidos:


Coste = coste acceso índice + coste acceso fichero de datos = ℎ + 𝐷 = ℎ + [𝑅(𝑏 = 𝑌)/𝑓]
- Acceso por diversos valores: estrategia de intersección de RIDs:
Coste = coste acceso índice1 + … + coste acceso índicen coste acceso fichero de datos =
= (ℎ𝑎 + 𝐹𝑎 ) + (ℎ𝑏 + 𝐹𝑏 ) + |𝑅(𝑎 ≥ 𝑋 ⋀ 𝑏 = 𝑌)|
Nota: el coste de acceso a índice puede disminuir en 1 si la raíz está almacenada en memoria.
ℎ = niveles árbol
𝐹 = número de hojas recorridas
𝑅(𝑐𝑜𝑛𝑑𝑖𝑐𝑖ó𝑛) = número de tuplas que cumplen la condición en el fichero de datos
𝐷 = nombre de páginas del fichero de datos que hay que recorrer
𝑓 = número de registros por página

Tema 6 – Programación usando SQL


SQL estático: las sentencias SQL son fijas y las mismas en cualquier ejecución del programa.
- SQLJ: se trata de incrustar sentencias SQL estáticas dentro del programa, por ello hace falta una pre-
compilación, traducir las sentencias SQL en sentencias del lenguaje de programación utilizado, por ello es
poco portable, más difícil de programar pero más eficiente y ocupa menos líneas de código.
SQL dinámico: las sentencias SQL se incrustan durante la ejecución del programa.
- JDBC: es una API que define unos métodos de conexión para la conexión y acceso a datos remotos desde
un programa escrito en Java. Las funciones SQL se compilan durante la ejecución, por lo que lo hace más
portable y más fácil de programar pero menos eficiente y ocupa más líneas de código. Tipos de drivers:
import java.sql.*; // importamos las librerías sql

// Indicamos el driver JDBC que se usará para acceder a la base de datos


Class.forName("nombreDriver");

// Propiedades como el usarname y password al que queremos conectarnos


Properties props = new Properties();
props.setProperty("user", "miUsuario");
props.setProperty("password", "miContraseña");
// Conexión con la base de datos
Connection c = DriverManager.getConnection("url", props);
c.setAutoCommit(false);

// Selección del schema


set schema nombreSchema

/* Comunicación con la base de datos */


//--------------------------------------------------------------------------
// Comunicación usando Statement (se usa cuando ejecutamos el código 1 sola vez)
Statement s = c.createStatement();
// Consultas
nt consulta = s.executeQuery ("Sentencia de consulta SQL");
// Modificaciones
int modificaciones = s.executeUpdate("Sentencia insert/delete/update SQL");
if (modificaciones == 0) System.out.println("Se ha modificado con éxito");
s.close(); // Cerramos la conexión con la base de datos
//--------------------------------------------------------------------------
// Comunicación usando PreparedStatement
// (se usa cuando ejecutamos el código más de 1 vez, como por ejemplo en bucles)
// Consultas
PreparedStatement ps = c.prepareStatement("Sentencia consulta SQL");
ps.executeQuery();
// Modificaciones
PreparedStatement ps = c.prepareStatement("Sentencia insert/delete/update SQL");
int modificaciones = ps.executeUpdate();
if (modificaciones == 0) System.out.println("Se ha modificado con éxito");
ps.close(); // Cerramos la conexión con la base de datos

13
Bases de Datos

// ResultSet

telefono siguiente = r.next(); // siguiente = true


siguiente = r.next(); // siguiente = true
siguiente = r.next(); // siguiente = false

ResultSet r = s.executeQuery("Consulta SQL");


r.next(); // indica si existe otra tupla a la que acceder
// Ejemplo
String telf = r.getString("telefono");
if (telf == null) ...; // Para saber si el valor es nulo
if (telf.wasNull()) ...; // Otra manera para saber si el valor es nulo

// Transacciones
c.commit(); // Guarda permanentemente los cambios hechos
c.rollback(); // Deshace los cambios que no se hayan ya guardado en la BD

/* Excepciones (así es como se crea una clase para programar con SQL) */
public class progrEx1 {
public static void main (String[] args) {
try {
// Enregistrar el driver
// Conexión a la base de datos
// Consultes-modificaciones
// Desconexión
}
catch (ClassNotFoundException ce) {
System.out.println ("Error al cargar el driver d'informix.");
}
catch (SQLException se) {
System.out.println ("Error conexión o acceso a la base de
datos");}
}}

// Gestión de errores
try {
// Ejecutar el Statement o PreparedStatement
} catch (SQLException se) {
if (se.getSQLState().equals("Código")) System.out.println("Error que sea");
else System.out.println(se.getSQLState() + " " + se.getMessage())

14

También podría gustarte