RESTRICCIONES DE INTEGRIDAD
TEORÍA 6
Introducción a las Bases de Datos y
Bases de Datos
Tecnicaturas TUPAR y TUDAI
2019
“Un SGBD debe ayudar a prevenir el ingreso incorrecto de datos”
RESTRICCIONES DE INTEGRIDAD (RI) - CONCEPTO
condiciones que restringen los valores en la BD
descripción de estados correctos en tiempo de diseño
previenen inconsistencias
RI
forzar las RI → garantizar instancias legales de la BD
Ejemplos
CÓMO MANTENER LA INTEGRIDAD EN UNA BD
DBA: especifica las RI sobre los datos
ambas respuestas deben dejar la BD en un estado consistente
SGBD: evita actualizaciones en los datos que no cumplan las RI
Según su naturaleza:
Por los estados involucrados:
CLASIFICACIÓN DE RI
De Estado:
RI DE ESTADO
En SQL: CREATE TABLE NombreTabla
( { nom_col TipoDato [NOT NULL] [DEFAULT valorDefecto], … }
[ [CONSTRAINT PK_nom] PRIMARY KEY (lista_col_PK),]
{ [ [CONSTRAINT nom_restr] UNIQUE (lista_col),] }
... );
o: ALTER TABLE NombreTabla
ADD [CONSTRAINT PK_nom] PRIMARY KEY (lista_col_PK);
ídem UNIQUE
{}: repetición []: opcional
Recomendable!
RESTRICCIONES DE NO-NULIDAD �Y DE UNICIDAD
RESTRICCIONES DE INTEGRIDAD REFERENCIAL (RIRS)
El conjunto de valores de la clave extranjera de una tabla A debe coincidir al menos con un valor de la clave primaria de la tabla B, a la que hace referencia, o bien ser nulo
En SQL: CREATE TABLE NombreTabla
( { nombre_columna TipoDato [NOT NULL] … }
[ [CONSTRAINT PK_nom] PRIMARY KEY (lista_columnasPK),]
{ [ [CONSTRAINT U_nom] UNIQUE (lista_columnas),] }
{ [ [CONSTRAINT FK_nom] FOREIGN KEY (lista_columnasFK)
REFERENCES nombreTablaRef [(lista_columnasRef)]
[ MATCH {FULL | PARTIAL | SIMPLE}]
[ON UPDATE AccionRef]
[ON DELETE AccionRef] ] } ….. );
o: ALTER TABLE NombreTabla
ADD CONSTRAINT FK_nom FOREIGN KEY (lista_columnasFK) …;
AccionRef = NO ACTION | CASCADE | SET NULL | SET DEFAULT | RESTRICT
RESTRICCIONES DE INTEGRIDAD REFERENCIAL (RIRS)
Qué sucede si se intenta borrar (delete) un registro en la Tabla_B que está siendo referenciada en la Tabla_A por la FK?
→ Opciones 1 - Rechazo de la operación
→ Opciones 2 - Acepta la operación y realiza acciones reparadoras adicionales
RIRS – ACCIONES REFERENCIALES
RIRS – ACCIONES REFERENCIALES
Qué sucede si se intenta modificar (update) la clave primaria de un registro en la Tabla_B que está siendo referenciada en Tabla_A por la FK?
→ Rechazar la operación
→ Aceptar la operación y realizar acciones reparadoras adicionales
Cómo proceden las sig. operaciones considerando las diferentes acciones referenc.?�(considerar la instancia dada para las tablas y result. individuales, no acumulativos)
EMPLEADO | |||
IdE | Nombre | … | AreaT |
1 | E1 | … | 101 |
2 | E2 | … | 101 |
AREA | |
IdArea | … |
101 | … |
102 | … |
AREA
(0,N) (0,1)
EMPLEADO
R
Desarrollo en clase
CREATE TABLE Empleado (…);
CREATE TABLE Area (…);
ALTER TABLE Empleado
ADD CONSTRAINT FK_R
FOREIGN KEY (AreaT) REFERENCES Area
ON UPDATE ….
ON DELETE ….;
Ejemplo
EMPLEADO(idE,nombre,..,AreaT) AREA(idArea, … )
RIRS – ACCIONES REFERENCIALES
RIRS – TIPOS DE MATCHING
La integridad referencial se satisface si para cada tupla en la tabla referenciante se verifica lo siguiente:
Ninguna de las columnas de la FK es NULL y existe una tupla en la tabla referenciada cuyos valores de clave coinciden con los de tales columnas, o
RIRS – TIPOS DE MATCHING
Analizar la posibilidad de alta de las sig. tuplas en T-EMPLEADO según los distintos tipos de matching (suponiendo que la FK admita nulos)
TipoA IdArea …
A 1 …
B 1 …
B 2 …
AREA
IdEmp TipoA IdArea
1 … A 1
2 … A 2
3 … null null
4 … null 1
5 … C null
EMPLEADO
Simple Parcial Full
ok ok ok
X X X
ok ok ok
ok ok X
ok X X
MATCHING
Ejemplo
Desarrollo en clase
RIRS – TIPOS DE MATCHING
→ RI Dominio (DOMAIN)
→ RI de tabla asociada a uno ó más atributos (CHECK de registro)
→ RI de tabla asociada a varias tuplas (CHECK de tabla)
→ RI generales de la base de datos (ASSERTION)
OTRAS RESTRICCIONES DE INTEGRIDAD EN SQL
DISPARADORES (TRIGGERS)
→ Es una pieza de código almacenada en la BD que “se dispara” � automáticamente ante la ocurrencia de algún evento
PROCEDIMIENTOS
FUNCIONES
OTRAS RESTRICCIONES DE INTEGRIDAD EN SQL
RI DE DOMINIO /ATRIBUTO
CREATE DOMAIN NomDominio
AS TipoDato [ DEFAULT ValorDefecto ]
[ [CONSTRAINT NomRestriccion] CHECK (condición);
La condición debe evaluar como VERDADERA o DESCONOCIDA
RI DE DOMINIO /ATRIBUTO
Pueden plantearse distinto tipo de condiciones:
% (para 0 o más caracteres) Ej: LIKE ‘s%’ - (para un carácter simple) Ej: LIKE ‘s_’
El sueldo de un empleado es un valor no nulo, mayor a 0 e inferior a 50000, �y con 2 decimales
EMPLEADO(idE,.., sueldo)
CREATE DOMAIN SueldoValido
AS Numeric (7,2) NOT NULL
CHECK (value BETWEEN 0 AND 50000);
o CREATE TABLE Empleado
( …. ,
sueldo Numeric (7,2) NOT NULL
CHECK (sueldo BETWEEN 0 AND 50000),
o
sueldo SueldoValido,,
…. );
CREATE TABLE Empleado
( …. ,
sueldo SueldoValido, ... );
RI DE DOMINIO /ATRIBUTO
Ejemplo
RI (CHECK) DE REGISTRO
En SQL: CREATE TABLE NombreTabla
( …..
{ [[CONSTRAINT nom_restr] CHECK (condición) ] } );
�
o: ALTER TABLE NombreTabla
ADD [CONSTRAINT nom_restr] CHECK (condición) ;
La condición debe evaluar como VERDADERA o DESCONOCIDA
RI (CHECK) DE TUPLA
Un empleado o bien no ha ascendido o, si ha ascendido, la fecha de ascenso no puede ser anterior a la fecha de ingreso
EMPLEADO(idE,.., FechaAscenso, FechaIngreso)
ALTER TABLE Empleado
ADD CONSTRAINT Ascenso
CHECK ( (FechaAscenso IS NULL)
OR (FechaIngreso < FechaAscenso ));
Ejemplo
RI (CHECK) DE TABLA
No puede haber más de 30 empleados por area
ALTER TABLE Empleado
ADD CONSTRAINT area_max
CHECK ( NOT EXISTS (SELECT 1 FROM Empleado
GROUP BY TipoA, IdArea
HAVING count(*) > 30));
Ejemplo
23
RI GLOBALES (ASSERTIONS)
CREATE ASSERTION NomAssertion CHECK (condición);
→ los DBMS comerciales no soportan ASSERTIONS !
La condición debe evaluar como VERDADERA o DESCONOCIDA
RI GLOBALES (ASSERTIONS)
El sueldo de los empleados de un área no puede ser mayor al sueldo del gerente de esa área
EMPLEADO (idE,.., sueldo, AreaT) AREA (IdArea, …., gerente)
CREATE ASSERTION salario_valido
CHECK ( NOT EXISTS ( SELECT 1 FROM Empleado E, Empleado G, Area A
WHERE E.sueldo > G.sueldo
AND E.AreaT = A.IdArea
AND G.IdE = A.gerente ) );
Ejemplo
SQL no proporciona un mecanismo para expresar la condición «para todo X, P(X)» �(P=predicado) → se debe utilizar su equivalente «no existe X tal que no P(X)»
necesidad de una herramienta útil para escribir aserciones, restricciones complejas, acciones específicas de reparación, etc.
→ Triggers (disparadores)
25
UNA ALTERNATIVA PARA ESPECIFICAR RESTRICCIONES
cuando ocurre el Evento (sentencia o situación que dispara su ejecución)
… se evalúa la Condición (expresión booleana que debe evaluar en VERDADERO para que el trigger se active. Si evalúa en FALSO o DESCONOCIDO no se ejecuta. Solo para Triggers a nivel fila)
… y si se satisface se ejecuta la Acción (procedimiento que contiene �las sentencias SQL a ser ejecutadas)
RI MEDIANTE TRIGGERS
TRIGGERS – SINTAXIS PostgreSQL
CREATE [ CONSTRAINT ] TRIGGER nombre_del_trigger
{ BEFORE | AFTER | INSTEAD OF } ← tiempo de activación
{ INSERT [ OR ] UPDATE [ OF nombre_columna [, ... ] ] ← EVENTO� [ OR ] DELETE [ OR ] TRUNCATE }� ON nombre_tabla_o_vista� [ FOR [ EACH ] { ROW | STATEMENT } ] ← granularidad� [ WHEN ( condición ) ] ← CONDICIÓN� EXECUTE PROCEDURE nombre_función; ← ACCIÓN
EVENTO: puede ser una operación de actualización sobre la tabla o vista a la que está asociado el trigger:
TIEMPO DE ACTIVACIÓN: en relación a la sentencia que lo activa, el trigger puede ejecutarse:
TRIGGERS – ACTIVACIÓN Y EVENTOS
Los triggers pueden ser:
(Por defecto → FOR EACH STATEMENT)
TRIGGERS – GRANULARIDAD
La sentencia INSERT manipula una nueva fila (si el trigger es FOR EACH ROW) o un nuevo conjunto de filas (si es FOR EACH STATEMENT)
DELETE manipula una fila vieja (para triggers a nivel fila) o un conjunto de filas o tabla vieja (para triggers de sentencia)
UPDATE manipula estados viejos y nuevos, tanto de filas como de conjuntos de filas, según corresponda
Corresponde referirse a estos elementos como NEW. y OLD. dentro del cuerpo de la función trigger
TRIGGERS – REFERENCIAS
TRIGGERS – ACCIÓN
→ esto podría dar lugar a una cadena “infinita” de activaciones!
UPDATE_T1 Trigger
BEFORE UPDATE ON T1
FOR EACH ROW
INSERT INTO T2 VALUES (...);
INSERT_T2 Trigger
BEFORE INSERT ON T2
FOR EACH ROW
INSERT INTO ... VALUES (...);
TRIGGERS – COMPORTAMIENTO
SQL statement
UPDATE T1 SET …;
Los DBMS suelen limitar la longitud de las cadenas de disparadores
Los triggers se pueden usar para:
TRIGGERS – UTILIDAD
create trigger <nombre>
before <operación crítica sobre la BD>
when <condición por la que una RI es incumplida>
< acción(es) del trigger > →rechazo (acción pasiva) /reparación (acción activa)
Verificar que el sueldo de un empleado no se reduzca
CREATE TRIGGER sueldo_no_se_reduce
BEFORE UPDATE OF sueldo ON Empleado
FOR EACH ROW
WHEN (:old.sueldo > :new.sueldo)
EXECUTE PROCEDURE funcion_error();
TRIGGERS – EJEMPLOS
Ejemplo
TRIGGERS – EJEMPLOS
Mantener automáticamente la cantidad total de empleados del Area � (ante altas, bajas o modificaciones en Empleado)
EMPLEADO(idE,nombre,..,AreaT) AREA(idArea, … CantEmp)
CREATE TRIGGER Incrementar_EmpArea
AFTER INSERT OR UPDATE OF AreaT OR DELETE
ON Empleado
FOR EACH ROW
EXECUTE PROCEDURE cant_total_empleados();
Ejemplo
TRIGGERS – EJEMPLOS
CREATE FUNCTION cant_total_empleados ( )
RETURNS trigger AS $body$
BEGIN
IF TG_OP = 'INSERT' THEN
UPDATE area set CantEmp = CantEmp + 1 where IdArea = new.AreaT;
RETURN NEW;
END IF;
IF TG_OP = 'UPDATE' THEN
UPDATE area set CantEmp = CantEmp - 1 where IdArea = old.AreaT;
UPDATE area set CantEmp = CantEmp + 1 where IdArea = new.AreaT;
RETURN NEW;
END IF;
IF TG_OP = 'DELETE' THEN
UPDATE area set CantEmp = CantEmp - 1 where IdArea = old.AreaT;
RETURN OLD;
END IF;
END; $body$
LANGUAGE 'plpgsql'
Ejemplo
TRIGGERS vs. RI DECLARATIVAS
1. Ejecuta todos los triggers �BEFORE-statement
2. Realiza un ciclo por todas las filas �afectadas por la sentencia SQL
a. Ejecuta todos los triggers �BEFORE-row
b. Bloquea y actualiza cada fila y ejecuta �los chequeos de integridad declarat.�(El bloqueo no se levanta hasta el final de la transacción)
c. Ejecuta todos los triggers AFTER-row
3. Completa las acciones correspondientes a �la verificación diferida de integridad �expresada declarativamente
4. Ejecuta todos los triggers AFTER-statement
De: “Semantic Integrity Support in SQL-99 and Commercial (Object-) Relational Database Management Systems” (Türker y Gertz)
MODELO DE EJECUCIÓN SQL-99 �(+ TRIGGERS)
BIBLIOGRAFÍA
Capitulo 36 del Manual de POstgreSQL . www.postgresql.org
Date, C., “An Introduction to Database Systems”. 7º ed., Addison Wesley, 2000
Elmasri, R., Navathe, S., “Fundamentals of Database Systems”, Addison Wesley, 2011
Silberschatz, A., Korth, H, Sudarshan, S., “Database System Concepts”, McGraw Hill, 2001
Sumathi S., Esakkirajan S., Fundamentals of Relational Database Management Systems, 2007