You are on page 1of 7

Tema 5. Restricciones de integridad.

Tema 5.Restricciones de integridad.


Las restricciones de integridad proporcionan una medio de asegurar que los cambios que se hacen en la BD por
usuarios autorizados no resultan en una perdida de consistencia de los datos. Así pues, las restricciones de integridad
protegen la BD contra daños accidentales.
Ya hemos visto una forma de restricción de integridad para el modelo E-R en el capitulo 2. Estas restricciones
estaban en forma de:
n Declaraciones de clave. La estipulación de que ciertos atributos forman una clave candidata para un conjunto
de entidades dado. El conjunto de inserciones y actualizaciones permitidas están limitadas a aquellas que no
crean dos entidades con el mismo valor en una clave candidata.
n Forma de una relación. Muchos a muchos, uno a muchos, uno a uno. Una relación uno a uno o uno a
muchos restringe el conjunto de relaciones permitidas entre entidades de una colección de conjuntos de
entidades.
En general, una restricción de integridad puede ser un predicado arbitrario perteneciente a la BD. Sin embargo,
los predicados arbitrarios pueden ser costosos de probar, así, normalmente los limitamos a restricciones de integridad
que pueden probarse con un mínimo tiempo extra.

5.1. Restricciones de dominio.


Hemos visto anteriormente que un dominio de valores posible puede estar asociado con cada atributo. Los
límites de dominios son la forma más elemental de restricciones de integridad. Son fáciles de probar por el sistema
siempre que se introduce un nuevo dato en la BD.

5.1.1. Tipos de dominios.

Es posible que varios atributos tengan el mismo dominio, como ocurre con nombre_cliente y
nombre_empleado, que tienen como dominio el conjunto de todos los nombres de personas. Sin embargo los
dominios de saldo y nombre_sucursal deben ser distintos.
El principio que hay detrás de los dominios de atributo es similar al que hay detrás de la asignación de tipos a
variables en los lenguajes de programación.

5.1.2. Tipos de dominios en SQL.

El SQL estándar soporta un conjunto restringido de tipos de dominios:


n Cadena de caracteres de longitud fija, con longitud especificada por el usuario.
n Número en coma fija, con precisión especificada por el usuario.
n Entero, que es dependiente de la máquina.
n Entero pequeño, también es dependiente de la máquina.
n Números en coma flotante y en coma flotante de doble de precisión dependiente de la máquina.
Varias implementaciones de SQL incluyen un tipo fecha.
A menudo resulta útil poder comparar valores de dominios compatibles. Por ejemplo, puesto que todos los
enteros pequeños son enteros, una comparación x < y, con x entero pequeño e y entero, tiene sentido. Una comparación
de este tipo se hace convirtiendo el entero pequeño en entero. Una transformación de este tipo se llama coacción de
tipo. La coacción de tipo se usa de forma rutinaria en los lenguajes comunes de programación, así como en los DBMS.
Así, vemos que en el SQL estándar, nombre_sucursal y nombre_cliente tendrían el dominio de cadena de
caracteres. Aunque las longitudes de las cadenas podrían ser diferentes, SQL consideraría los dos dominios compatibles.

5.1.3. Valores nulos.

Vimos que la inserción de tuplas incompletas pueden introducir valores vacíos en la BD. Para determinados
atributos, los valores nulos pueden ser inapropiados.
Considérese una tupla en la relación cliente en la que nombre_cliente es un valor vacío. En casos como éste,
deseamos prohibir los valores nulos, restringiendo el dominio de nombre_cliente para que excluya los valores nulos.
El SQL estándar permite que la declaración del dominio de un atributo incluya la especificación not null. Esto
prohibe la inserción de un valor nulo para este atributo. Cualquier modificación de la BD que causara que se insertase un
valor nulo en un dominio not null genera un diagnóstico de error.
Hay muchas situaciones en las que la prohibición de valores nulos es deseable. Un caso particular en el que es
esencial prohibir los valores nulos es en la clave primaria de un esquema de relación.

5.2. Integridad referencial.


