Integridad y seguridad Informática aplicada
Contenido Restricciones de dominio Integridad referencial Asertos Disparadores Seguridad y autorización Autorización en SQL
Restricciones de dominio La claúsula create domain crea un nombre de dominio, ej.: create domain Euros numeric(12,2) create domain Dólares numeric(12,2) Se puede usar un dominio por otro. Por ejemplo si el atributo A de r es de tipo Euros se puede convertir mediante: cast r.A as Dólares
Claúsula check una cláusula check puede asegurar que un dominio de sueldo por hora sólo permita valores mayores que un valor especificado create domain sueldo-por-hora numeric(5,2) constraint comprobación-valor-sueldo check(value ≥ 4.00) La cláusula check también puede utilizarse para restringir un dominio para que no contenga valores nulos, como se muestra aquí: create domain número-cuenta char(10) constraint comprobación-número—cuenta-nulo check(value not null)
En este otro ejemplo el dominio se puede limitar para que contenga sólo un conjunto especificado de valores usando la cláusula in: create domain tipo-cuenta char(10) constraint comprobación-tipo-cuenta check(value in (‘Corriente’, ‘Ahorro’)) Una restricción se podría especificar sobre la relación préstamo: check (nombre-sucursal in (select nombre-sucursal from sucursal))
Integridad referencial A menudo se desea asegurar que un valor que aparece en una relación para un conjunto de atributos determinado aparezca también en otra relación para un cierto conjunto de atributos. Esta condición se denomina integridad referencial.
Conceptos básicos Considérese un par de relaciones r (R) y s (S) y la reunión natural r |X| s. Puede haber una tupla tr de r que no se reúna con ninguna tupla de s. Es decir, no hay ningún ts en s tal que tr [R ∩ S] = ts [R ∩ S]. Estas tuplas se denominan colgantes. Sean r1(R1) y r2(R2) dos relaciones con las claves primarias K1 y K2, respectivamente. Se dice que un subconjunto α de R2 es una clave externa que hace referencia a K1 de la relación r1 si se exige que para cada t2 de r2 haya una tupla t1 de r1 tal que t1[K1] = t2[α]. Las exigencias de este tipo se denominan restricciones de integridad referencial o dependencia de subconjunto. Para que una restricción de integridad referencial tenga sentido, α debe ser igual a K1, o bien α y K1 deben ser conjuntos compatibles de atributos.
Modificación de la base de datos La modificación de la base de datos puede ocasionar violaciones de la integridad referencial. Insertar. Si se inserta una tupla t 2 en r 2, el sistema debe asegurar que hay una tupla t 1 de r 1 tal que t 1 [K] = t 2 [α]. Es decir, t 2 [α] ∈ K (r 1 ) Borrar. Si se borra una tupla t 1 de r 1 el sistema debe calcular el conjunto de tuplas de r 2 que hacen referencia a r 1 : = t1[K] (r 2 ) Si este conjunto no es el conjunto vacío, o bien se rechaza la orden borrar como error, o bien se deben borrar las tuplas que hacen referencia a t 1. La última solución puede llevar a borrados en cascada, dado que las tuplas pueden hacer referencia a tuplas que hagan referencia a t 1, etcétera.
Actualizar. Hay que considerar dos casos: las actualizaciones de la relación que realiza la referencia (r 2 ) y las actualizaciones de la relación a la que se hace referencia (r 1 ). — Si se actualiza la tupla t 2 de la relación r 2 y esta actualización modifica valores de la clave externa α, se realiza una comprobación parecida a la del caso de la inserción. Si t′ 2 denota el nuevo valor de la tupla t 2, el sistema debe asegurar que t′ 2 [α] ∈ K (r 1 ) — Si se actualiza la tupla t 1 de la relación r 1 y esta actualización modifica valores de la clave primaria (K), se realiza una comprobación parecida a la del caso del borrado. El sistema debe asegurar que = t1[K] (r 2 ) utilizando el valor anterior de t 1 (el valor antes de que se lleve a cabo la actualización). Si este conjunto no es el conjunto vacío, la actualización se rechaza como error o se ejecuta en cascada de manera parecida al borrado.
Integridad referencial en SQL Ejemplo del banco: create table cliente (nombre-cliente char(20), calle-cliente char(30), ciudad-cliente char(30), primary key (nombre-cliente)); create table sucursal (nombre-sucursal char(15), ciudad-sucursal char(30), activo integer, primary key (nombre-sucursal), check (activo > = 0));
create table cuenta (número-cuenta char(10), nombre-sucursal char(15), saldo integer, primary key (número-cuenta), foreign key (nombre-sucursal) references sucursal, check (saldo >= 0)); create table impositor (nombre-cliente char(20), número-cuenta char(10), primary key (nombre-cliente, número-cuenta), foreign key (nombre-cliente) references cliente, foreign key (número-cuenta) references cuenta);
Especificación de borrado y actualización en cascada: create table cuenta (… foreign key (nombre-sucursal) references sucursal on delete cascade on update cascade, …);
Actividad Complétese la definición del LDD de SQL de la base de datos bancaria de la Figura anterior para incluir las relaciones préstamo y prestatario.
Considérese la siguiente base de datos relacional: empleado (nombre-empleado, calle, ciudad) trabaja (nombre-empleado, nombre-empresa, sueldo) empresa (nombre-empresa, ciudad) jefe (nombre-empleado, nombre-jefe) De una definición en el LDD de SQL de esta base de datos. Identifíquense las restricciones de integridad referencial que deban cumplirse e inclúyanse en la definición del LDD.
ASERTOS Un aserto es un predicado que expresa una condición que se desea que la base de datos satisfaga siempre. Las restricciones de dominio y las de integridad referencial son formas especiales de los asertos. Ejemplos de estas restricciones pueden ser La suma de todos los importes de los préstamos de cada sucursal debe ser menor que la suma de todos los saldos de las cuentas de esa sucursal. Cada préstamo tiene al menos un cliente que tiene una cuenta con un saldo mínimo de €.
create assertion restricción-suma check (not exists (select * from sucursal where (select sum(importe) from préstamo where préstamo.nombre-sucursal = sucursal.nombre-sucursal) >= (select sum (importe) from cuenta where préstamo.nombre-sucursal = sucursal.nombre-sucursal))); create assertion restricción-saldo check (not exists (select * from préstamo where not exists (select * from prestatario, impositor, cuenta where préstamo.número-préstamo = prestatario.número-préstamo and prestatario.nombre-prestatario = impositor.nombre-cliente and impositor.número-cuenta = cuenta.número-cuenta and cuenta.saldo >= 1000)));
DISPARADORES Un disparador es una orden que el sistema ejecuta de manera automática como efecto secundario de la modificación de la base de datos. Para diseñar un mecanismo disparador hay que cumplir dos requisitos: 1. Especificar las condiciones en las que se va a ejecutar el disparador. Esto se descompone en un evento que causa la comprobación del disparador y una condición que se debe cumplir para ejecutar el disparador. 2. Especificar las acciones que se van a realizar cuando se ejecute el disparador. Este modelo de disparadores se denomina modelo evento-condición-acción.
Ejemplo A modo de ejemplo supóngase que, en lugar de permitir saldos de cuenta negativos, el banco trata los descubiertos dejando a cero el saldo de las cuentas y creando un préstamo por el importe del descubierto. Este préstamo recibe un número de préstamo idéntico al número de cuenta que ha tenido el descubierto. Las acciones que hay que emprender son las siguientes: Insertar una nueva tupla s a la relación préstamo con s[nombre-sucursal] = t[nombre-sucursal] s[número-préstamo] = t[número-cuenta] s[importe] = – t[saldo] Insertar una nueva tupla u a la relación prestatario con u[nombre-cliente] = «Santos» u[número-préstamo] = t[número-cuenta] Hacer que t[saldo] sea 0.
Disparadores en SQL create trigger descubierto after update on cuenta referencing new row as nfila for each row when nfila.saldo < 0 begin atomic insert into prestatario (select nombre-cliente, número-cuenta from impositor where nfila.número-cuenta = impositor.número- cuenta); insert into préstamo values (nfila.número-cuenta, nfila.nombre-sucursal, – nfila.saldo) update cuenta set saldo = 0 where cuenta.número- cuenta = nfila.número-cuenta end;
Versión MySQL create trigger descubierto before update on cuenta for each row begin if new.saldo<0 then insert into prestatario (select nombre_cliente, numero_cuenta from impositor where new.numero_cuenta = impositor.numero_cuenta); insert into prestamo values (new.numero_cuenta,new.nombre_sucursal,-new.saldo); set new.saldo = 0; end if; end;
Ejemplo supóngase que se tienen las siguientes relaciones: inventario(producto, nivel), que denota la cantidad actual (número/peso/volumen) del producto en el almacén. nivelmínimo(producto, nivel), que denota la cantidad mínima a mantener de cada producto. nuevopedido(producto, cantidad), que denota la cantidad de producto a pedir cuando su nivel cae por debajo del mínimo. pedidos(producto, cantidad), que denota la cantidad de producto a pedir.
Se puede usar entonces el disparador mostrado para solicitar un nuevo pedido del producto. create trigger nuevopedido after update of cantidad on inventario referencing old row as ofila, new row as nfila for each row when nfila.nivel <= (select nivel from nivelmínimo where nivelmínimo.producto = ofila.producto) and ofila.nivel >= (select nivel from nivelmínimo where nivelmínimo.producto = ofila.producto) begin insert into pedidos (select producto, cantidad from nuevopedido where nuevopedido.producto= ofila.producto); end
Cuándo no deben usarse los disparadores Para mantener los datos de resumen. Para las réplicas de las bases de datos. En el peor de los casos esto podría dar lugar a una cadena infinita de disparos. Por ejemplo, supóngase que un disparador de inserción sobre una relación realice otra (nueva) inserción sobre la misma relación. La acción de inserción dispara otra acción de inserción, y así hasta el infinito.
Actividad Escríbase un disparador SQL para realizar la siguiente acción: Cuando se borre una cuenta, comprobar para cada tenedor de la cuenta si tiene otras cuentas y, si no, borrarlo de la relación impositor.
SEGURIDAD Y AUTORIZACIÓN Los datos guardados en la base de datos deben estar protegidos contra los accesos no autorizados, de la destrucción o alteración malintencionadas además de la introducción accidental de inconsistencias que evitan las restricciones de integridad. Entre las formas de acceso malintencionado se ncuentran: La lectura no autorizada de los datos (robo de información) La modificación no autorizada de los datos La destrucción no autorizada de los datos
Niveles de seguridad Para proteger la base de datos hay que adoptar medidas de seguridad en varios niveles: Sistema de bases de datos. Sistema operativo. Red. Físico. Humano.
Autorizaciones Los usuarios pueden tener varios tipos de autorización para diferentes partes de la base de datos. Entre ellas están las siguientes: La autorización de lectura permite la lectura de los datos, pero no su modificación. La autorización de inserción permite la inserción de datos nuevos, pero no la modificación de los existentes. La autorización de actualización permite la modificación de los datos, pero no su borrado. La autorización de borrado permite el borrado de los datos.
Cont. Además de estas formas de autorización para el acceso a los datos, los usuarios pueden recibir autorización para modificar el esquema de la base de datos: La autorización de índices permite la creación y borrado de índices. La autorización de recursos permite la creación de relaciones nuevas. La autorización de alteración permite el añadido o el borrado de atributos de las relaciones. La autorización de eliminación permite el borrado de relaciones.
Autorizaciones y vistas Una vista puede ocultar los datos que un usuario no necesita ver. La capacidad de las vistas para ocultar datos sirve para simplificar el uso del sistema y para mejorar la seguridad. El uso del sistema se simplifica porque se permite al usuario restringir su atención a los datos de interés. Aunque puede que se niegue el acceso directo a una relación, puede que se le permita el acceso a parte de esa relación mediante una vista. Por tanto, se puede utilizar una combinación de seguridad en el nivel relacional y en el nivel de las vistas para limitar el acceso de un usuario precisamente a los datos que necesita.
Actividad Utilizando las relaciones de la base de datos bancaria de ejemplo escríbase una expresión SQL para definir las vistas siguientes: a. Una vista que contenga los números de cuenta y los nombres de los clientes (pero no los saldos) de todas las cuentas de la sucursal de El Escorial. b. Una vista que contenga el nombre y la dirección de todos los clientes que tengan cuenta en el banco pero no tengan ningún préstamo. c. Una vista que contenga el nombre y el saldo medio de la cuenta de cada cliente de la sucursal de Collado Villalba.
Concesión de privilegios El usuario al que se le ha concedido alguna forma de autorización puede ser autorizado a transmitir esa autorización a otros usuarios. debe tener los mismos tipos de autorizaciones Grafo de concesión de autorizaciones. ABD U1U1 U2U2 U3U3 U4U4 U5U5
Papeles En la base de datos se crea un conjunto de papeles. Las autorizaciones se conceden a los papeles, de igual modo que se conceden a usuarios individuales. Se concede un conjunto de papeles a cada usuario de la base de datos (que puede ser vacío) para los que está autorizado. En el ejemplo bancario, algunos ejemplos de papeles serían cajero, gestor-sucursal, auditor y administrador- del-sistema.
Trazas de auditoría Una traza de auditoría es un registro histórico de todos los cambios (inserciones, borrados o actualizaciones) de la base de datos, junto con información sobre el usuario que realizó el cambio y en qué momento.
AUTORIZACIÓN EN SQL La norma SQL incluye los privilegios delete, insert, select y update. El lenguaje de definición de datos de SQL incluye órdenes para conceder y retirar privilegios. La instrucción grant se utiliza para conferir autorizaciones. La forma básica de esta instrucción es la siguiente: grant on <nombre de relación o de lista> to Ej.: grant select on sucursal to U1, U2, U3
Cont. El privilegio all privileges puede utilizarse como una forma abreviada de todos los privilegios que se pueden conceder. De manera parecida, el nombre de usuario public hace referencia a todos los usuarios presentes y futuros del sistema. SQL incluye también un privilegio usage que autoriza a un usuario a utilizar un dominio especificado (recuérdese que el dominio se corresponde con el concepto de tipo de un lenguaje de programación y puede ser definido por el usuario).
Papeles en SQL Los papeles se pueden crear en SQL:1999 como sigue create role cajero Se pueden conceder privilegios a los papeles al igual que a los usuarios, como se ilustra en la siguiente instrucción grant select on cuenta to cajero Los papeles se pueden asignar a los usuarios, así como a otros papeles, como muestran estas instrucciones. grant cajero to juan create role gestor grant cajero to gestor grant gestor to maría
El privilegio de conceder privilegios Un usuario o papel al que se le concede un privilegio no está autorizado de manera predeterminada a concedérselo a otros usuarios o papeles. Si se desea conceder un privilegio a un usuario y permitirle que lo transmita a otros usuarios hay que añadir la cláusula with grant option a la orden grant correspondiente. Por ejemplo, si se desea conceder a U1 el privilegio select sobre sucursal y que pueda transmitirlo a otros, hay que escribir grant select on sucursal to U1 with grant option
Revocar privilegios Para retirar una autorización se utiliza la instrucción revoke. Adopta una forma casi idéntica a la de grant: revoke on from [restrict | cascade] Por tanto, para retirar los privilegios que se han concedido con anterioridad hay que escribir revoke select on sucursal from U1, U2, U3 revoke update (importe) on préstamo from U1, U2, U3 revoke references (nombre-sucursal) on sucursal from U1
Limitaciones de la autorización SQL Las normas SQL actuales de autorización tienen algunas deficiencias. Por ejemplo, supóngase que se desea que todos los estudiantes sean capaces de ver sus propias notas, pero no las del resto. La autorización debe estar en el nivel de las tuplas, lo cual no es posible en los estándares de autorización de SQL.
DEPENDENCIAS FUNCIONALES Una dependencia funcional es un tipo de restricción que constituye una generalización del concepto de clave
Conceptos básicos Las dependencias funcionales son restricciones del conjunto de relaciones legales. Permiten expresar hechos sobre la empresa que se modela con la base de datos. Sea R el esquema de una relación. El 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 de r tales que t1 ≠ t2, t1 [K] ≠ t2 [K]. Considérese el esquema de una relación R y sean α ⊆ R y β ⊆ R. La dependencia funcional α →β se cumple para el esquema R si, en cualquier relación legal r (R), para todos los pares de tuplas t1 y t2 de r tales que t1 [α] = t2 [α], también ocurre que t1 [β] = t2 [β].
Ejemplo Considérese el esquema Esquema-info-préstamo = (número-préstamo, nombre-sucursal, nombre-cliente, importe) El conjunto de dependencias funcionales que se espera que se cumplan en este esquema de relación es número-préstamo → importe número-préstamo → nombre-sucursal Sin embargo, no se espera que se cumpla la dependencia funcional Número-préstamo → nombre-cliente ya que, en general, cada préstamo se puede conceder a más de un cliente
uso Las dependencias funcionales se utilizarán de dos maneras: 1. Para probar las relaciones y ver si son legales según un conjunto dado de dependencias funcionales. Si una relación r es legal según el conjunto F de dependencias funcionales, se dice que r satisface F. 2. Para especificar las restricciones del conjunto de relaciones legales. Así, sólo habrá que preocuparse por las relaciones que satisfagan un conjunto dado de dependencias funcionales. Si uno desea restringirse a las relaciones del esquema R que satisfagan el conjunto F de dependencias funcionales, se dice que F se cumple en R.
ejemplo ABCD a1b1c1d1 a1b2c1d2 a2b2c2d2 a2b3c2d3 a3b3c2d4 se satisface A→C C →A no se satisface se satisface AB → D
Se dice que algunas dependencias funcionales son triviales porque las satisfacen todas las relaciones. Por ejemplo, A → A la satisfacen todas las relaciones que impliquen al atributo A. En general, una dependencia funcional de la forma α →β es trivial si β ⊆ α.
Tablas del banco nombre-clientecalle-clienteciudad-cliente SantosMayorPeguerinos GómezCarretasCerceda LópezMayorPeguerinos PérezCarretasCerceda RupérezRamblasLeón AbrilPreciadosValsaín ValdiviesoGoyaVigo FernándezJazmínLeón GonzálezArenalLa Granja RodríguezYeseríasCádiz AmoEmbajadoresArganzuela BadorreyDeliciasValsaín
número-préstamonombre-sucursalImporte P-17Centro1000 P-23Moralzarzal2000 P-15Navacerrada1500 P-14Centro1500 P-93Becerril500 P-11Collado Mediano900 P-29Navas de la Asunción1200 P-16Segovia1300 P-18Centro2000 P-25Navacerrada2500 P-10Galapagar2200
nombre-sucursalciudad-sucursalactivo CentroArganzuela MoralzarzalLa Granja NavacerradaAluche BecerrilAluche Collado MedianoAluche Navas de la AsunciónAlcalá de Henares SegoviaCerceda GalapagarArganzuela
Ejemplos Si se considera la relación cliente (en Esquemacliente) puede verse que se satisface calle-cliente → ciudad-cliente. En la relación préstamo (de Esquema-préstamo) se puede ver que se satisface la dependencia número-préstamo → importe. Se satisface nombre-sucursal → activo, igual que ocurre con activo → nombre-sucursal
Diseño cuando se diseña una base de datos relacional, se enumeran en primer lugar las dependencias funcionales que se deben cumplir siempre. En el ejemplo del banco, en la lista de dependencias figuran: En Esquema-sucursal: nombre-sucursal → ciudad-sucursal nombre-sucursal → activo En Esquema-cliente: nombre-cliente → ciudad-cliente nombre-cliente → calle-cliente En Esquema-préstamo: número-préstamo → importe número-préstamo → nombre-sucursal En Esquema-prestatario: Ninguna dependencia funcional En Esquema-cuenta: número-cuenta → nombre-sucursal número-cuenta → saldo En Esquema-impositor: Ninguna dependencia funcional
Diseño de bases relacionales Bases de datos
Descomposición Ejemplo de descomposición Sea el esquema: esquema-empréstito = (nombre-sucursal, ciudad-sucursal, activo, nombre- cliente, número-préstamo, importe) Al añadir una tupla se deben repetir algunos datos como la ciudad de la sucursal. Si una sucursal se cambia de ciudad habrá que cambiar muchas tuplas. La dependencia funcional nombre-sucursal ciudad-sucursal se espera que se cumpla, pero no nombre-sucursal número-préstamo. No se puede representar directamente la información de una sucursal (nombre-sucursal, ciudad-sucursal, activo). Peor aún, tendría que borrarse la información cuando se hayan pagado todos los prestamos.
tabla empréstito nombre de la sucursalciudad de la sucursalactivosnombre-clientenúmero-préstamoimporte CentroArganzuela1,800,000,000SantosP-17200,000 MoralzarzalLa Granja420,000,000GómezP-23400,000 NavacerradaAluche340,000,000LópezP-15300,000 CentroArganzuela1,800,000,000SotocaP-14300,000 BecerrilAluche80,000,000SantosP-93100,000 Collado MedianoAluche1,600,000,000AbrilP-11180,000 Navas de AsunciónAlcalá de Henares60,000,000ValdiviesoP-29240,000 SegoviaCerceda740,000,000LópezP-16260,000 CentroArganzuela1,800,000,000GonzálezP-23400,000 GalapagarArganzuela1,420,000,000RodríguezP-25500,000 CuencaVillaverde15,000,000AmoP-10440,000
Supongamos que se separa en: esquema-sucursal-cliente = (nombre-sucursal, ciudad-sucursal, activo, nombre-cliente) esquema-préstamo-cliente = (nombre-cliente, número-préstamo, importe) Se crean las tablas sucursal-cliente y préstamo-cliente por medio de sucursal-cliente = P nombre-sucursal, ciudad-sucursal, activo, nombre-cliente (empréstito) préstamo-cliente = P nombre-cliente, número-préstamo, importe (empréstito) La reunión natural de estas tablas es sucursal-cliente |><| préstamo-cliente Esta reunión produce la tabla de la siguiente lámina
nombre de la sucursalciudad de la sucursalactivos nombre- clientenúmero-préstamoimporte CentroArganzuela1,800,000,000SantosP-17200,000 CentroArganzuela1,800,000,000SantosP-93100,000 MoralzarzalLa Granja420,000,000GómezP-23400,000 NavacerradaAluche340,000,000LópezP-15300,000 NavacerradaAluche340,000,000LópezP-16260,000 CentroArganzuela1,800,000,000SotocaP-14300,000 BecerrilAluche80,000,000SantosP-17100,000 BecerrilAluche80,000,000SantosP-93100,000 Collado MedianoAluche1,600,000,000AbrilP-11180,000 Navas de AsunciónAlcalá de Henares60,000,000ValdiviesoP-29240,000 SegoviaCerceda740,000,000LópezP-15300,000 SegoviaCerceda740,000,000LópezP-16260,000 CentroArganzuela1,800,000,000GonzálezP-23400,000 NavacerradaAluche340,000,000RodríguezP-25500,000 GalapagarArganzuela1,420,000,000AmoP-10440,000
El único camino para relacionar número-préstamo y nombre-sucursal es a través de nombre-cliente. Esto no es adecuado porque un cliente puede tener préstamos en varias sucursales. Considere la siguiente descomposición: Esquema-sucursal =(nombre-sucursal, ciudad-sucursal, activo) Esquema-info-préstamo = (nombre-sucursal, nombre-cliente, número-préstamo, importe) Se mantiene la dependencia funcional nombre-sucursal activo ciudad-sucursal pero nombre-cliente no determina funcionalmente a número-préstamo
Definición Sea C un conjunto de ligaduras en la base de datos. Una descomposición [R1, R2,..., Rn] de un esquema de relación R es una descomposición de reunión sin pérdida para R si para todas las relaciones r que son legales bajo C r = R1 (r) |> <| Rn (r)
Primera forma normal Los dominios deben de ser atómicos Ejemplos de dominios no atómicos conjunto de nombres, atributos compuestos Número de identificación como CS101 que pueden dividirse en partes un esquema de relación R esta en primera forma normal si los dominios de todos los atributos son atómicos Los valores no-atómicos complican el almacenamiento y producen almacenamiento redundante (repetido) de los datos Ejemplo:. conjunto de cuentas guardado con cada cliente, y conjunto de propietarios guardado con cada cuenta Suponemos todas las relaciones están en primera forma normal
Primera forma normal (cont.) La atomicidad es realmente una propiedad de como los elementos de un dominio son usados. Ejemplo: Las cadenas se consideran normalmente indivisibles Suponga que a los estudiantes se les da un número el cual es una cadena de la forma CS0012 o EE1127 Si los dos primeros caracteres son extraídos para encontrar el departamento, el dominio de los números no es atómico. Hacer esto es una mala idea: lleva a codificar información en el programa de aplicación en lugar de en la base de datos.
Objetivo - inventar una teoría para lo siguiente Decida si una relación particular R esta en "buena" forma. En el caso de que una relación R no este en "buena" forma, descomponerla en un conjunto de relaciones {R1, R2,..., Rn} tales que: cada relación este en "buena" forma la descomposición sea sin reunión con pérdida Nuestra teoría esta basada en: dependencias funcionales dependencias multivaluadas
Ligaduras de los dominios La ligadura de dominio permite la verificación de valores al momento de agregar datos a la base de datos. Solo aquellos que cumplan con la ligadura serán aceptados como datos válidos, los demás serán rechazados. En SQL se utiliza la sentencia check para establecer la ligadura de dominios, ejemplos: create domain sueldo-por-hora numeric(7,1) constraint comprobacion-valor-sueldo check (value >= 800) create domain numero-cuenta char(10) constraint comprobacion-numero-cuenta-nulo check (value not null)
Integridad referencial Sean r 1 (R 1 ) y r 2 (R 2 ) dos relaciones con claves primarias K 1 y K 2. Se dice que un subconjunto de R es una clave externa que hace referencia a K 1 de la relación r 1 si se exige que para cada t 2 de r 2 haya una tupla t 1 en r 1 tal que t 1 [K 1 ] = t 2 [ ] Las exigencias de este tipo se denominan ligaduras de integridad referencial o dependencias de subconjunto. La última denominación proviene de que lo anterior puede expresarse como: (r 2 ) K1 (r 2 )
Modificación de la base de datos insertar. Si se inserta una tupla t 2 en r 2, el sistema debe asegurar que hay una tupla t 1 en r 1 tal que t 1 [K] = t 2 [ ], es decir t 2 [ ] K1 (r 2 ) borrar. Si se borra una tupla t 1 en r 1, el sistema debe calcular el conjunto de tuplas de r 2 que hacen referencia a r 1 : = t 1[ K] (r 2 ) Actualizar: Hay que considerara dos casos: las actualizaciones de la relación que realiza la referencia (r2) y las actualizaciones de la relación a la que se hace referencia (r1). - si se actualiza la tupla t 2 de la relación r 2 y esta actualización modifica los valores de la clave externa , se realiza una comprobación parecida al caso de la inserción. El sistema debe asegurar que t 2 ’[ ] K (r 1 ) - si se actualiza la tupla t 1 de la relación r 1 y esta actualización modifica los valores de la clave externa primaria (K), se realiza una comprobación parecida al caso del borrado. El sistema debe asegurar que = t 1[ K] (r 2 )
Dependencias funcionales Sea R un esquema de relación. Sean R y R. La dependencia fucnional , se cumple en R si en cualquier relación legal r(R), para todos las pares de tuplas t 1 y t 2 de r tales que t 1 [ ] = t 2 [ ] también ocurre t 1 [ ] = t 2 [ ]. Considere el esquema esquema-información-préstamo = (nombre-sucursal, número-préstamo, nombre-cliente, importe) Se esperan las siguientes dependencias funcionales número-préstamo importe número-préstamo nombre-sucursal pero no número-préstamo nombre-cliente
Utilización 1. para especificar las ligaduras del conjunto de relaciones legales. Así solo habrá que preocuparse por las relaciones que satisfagan un conjunto dado de dependencias funcionales. 2. Para examinar las relaciones y comprobar si son legales bajo un conjunto dado de dependencias funcionales. ABCD a1a1 b1b1 c1c1 d1d1 a1a1 b2b2 c1c1 d2d2 a2a2 b2b2 c2c2 d2d2 a2a2 b3b3 c2c2 d3d3 a3a3 b3b3 c2c2 d4d4 Se satisface A C No se satisface C A Se satisface AB D
Ejemplo bancario Esquema esquema-sucursal nombre-sucursal ciudad-sucursal nombre-sucursal activo Esquema esquema-cliente nombre-cliente ciudad-cliente nombre-cliente calle-cliente Esquema esquema-prestamo número-préstamo importe número-préstamo nombre-sucursal Esquema esquema-prestatario No hay Esquema esquema-cuenta número-préstamo nombre-sucursal número-préstamo saldo Esquema esquema-impositor No hay
Cierre de un conjunto de dependencias funcionales Sea un esquema de relación R = (A, B, C, G, H, I) y el conjunto de dependencias funcionales A B A C CG H CG I B H A H está implicada lógicamente. El cierre de un conjunto de dependencias funcionales F es el conjunto de todas las dependencias funcionales implicadas lógicamente por F. Se denota por F +. Por las reglas que siguen CG HI y AG I
Reglas de inferencia Regla de reflexividad. Si es un conjunto de atributos y , entonces se cumple que . Regla de aumentatividad. Si se cumple que y es un conjunto de atributos, entonces se cumple que . Regla de transitividad. Si se cumple que y , entonces Estas reglas se conocen como axiomas de Armstrong. Se agregan las siguientes reglas deducibles a partir de las anteriores. Regla de la unión. Si se cumple que y , entonces se cumple Regla de la descomposición. Si se cumple que , entonces se cumple que y que Regla de la seudotransitividad. Si se cumple que y que , entonces se cumple
Cierre de los conjuntos de atributos Para comprobar si un conjunto es una superclave hay que preparar un algoritmo para calcular el conjunto de los atributos determinados funcionalmente por . Se denomina cierre de sobre F al conjunto de todos los atributos determinados funcionalmente por bajo un conjunto de dependencias funcionales F; se denota por +. Algoritmo en pseudo Pascal resultado : = ; while (cambios en resultado) do for each dependencia funcional in F do begin if resultado then resultado := resultado ; end
Ejemplo Para el esquema de relación R = (A, B, C, G, H, I) y el conjunto de dependencias funcionales A B A C CG H CG I B H Aplicamos el algoritmo para calcular (AG) + : pasodependenciaresultado 1 A B ABG 2A CABCG 3CG HABCGH 4CG IABCGHI ¿Es AG una llave candidata?
Recubrimiento canónico Conjuntos de dependencias funcionales pueden ser inferidos a partir de otros Por ejemplo: A C es redundante en {A b, B C} partes de una dependencia funcional puede ser redundante o sea: en RHS: {A B, B C, A CD} se puede simplificar a {A B, B C, A D} o sea: en LHS: {A B, B C, AC D} se puede simplificar a {A B, B C, A D} Intuitivamente, un recubrimiento canónico de F es un conjunto "mínimo" de dependencias funcionales equivalente a F, sin teniendo dependencias redundantes o partes redundantes de dependencias.
Atributos extraños Considere un conjunto F de dependencias funcionales y la dependencia funcional en F. El atributo A es extraño en si A de y F implica lógicamente (F- { } {( -A) } El atributo A es extraño en si A y el conjunto de dependencias funcionales (F-{ } { (A- )} implica lóigicalmente a F Note: la implicación en la dirección contraria es trivial en cada uno de los casos de arriba, ya que una dependencia funcional "fuerte" siempre implica a una más débil Ejemplo: dado f = {A C. AB C} B es extraña en AB C debido a {A C, AB >C} implica lógicamente A C (el resultado de quitar B de AB C) Ejemplo: dado f = {A C.AB CD} C es extraña en AB CD debido a AB C es inferido aun despues de borrar C
Prueba si un atributo es extraño Considere un conjunto F de dependencias funcionales y la dependencia funcional en F Para probar si A es extraño en a calcule ([ ] - A) + usando las dependencias funcionales en F, cheque si ([ ] - A) + contiene , si es así, A es extraño en . Para probar si el atributo A elemento de es extraño en calcule + usando solo dependencias funcionales en F‘ = (F-{ }) { (b-A)}, cheque si + contine a A, si es así, A es extraño en .
Recubrimiento canónico Un Recubrimiento canónico para F es un conjunto de dependencias funcionales F c tales que: F implica lógicamente todas las dependencias en F c y F c implica lógicamente todas las dependencias en F y Ninguna dependencia funcional en F c contiene atributos extraños y Todos los lados izquierdos de dependencias funcionales en F c son únicos Para calcular el recubrimiento canónico para F repeat Use la regla de unión para reemplazar cualquier dependencia en F 1 y 1 2 con 1 2 encuentre una dependencia funcional con un atributo extraño en o en if se halla el atributo extraño, elimínelo de until que F no cambie Note que la regla de unión puede ser aplicable después de que los atributos extraños han sido borrados, por esto deberá ser reaplicada.
aplicación R = (A, B, C) F = {A BC B C A B AB C} Combine A BC and A B into A BC El conjunto es ahora {A BC, B C, AB C} A is extraño en AB C Cheque si el resultado de borrar A de AB C es implicado por las otras dependencias Si: en efecto, B C está aún presente! El conjunto es ahora {A BC, B C} C is extraño en A BC Cheque si A C esta lógicamente implicado por A B y las otras dependencias Si: usando transitividad en A B and B C. Se puede usar cerradura de atributos de A en casos más complejos. El recubrimiento canónico es:A B B C
Forma normal de Boyce-Codd Un esquema de relación R esta en FNBC con respecto a un conjunto de dependencias funcionales si todas las dependencias funcionales en F + de la forma donde R y R, por lo menos una de las siguientes se cumple: es trivial (o sea ) es superllave de R Ejemplo de un esquema no en FNBC: prestatario_préstamo = (cliente_id, número_préstamo, cantidad) debido a que numero_prestamo cantidad en prestatario_prestamo se cumple pero numero_prestamo no es superclave
Ejemplo Sean los siguientes esquemas y dependencias funcionales Esquema esquema-cliente = (nombre-cliente, calle-cliente, ciudad-cliente) nombre-cliente ciudad-cliente calle-cliente Esquema esquema-sucursal = (nombre-sucursal, activo, ciudad-sucursal) nombre-sucursal activo ciudad-sucursal Esquema esquema-info-préstamo = (nombre-sucursal, nombre-cliente, número-préstamo, importe) número-préstamo importe nombre-sucursal Podemos afirmar que esquema-cliente está en FNBC, también esquema- sucursal está en FNBC. Pero esquema-info-préstamo no está en FNBC ya que número-préstamo no es superllave de esquema-info-préstamo.
Descomposición de un esquema en BCNF Suponga que tenemos un esquema R y una dependencia no trivial causa una violación de FNBC Descomponemos R en: ( ) (R- - )) En nuestro ejemplo = numero_prestamo = cantidad y prestatario_prestamo se reemplaza por ( ) = (numero_prestamo,cantidad) (R-( - )) = (cliente_id, numero_prestamo)
Algoritmo de descomposición resultado := {R}; hecho := false; calcular F’; while (not hecho) do if(hay un esquema Ri de resultado que no este en FNBC) then begin sea a ->b una dependencia funcional no trivial que se cumpla en Ri de modo que a -> Ri, no está en F’ y que ainter b = fi; resultado := (resultado – Ri) union (Ri – b)(a,b) end else hecho := true; Donde F’ es la unión de las dependencias funcionales en donde solo aparecen atributos de un esquema en particular.
Ejemplo Considere el esquema esquema-empréstito = (nombre-sucursal, ciudad-sucursal, activo, nombre-cliente, número-préstamo, importe) Con las siguientes dependencias funcionales nombre-sucursal activo ciudad-sucursal número-préstamo importe nombre-sucursal una clave candidata es (número-préstamo, nombre-cliente) La aplicación del algoritmo da: 1. ya que nombre-sucursal no es una superclave, el esquema se debe se reemplaza por esquema-sucursal = (nombre-sucursal, ciudad-sucursal, activo) esquema-info-préstamo = (nombre-sucursal, nombre-cliente, número-préstamo, importe) 2. en este esquema es clave de y por lo tanto está en FNBC
Ejemplo (cont.) 3. número-préstamo no es clave en esquema-info-préstamo, por lo que hay que reemplazarlo con esquema-préstamo = (nombre-sucursal, número-préstamo, importe) esquema-prestatario = (nombre-cliente, número-préstamo) Estos esquemas están en FNBC
BCNF y conservación de las dependencias Ligaduras, incluyendo las dependencias funcionales, son costosas para verificar en la práctica a que pertenezcan a una sola relación Si es suficiente probar solo aquellas dependencias en cada relación individual de la descomposición de manera de asegurar que todas las dependencias funcionales se cumplan, entonces esa descomposición conserva las dependencias. Debido a que no siempre es posible obtener ambas FNBC y conservación de las dependencias, la consideramos una forma normal débil, conocida como tercera forma normal.
Tercera forma normal Un esquema de relación R esta en tercera forma normal (3NF) si para todas: en F+ por lo menos una de las siguientes se cumple: es trivial (o sea ) es superllave para R Cada atributo A en - esta contenido en una llave candidata para R. (note: cada atributo puede ser en una llave candidata diferente) Si una relación esta en FNBC esta en 3NF (ya que en FNBC una de las primeras dos condiciones de arriba se debe cumplir) La tercera condición es una relajación mínima de FNBC para asegurar la conservación de dependencias.
Algoritmo 3NF que preserva dependencias Sea F c un recubrimiento canónico de F; i := 0; for each dependencia funcional en F c do if ninguno de los esquemas Rj, 1 j i contiene then begin i := i + 1; Ri := end if de los esquemas Rj, 1 j i contiene un clave candidata para R then begin i := i + 1; Ri := cualquier clave candidata para R; end return (R1, R2,..., Ri)
Algoritmo 3NF que preserva dependencias (cont.) El algoritmo asegura que: Cada esquema de relación Ri esta en 3FN La descomposición preserva dependencias y reunión sin pérdida
Ejemplo Esquema de relation: cliente_banquero_sucursal = (cliente_id, empleado_id, nombre_sucucral, tipo ) Las dependencias funcionales de este esquema son: cliente_id, empleado_id nombre_sucucral tipo empleado_id nombre_sucucral cliente_id, nombre_sucucral empleado_id Calculamos el recubrimiento canónico nombre_sucucral es extraño en el r.h.s. de la 1st dependencia Nuingún otror atributo es extraño, por tanto obtenemos FC = cliente_id, empleado_id tipo empleado_id nombre_sucucral cliente_id, nombre_sucucral empleado_id
ejemplo (cont.) El lazo for genera el siguiente esquema 3NF: (cliente_id, empleado_id, tipo ) (empleado_id, nombre_sucursal) (cliente_id, nombre_sucursal, empleado_id) Observe que (cliente_id, empleado_id, tipo ) contiene una clave candidata del esquema original, por tanto es necesario agregar más equemas de relación. Si la FDs fuera considerada en order different, con la 2nda considerada después de la tercera, (empleado_id, nombre_sucursal) no sería incluida en la descomposición debido a que es un subconjunto de (cliente_id, nombre_sucursal, empleado_id) Extensiones Menores del algoritmo de decomposicion 3NF: al final del lazo for, detectar y borrar esquemas, tales que (empleado_id, nombre_sucursal), los cuales son subconjuntos de otros esquemas resultantes no dependen en el orden en que FDs son considerados. El esquema resultado simplificado 3NFes: (cliente_id, empleado_id, tipo) (cliente_id, nombre_sucursal, empleado_id)
Objetivos de Normalización Sea R un esquema de relación con un conjunto F de dependencias funcionales. Decida si un esquema de relación R esta en "buena" forma. En el caso de que el esquema de relación R no este en "buena" forma, descompóngalo en un conjunto de esquemas de relación {R1, R2,...,Rn} tales que: cada esquema de relación este en buena forma la descomposición es una descomposición sin pérdida Preferiblemente, la descomposición debe ser tal que conserve las dependencias.
¿Que tan buena es NFBC? Hay esquemas de bases de datos en NFBC que no parecen suficientemente normalizados Considere la base de datos clases(curso, maetro, libro) tal que (c, m, b) elemento de clases significa que m es calificado para enseñar c, y b es el libro de texto para c. La base de datos se supone que lista para cada curso un conjunto de maestros cualquiera de ellos puede ser el instructor, y un conjunto de libros, todos los cuales son requeridos para el curso (sin importar quien lo enseña)
¿Que tan buena es NFBC? (cont.) cursomaestrolibro base de datosAviDB concepts base de datosAviUllman base de datosHankDB concepts base de datosHankUllman base de datosSudarshaDB concepts base de datosSudarshaUllman Sistemas oper.AviOS concepts Sistemas oper. AviStallings Sistemas oper. PeteOS concepts Sistemas oper. PeteStallings No hay dependencias funcionales no-triviales y por lo tanto la relación está en BCNF Anomalias de inserción - o sea si Marilyn es una nueva maestra que puede enseñar dases de datos, se deben insertar dos tuplas (bases de datos, Marilyn, DB concepts) (bases de datos, Marilyn, Ullman)
¿Que tan buena es NFBC? (cont.) Por lo tanto es mejor descomponer clases en: cursomaestro base de datosAvi base de datosHank base de datosSudarshan Sistemas oper.Avi Sistemas oper.Jim Maestros cursolibro base de datosDB concepts base de datosUllman Sistemas oper.OS concepts Sistemas oper.Shaw libro