A menudo queremos asegurar que un valor que aparece en una relación para un conjunto de atributos dado
también aparece para un cierto conjunto de atributos en otra relación. Esto se llama integridad referencial.

5.2.1. Conceptos básicos.

43
Bases de Datos

Considérese un par de relaciones r(R ) y s(S) y el producto natural r|x|s. Puede darse el caso de que haya una
tupla t en r que no se corresponda con ninguna tupla en s. Es decir, no hay ninguna t en s tal que tr[R∩S]=ts[R∩S].
Dichas tupla se llaman tuplas colgadas.
Supóngase que hay una tupla t en depósito con t1[nombre_sucursal = “Lunartown”], pero no hay no hay
ninguna tupla en la relación sucursal para Lunartown. Esta sería una situación no deseable. Esperamos que la relación
sucursal liste todas las sucursales, por tanto, t haría referencia a una cuenta de una sucursal que no existe. Esta claro que
queremos tener una restricción de integridad que prohiba tuplas colgadas de este tipo.
Sin embargo, no todas las instancias de tuplas colgadas son no deseables. Supóngase que hay una tupla t en la
relación sucursal con t2[nombre_sucursal = “Mokan”], pero no hay ninguna tupla en depósito para Mokan. En este
caso existe una sucursal que no tiene cuentas, y aunque no es deseable es posible esta situación.
Para ver la diferencia entre estos dos ejemplos, recordamos que nombre_sucursal es la clave primaria de
esquema_sucursal. Puesto que nombre_sucursal aparece en esquema_depósito, las tuplas depósito hacen referencia a la
clave primaria de sucursal. decimos que el atributo nombre_sucursal en esquema_depósito es una clave exterior, ya que
nombre_sucursal es la clave primaria de una planificación de relaciones distinta de esquema_depósito. Sin embargo, el
atributo nombre_sucursal en esquema_sucursal no es una clave exterior ya que nombre_sucursal no es la clave de
ningún otro esquema de relaciones.
Así, la distinción entre estos dos ejemplos de tuplas colgadas es la presencia de una clave exterior.
Sean r1(R1) y r2(R2) relaciones con claves primarias K 1 y K 2 respectivamente. Decimos que un subconjunto α de
R2 es una clave exterior con referencia K 1 en la relación r1 si es necesario que para cada t2 en r2 haya una tupla t1 en r1 tal
que t1[K 1] = t2[α].El último término surge del hecho de que la restricción de integridad anterior puede escribirse como
∏α(r2)⊆∏k1(r1). Nótese que para que una restricción de integridad referencial tenga sentido, o bien α = K1, o α y K1
deben ser conjuntos de atributos compatibles.

5.2.2. Integridad referencial en el modelo E-R.

Las restricciones de integridad referencial se presentan frecuentemente. Si obtenemos el esquema de BD


relacional construyendo tablas desde diagramas E-R, entonces todas las relaciones que surgen de un conjunto de
relaciones tienen restricciones de integridad referencial. Por ejemplo, un conjunto de relaciones n-ario R, referente a los
conjuntos de entidades E 1, E 2, …, E n. K i representa la clave primaria de E i. Los atributos del esquema de relaciones para
el conjunto de relaciones R incluyen K 1 ∪ K2 ∪ … ∪ Kn. Cada K i del esquema de R es una clave exterior que conduce a
una restricción de integridad referencial.

Otra fuente de restricciones de integridad referencial son los conjuntos de entidades débiles. Recuerdese que el
esquema de relaciones para un conjunto de entidades débil debe incluir la clave primaria del conjunto de entidades del
cual depende. Así pues, el esquema de relaciones para cada conjunto de entidades débil uncluye una clave exterior que
conduce a una restricción de integridad referencial.

5.2.3. Modificación de la base de datos.

Las modificaciones de la BD pueden causar violaciones de la integridad referencial. A continuación listamos la


prueba que debe hacerse para cada tipo de modificación de la BD para proteger la restricción de integridad referencial
siguiente:
∏α(r2) ⊆ ∏k(r1)

n Insertar. Si una tupla t2 se inserta en r2, el sistema debe asegurar que existe una tupla t1 en r1, tal que t1[K] =
t2[α]. Es decir:
t2[α]∈∏k(r1)
n Eliminar. Si una tupla t1 se elimina en r1, el sistema debe calcular el conjunto de tuplas en r2 que hacen
referencia a t1:
σα=t1[K](r2)
Si este conjunto no está vacío, o la orden de eliminar se rechaza como un error, se deben eliminar las tuplas
que hacen referencia a t1. La última solución puede llevar a eliminaciones en forma de cascada, ya que las
tuplas pueden hacer referencia a t1, y así respectivamente.
n Actualizar. Debemos considerar dos casos para actualizar: actualizaciones a la relación que hace referencia (r2)
y actualizaciones a la relación referenciada (r1).

44
Tema 5. Restricciones de integridad.

Si se actualiza una tupla t2 en la relación r2 y la actualización modifica valores para la clave exterior α,
entonces se hace una prueba similar a la del caso de insertar.t’2 representa el nuevo valor de la tupla t2. El
sistema debe asegurar que:
t’2[α]∈∏k(r1)
Si se actualiza una tupla t1 en r1 y la actualización modifica valores para la clave primaria (K), entonces se
hace una prueba similar a la del caso de eliminar. El sistema debe calcular:
σα=t1[K](r2)
usando el valor antiguo de t1 (se aplica el valor de antes de la actualización). Si el conjunto no está vacío, la
actualización se rechaza como un error.

5.2.4. Integridad referencial en SQL.

El SQL estándar original no incluía sentencias para especificar claves exteriores. Una característica de
intensificación de la integridad ha sido aprobada como un añadido al estándar. Esta característica permite la especificación
de claves primarias y candidatas y de claves exteriores como parte de la sentencia create table:
n La cláusula primary key de la sentencia create table incluye una lista de los atributos que comprenden la
clave primaria.
n La cláusula unique key incluye una lista de los atributos que comprenden una clave candidata.
n La cláusula foreign key incluye una lista de los atributos que comprenden la clave exterior y el nombre de la
relación a la que hace referencia la clave exterior.
create table depósito
(nombre_sucursal char (15) not null,
número_cuenta char (10)
nombre_cliente char (20) not null
saldo integer,
primary key (número_cuenta, nombre_cliente),
foreign key (nombre_sucursal) references sucursal
foreign key (nombre_cliente) references cliente) )
Cualquier atributo que sea miembro de una clave candidata debe ser not null. Así pues, en la definición de
depósito necesitamos especificar número_cuenta y nombre_cliente como not null. Esta permitido tener valores vacíos
en una clave exterior a menos que dicha clave exterior sea miembro de una clave candidata.

5.3. Dependencias funcionales.


Esta sección se centra en un tipo particular de restricción llamado dependencia funcional. La noción de
dependencia funcional es una generalización de la noción de clave.

5.3.1. Conceptos básicos.

Las dependencias funcionales son una restricción al conjunto de relaciones legales. Nos permiten expresar
hechos acerca de la empresa que estamos modelando con la BD.
Anteriormente definimos la noción de superclave como sigue: sea R un esquema de relaciones, un
subconjunto K de R es una superclave de R si, en cualquier relación legal r(R ), para todos los pares t1 y t2 de tuplas en r
tales que t1 ≠ t2, t1[K] ≠ t2[K]. Es decir, dos tuplas en cualquier relación legal r(R ) no pueden tener el mismo valor en el
conjunto de atributos K.
La noción de dependencia funcional generaliza la noción de superclave. Sea α⊆R y β⊆R. La dependencia
funcional α→β
se cumple en R si en cualquier relación legal r(R ), para todos los pares de tuplas t1 y t2 en r tales que t1[α] = t2[α],
también se cumple que t1[β] = t2[β]
Utilizando la notación de la dependencia funcional, decimos que K es una superclave de R si Kà R. Es decir,
K es una superclave si siempre que t1[K] = t2[K], también se cumple que t1[R] = t2[R], es decir, t1 = t2.
Las dependencias funcionales nos permiten expresar restricciones que no pueden expresarse por medio de
superclaves. Considérese el esquema:
Esquema_préstamo = ( nombre_sucursal, número_préstamo, nombre_cliente, cantidad)
Si un préstamo dado puede hacerse a más de un cliente, entonces no esperaríamos que el atributo
número_prestamo fuenra una superclave. Sin embargo, esperamos que la dependencia funcional
número_prestamo à cantidad
se cumpla, puesto que sabemos que cada número de préstamo está asociado precisamente a una cantidad.
Usaremos las dependencias funcionales de dos formas:
n Para especificar restricciones en el conjunto de relaciones legales. Así pues, nos interesaremos sólo por las
relaciones que satisfagan un conjunto dado de dependencias funcionales. Si queremos limitarnos a las
relaciones de esquema R que satisfacen F, decimos que F se cumple e R.
n Para probar si una relación es legal bajo un conjunto dado de dependencias funcionales. Si una relación r es
legal bajo un conjunto F de dependencias funcionales, decimos que r satisface a F.

45
Bases de Datos

Consideremos la siguiente relación:


A B C D
a1 b1 c1 d1
a1 b2 c1 d2
a2 b2 c2 d2
a2 b3 c2 d3
a3 b3 c2 d4
Obsérvese que A à C se satisface. Hay dos tuplas que tienen el valor a1 en A, y que tienen el mismo valor c1 en
C, de la misma forma que ocurre con los valores a2 y c2. No existen otros pares de tuplas distintos que tengan el mismo
valor en A. sin embargo no se satisface la dependencia funcional C à A.
La relación r satisface muchas otras dependencias funcionales, incluyendo, por ejemplo, la dependencia
funcional AB à D, usando AB como abreviatura de {A, B}. Obsérvese que no hay ningún par de tuplas distintas t1 y t2
tales que t1[AB] = t2[AB]. Por tanto, si t1[AB] = t2[AB] debe cumplirse que t1 = t2 y, así, t1[D] = t2[D]. De este modo, r
satisface AB à D.
Se dice que algunas dependencias funcionales son triviales porque se satisfacen por todas las relaciones. Por
ejemplo, todas las relaciones que incluyen el atributo A satisfacen A à A, y de manera similar, todas las relaciones que
incluyen el atributo A satisfacen AB à A. En general, una dependencia funcional de la forma α→β es trivial si β ⊆ α.
Para distinguir entre los conceptos de una relación que satisface una dependencia y una dependencia que se
cumple en un esquema volvemos al ejemplo bancario.
Consideremos la relación cliente. Vemos que se satisface calle à ciudad_cliente, pero es posible que dos
ciudades tengan calles con el mismo nombre. Así pues, es posible tener una instancia de la relación cliente en la que no se
satisfaga calle à ciudad_cliente. Por tanto, no incluiríamos calle à ciudad_cliente en el conjunto de dependencias
funcionales que se cumplen en esquema_cliente.
En la relación préstamo vemos que se satisface número_préstamo à cantidad, ya que cada préstamo debe
tener una única cantidad. Por tanto, queremos exigir que la relación préstamo satisfaga número_préstamoàcantidad en
todo momento. En otras palabras, imponemos la restricción de que se cumpla número_préstamo à cantidad en
esquema_préstamo.
En lo que sigue suponemos que al diseñar una BD relacional primero listamos aquellas dependencias
funcionales que se deben cumplir siempre. En el ejemplo bancario la lista de dependencias incluye:
Esquema_sucursal: nombre_sucursal à ciudad_sucursal
nombre_sucursal à activo
Esquema_cliente: nombre_cliente à ciudad_cliente
nombre_cliente à calle
Esquema préstamo: número_préstamo à cantidad
número_préstamo à nombre_sucursal
Esquema_depósito: número_cuenta à saldo
número_cuenta à nombre_sucursal

5.3.2. Cierre de un conjunto de dependencias funcionales.

No es suficiente considerar un conjunto dado de dependencias funcionales. Ademas necesitamos considerar


todas las dependencias funcionales que se cumplen. Veremos que, dado un conjunto F de dependencias funcionales,
podemos probar que se cumplen otras ciertas dependencias funcionales. Se dice que F implica lógicamente dichas
dependencias funcionales.
Supóngase que nos dan un esquema de relaciones R = (A, B, C, G, H, I) y el conjunto de dependencias
funcionales:
AàB AàC CG à H CG à I BàH
La dependencia funcional A à H se implica lógicamente. Es decir, podemos demostrar que siempre que se
cumpla el conjunto dado de dependencias funcionales, A à H también debe cumplirse. Supóngase que t1 y t2 son
tuplas tales que t1[A] = t2[A]. Puesto que nos dan que A à B, se deduce de la definición de dependencia funcional que
t1[B] = t2[B]. Entonces, puesto que nos dan B à H se deduce que t1[H] = t2[H]. Por tanto, hemos demostrado que
siempre que t1 y t2 son tuplas tales que t1[A] = t2[A], también se cumple que t1[H] = t2[H]. Pero ésta es exactamente la
definición de A à H.
Sea F un conjunto de dependencias funcionales. El cierre de F es el conjunto de dependencias funcionales que
F implica lógicamente. Indicamos el cierre de F por F+. Dado F podemos calcular F+ directamente de la definición formal
de dependencia funcional, pero si F es grande este proceso sería largo y difícil, por lo que existen técnicas más sencillas
para deducir dependencias funcionales.
La primera técnica se basa en tres axiomas o reglas de inferencia para dependencias funcionales. Aplicando estas
reglas repetidamente, podemos encontrar F+ completo dado F.. Adoptaremos el convenio de usar letras griegas para
conjuntos de atributos y letras latinas mayúsculas para atributos individuales, así mismo utilizamos αβ para representar
α ∪ β.
n Regla de reflexividad. Si α es un conjunto de atributos y β ⊆ α, entonces se cumple α → β.
n Regla de aumento. Si se cumple α → β y γ es un conjunto de atributos, entonces se cumple γα → γβ.

46
Tema 5. Restricciones de integridad.

n Regla de transitividad. Si se cumple α → β, y se cumple β → γ, entonces se cumple α → γ.


Estas reglas son seguras porque no generan dependencias funcionales incorrectas, y son completas porque
para un conjunto F de dependencias funcionales, nos permiten generar F+ por completo. Esta colección de reglas se
llama axiomas de Armstrong en honor de la persona que los propuso.
Aunque los axiomas de Armstrong son completos, resulta pesado usarlos directamente para el cálculo de F+,
por lo que existen unas reglas adicionales para facilitar esta tarea:
n Regla de unión. Si se cumplen α → β y α → γ, entonces se cumple α → βγ.
n Regla de descomposición. Si se cumple α → βγ, entonces se cumplen α → β y α → γ.
n Regla de pseudotransitividad. Si se cumplen α → β y γβ → δ, entonces se cumple αγ → δ.
Apliquemos estas reglas al ejemplo anterior del esquema R=(A, B, C, G, H, I) y el conjunto F de dependencias
funcionales {AàB, AàC, CGàH, CGàI, BàH}. Algunos miembros de F+ son:
AàH. Puesto que se cumplen AàB y BàH, aplicamos la regla de la transitividad, cumpliéndose AàH.
CGàHI. Puesto que se cumplen CGàH y CGàI, la regla de unión implica CGàHI.
AGàI. Necesitamos varios pasos para demostrarla. Primero, como se cumple AàC, con la regla de aumento
vemos que AGàCG, y como tenemos CGàI, por la regla de la transitividad AGàI.

5.3.3. Cierre de conjuntos de atributos.

Para comprobar que un conjunto α es una superclave debemos idear un algoritmo para calcular el conjunto de
atributos determinados funcionalmente por α. Veremos que un algoritmo de este tipo, también es útil como parte del
cálculo del cierre de un conjunto F de dependencias funcionales.
Sea α un conjunto de atributos. Al conjunto de todos los atributos determinados funcionalmente por α bajo
un conjunto F de dependencias funcionales se le llama cierre de α bajo F y re representa por α+.
Ahora mostramos un algoritmo para calcular α+. La entrada es un conjunto F de dependencias funcionales y el
conjunto α de atributos. La salida se almacena en la variable resultado.
resultado:= α;
while (cambios en resultado) do
for each dependencia funcional β → γ in F do
begin
if β ⊆ resultado then resultado:= resultado ∪ γ;
end
Usemos el algoritmo para calcular (AG)+ con las dependencias funcionales definidas anteriormente.
Empezamos con resultado = AG. La primera vez que ejecutamos el bucle while para probar cada dependencia funcional
encontramos que:
AàB nos hace incluier B en el resultado, ya que AàB esta en F, A⊆resultado (que es aG), por tanto
resultado:=resultado∪B.
AàC hace que el resultado se convierta en ABCG.
CGàH hace que el resultado sea ABCGH.
CGàI hace que el resultado se convierta en ABCGHI.
La segunda vez que ejecutamos el bucle while, no se añaden atributos a resultado y el algoritmo termina.
La regla de unión implica que α à resultado ∪ γ, así α determina funcionalmente cualquier resultado nuevo
generado por el bucle while. Por tanto, cualquier atributo devuelto por el algoritmo está en α+.
Es fácil ver que el algoritmo encunetra α+ completo. Si hay algún atributo en α+ que no esté todavía en
resultado, entonces debe haber una dependencia funcional β → γ para la cual β ⊆ resultado y al menos un atributo de F
no está en resultado.
Resulta ser que en el peor de los casos este algoritmo puede tardar un tiempo que es una función cuadrática del
tamaño de F, así que existen algoritmos más rápidos.

5.3.4. Recubrimiento canónico.

Para minimizar el número de dependencias funcionales que necesitan ser probadas en caso de actualización,
restringimos un conjunto dado F de dependencias funcionales a un recubrimiento canónico de F. Un recubrimiento
canónico de F es un conjunto de dependencias tal que F implica lógicamente a todas las dependencias en Fc y Fc implica
lógicamente a todas las dependencias de F. Además Fc debe tener las siguientes propiedades:
n Cada una de las dependencias funcionales α→β en Fc no contiene atributos extraños a α. Los atributos
extraños son atributos que pueden eliminarse de α sin cambiar F+c. Así A es extraño a α si A∈α y Fc
implica lógicamente a (Fc-{α→β})∪{α-A→β}.
n Cada una de las dependencias funcionales α→β en Fc no contiene atributos extraños a β. Los atributos
extraños son atributos que pueden eliminarse de β sin cambiar F+c. Así A es extraño a β si A∈β y (Fc-
{α→β})∪{α→β-A}. implica lógicamente a Fc.
n Cada lado izquierdo de una dependencia funcional en Fc es único. Es decir, no existe dos dependencias
α1→β1 y α2→β2 en Fc tales que α1=α2.

47
Bases de Datos

Para calcular un recubrimiento canónico para F, utilícese la regla de unión para sustituir cualquier dependencia en
F de la forma α1→β1 y α1→β2 con α1→β1β2 . Pruébese cada dependencia funcional α→β para ver si hay un atributo
extraño a α. Para cada dependencia α→β compruébese si hay un atributo extraño a β. Este proceso se debe repetir
hasta que no ocurra ningún cambio en el bucle.
Considérese el siguiente conjunto de dependencias funcionales F={AàBC, BàC, AàB, ABàC} en el
esquema (A, B, C). Calculemos el recubrimiento canónico de F.
Hay dos dependencias con el mismo atributo en el lado izquierdo de la flecha AàBC y AàB, por lo que las
combinamos en AàBC.
A es extraño a ABàC porque BàC implica lógicamente a ABàC, y así ((F-{ABàC})∪{BàC} implica
lógicamente a Fc. Como resultado de suprimir A de ABàC, obtenemos que BàC, la cual ya está en el conjunto de
dependencias funcionales.
En este momento, el conjunto de dependencias funcionales es F={AàBC, BàC}.
Obsérvese que ahora se cumplen las propiedades de un recubrimiento canónico.

5.4. Afirmaciones.
Una afirmación es un predicado que expresa una condición que se desea que siempre satisfaga la BD. Las
restricciones de dominio, las dependencias funcionales y las restricciones de integridad referencial son formas especiales
de afirmación, sin embargo, existen muchas restricciones que no pueden expresarse usando solamente estas tres formas
especiales. Entre los ejemplos de dichos límites están: que cada cliente de préstamos debe tener una cuenta con un saldo
mínimo de 1000$, y que cada sucursal no puede prestar más dinero que su activo.
Cuando se hace una afirmación, el sistema prueba su validez. Si la afirmación es válida, entonces cualquier
futura modificación de la BD está permitida sólo si no se provoca que se viole la afirmación.
El elevado tiempo de prueba y mantenimiento de las afirmaciones ha llevado a la mayoría de los que
desarrollan los sistemas a omitir el soporte para afirmaciones generales. La propuesta original para el lenguaje SQL
incluía una construcción de propósito general assert, para la expresión de restricciones de integridad.
Una afirmación perteneciente a una única relación toma la forma:
assert <nom_afirmación> on nom_relación> : <predicado>
Por ejemplo, si queremos definir una restricción de integridad que ningún saldo de cuenta sea negativo:
assert limite_saldo on depósito : salo ≥ 0
Podíamos haber escrito la afirmación anterior como una restricción de dominio. Sin embargo, la sentencia
assert nos permite especificar restricciones en una relación que no pueden expresarse como un límite del dominio:
assert limite_banquero on persona: nombre_cliente ≠ nombre_empleado
Las afirmaciones pueden restringirse para aplicarse sólo a modificaciones de la BD como en el caso de que
queremos prevenir la adición de una cuenta a menos que el nombre del cliente aparezca en la relación cliente. Escribimos
la afirmación siguiente:
assert limite_dirección on insertion to depósito
exists (select * from cliente
where cliente.nombre_cliente = depósito.nombre_cliente)
De hecho, la afirmación anterior es una restricción de integridad referencial.
La forma más general de afirmación es:
assert <nom_afirmación> : <predicado>
donde >predicado> es cualquier cláusula where válida en SQL
Debido al elevado tiempo que lleva la prueba de afirmaciones arbitrarias, la sentencia assert ha desaparecido de
las versiones más recientes de SQL, incluyendo la estándar. En lugar de las afirmaciones están las restricciones más fáciles
de probar, como las de dominio, las de clave y las de integridad referencial. Sin embargo, existe una propuesta para
incluir afirmaciones generales en una futura revisión del SQL estándar.

5.5. Disparadores.
Un disparador es una sentencia que el sistema ejecuta automáticamente como un efecto secundario de una
modificación de la BD.
Para diseñar un mecanismo de parador debemos:
n Especificar las condiciones bajo las cuales se va a ejecutar el disparador.
n Especificar las acciones que se van a tomar cuando se ejecute el disparador.
Supóngase que en lugar de permitir saldos negativos, el banco trata los saldos deudores poniendo el saldo de
cuenta a cero y creando un préstamo en la cantidad del saldo deudor. A éste préstamo se le da un número igual al
número de cuenta de la cuenta deudora.. Sea t la tupla con un saldo negativo, las acciones que se deben realizar son las
siguientes:
Insertar una nueva tupla s en la relación préstamo con:
s[nombre_sucursal] = t[nombre_sucursal] s[número_préstamo] = t [número_préstamo]
s[cantidad] = ¬t[saldo] s[nombre_cliente] = t [nombre_cliente]
Poner t[saldo] a cero.
El disparador de éste ejemplo sería:

48
Tema 5. Restricciones de integridad.

define trigger saldo_deudor


on update of depósito T
(if new T.saldo < 0
then (insert into préstamo values
(T.nombre_sucursal, T,número_cuenta,
T.nombre_cliente, - new T.saldo)
update depósito S
set S.saldo = 0
where S.número_cuenta = T.número_cuenta))
El SQL estándar no incluye disparadores, aunque el Sequel original incluía características de disparador
limitadas. Existen diversos sistemas con sus propias características de disparadores no estándar.

49

You might also like