Javier Reyes Estupiñán
Eliezer Ramírez Cabrera
Rodrigo Heredero Robayna
Índice Introducción--------------------------------------------------------------------------------pag 3 Algoritmos Auxiliares--------------------------------------------------------------------pag 5 Algoritmo del del cálculo cálculo del cierre de un un descriptor-------------descriptor----------------------------pag --------------pag 5 Algoritmo del cálculo del recubrimiento recubrimiento minimal-------------------------minimal---------------------------pag -pag 7 Nuevos conceptos. conceptos. -------------------------------------------------------------- ---------------------------------pag ------------pag 7 Atributos Extraños------------------------------Extraños-------------------------------------------------------------------------pag ---pag 8 Eliminación Eliminación de atributos extraños. .----------------------------------pag .------------------- ---------------pag 9 Eliminación Eliminación de dependencias dependencias redundantes.------------------redundantes.--------------------------pag -------pag 11 Algoritmo completo completo del cálculo cálculo de recubrimiento recubrimiento minimal.------pag 13 Algoritmo de Determinación Determinación de claves. claves. --------------------------------------pag -------------------------------- ------pag 14 Algoritmo de Normalización Normalización -------------------------------------------------------------- --------------------------------------pag -----------------pag 17 Algoritmo de Síntesis--------------------------------------Síntesis-------------------------------------------------------------------------------pag -pag 17 Algoritmos de descomposición.-------------------------descomposición.-------------------------------------------------------------------pag --pag 18 Algoritmos que determinan determinan la forma normal en la que se encuentra un esquema esquema relacional relacional --------------------------------------pag ------------------- -------------------pag 19 Determinación 2FN---------------------------------------------pag 19 Determinación Determinación 3FN---------------------------------------------pag 3FN-------------------------- -------------------pag 23 Determinación Determinación FNBC--------------------------FNBC------------------------------------------pag ---------------pag 24 Algoritmos de descomposición de un esquema de relación en esquemas en FNBC--------------------------FNBC---------------------------------------------------------------------pag ---pag 25 Descomposición Descomposición en esquemas FNBC------------------------pag FNBC----------------------- -pag 25 Proyección de un conjunto de dependencias sobre un conjunto de atributos------------------------------atributos---------------------------------pag --pag 27 Algoritmo de descomposición de esquemas FNBC que mejora la eficiencia---------------------eficiencia----------------------------------------pag ------------------pag 28 Nuevo algoritmo algoritmo que mejora mejora la la funcionalida funcionalidad. d. -------------pag 31 Algoritmos que analizan si una descomposición se hace sin pérdidas de información. información. --------------------------------------------------------- ----------------------------pag --------pag 36 Determinación Determinación de si una una descomposició descomposiciónn es SPI-----------pag 36 Determinación Determinación de si una descomposición descomposición preserva las dependencias dependencias funcionales. funcionales. ---------------------------------pag ------------------- --------------pag 40 Algoritmos Alternativos-------------------------------------------------------------------pag 42 Particionamiento Particionamiento Vertical. Vertical. ---------------------------------------------------------- ------------------------------------pag ---------------pag 42 Particionamiento Particionamiento Horizontal. Horizontal. -------------------------------------------------------- ----------------------------------pag -------------pag 45 Conclusiones--------------------------------------------------------------------------------pag 46
Introducción Tradicionalmente, el diseño de una base de datos de organiza en 3 niveles de abstracción:
Diseño conceptual : obtener una representación de la realidad lo más fidedigna
posible, también llamado “obtención de la semántica de los datos. Diseño lógico: bajo un modelo concreto, se traduce el esquema conceptual, para generar un esquema lógico y un conjunto de transacciones sobre el mismo. representación física (ficheros, tablas, etc) de Diseño Físico: consiste en dar una representación los datos atendiendo a términos de eficiencia y eficacia. En este tema nos vamos a centrar en el diseño lógico de la base de datos. A su vez, este nivel de diseño tiene su propia metodología de desarrollo. Partiendo de un esquema conceptual (el Modelo Entidad Interrelación), se desarrollan reglas de derivación que permiten pasar de este modelo al Modelo Lógico Relacional (que representa la semántica de los datos mediante dependencias de tipo funcional, multivaluada, etc). El paso final es refinar este esquema obtenido con el simple uso de reglas de derivación, derivación, con el fin de recoger la mayor semántica semántica posible del universo de discurso que se trata de modelar. En este punto surgen, entre otras las formas normales ya vistas en años pasados.
Esquema Conceptual: semántica de datos Modelo Entidad Interrelación.
Esquema Lógico (I): Dependencias Funcionales Modelo Relacional
Esquema Lógico (II):
refinamiento de los esquemas relacionales. Algoritmos para el refinamiento.
Pues bien, los algoritmos que vamos a presentar en este tema están orientados a este último punto de optimización de los esquemas lógicos relacionales. La posibilidad de generar algoritmos que faciliten la optimización y generación por tanto de un esquema lógico se debe al tratamiento formal de las bases de datos, especialmente, al Modelo Relacional. La algoritmia permite en muchos casos facilitar la tarea al diseñador de la Base de Datos, si bien no puede abarcar todo el diseño de la base de datos, ni siquiera en el nivel lógico. Un ejemplo es la detección de formas normales 5NF en un esquema relacional, para el que sí existen algoritmos, pero que debido a su tiempo (exponencial) son impracticables en la realidad, recurriéndose muchas veces a la heurística como segunda alternativa. Vamos a organizar los algoritmos en función de su propósito dentro del refinamiento de esquemas relacionales. Así, desde algoritmos auxiliares que definen procesos para obtener características del esquema relacional que nos ayuden a su vez a resolver otros algoritmos más complejos (el resto), pasando por algoritmos de
con el fin de refinar los esquemas relacionales de forma lógica, y terminando con algoritmos alternativos que completen a la Normalización.
Normalización
Por ello, en este trabajo nos vamos a basar en los algoritmos que abordan los distintos problemas de la manera más eficiente posible, descartando aquellos que, si bien, en algunos casos sirvieron como base para la consecución de algoritmos más modernos y eficientes, hoy día son pocas (por no decir ninguna) las bases de datos que los implementan.
Algoritmos Auxiliares La mayoría de los algoritmos de análisis y de síntesis exigen calcular previamente el recubrimiento irredundante y las claves del esquema de relación, los cuales a su vez, se basan en el cálculo del cierre de un descriptor a su vez. Inicialmente eran de orden exponencial, lo cual hacía impracticables los algoritmos fundamentados en estos elementos básicos. Por ello es fundamental el costo en estos algoritmos, ya que van a ser la base de otros algoritmos. Los algoritmos que se van a exponer a continuación tienen como principal objetivo la reducción del tiempo computacional respecto a los propuestos anteriormente y, por lo tanto, hacerlos operativos. Muchos de ellos se basan en un estudio previo de las dependencias del esquema de relación que se desea normalizar, a fin de poder simplificar los cálculos posteriores detectando, mediante este “estudio previo” dependencias redundantes y/o atributos extraños, descartándolos, y reduciendo así el número de dependencias y atributos a los que se aplica el algoritmo
Algoritmo de cálculo del cierre de un descriptor Y comenzamos por éste por ser un cálculo básico del que los algoritmos siguientes van a hacer uso. El que a continuación continuación vamos a detallamos detallamos,, DIEDERICH DIEDERICH (1988), se caracteriza caracteriza por tener una complejidad lineal de O(n), siendo n el número de dependencias. Entrada: DF conjunto de dependencias funcionales. Salida: X+ cierre de X respecto a DF A continuación vamos a describir el proceso basándonos, para entenderlo mejor, en el siguiente ejemplo: Dada la siguiente relación: relación: R ({CE, NE, P, P, G, CP, C}, DF) DF) donde: DF = {CE → NE, NE → CE, P → CE, G → P, (CP, P) → G,CE → C, P → C} Calcular el cierre de (CP, P) +: Proceso:
1) X+ = X, ACTUAL = X (CP, P)+ = CP,P y ACTUAL = CP,P
2) Para cada dependencia funcional d de DF:
contador (d ) = nº de atributos de la parte izquierda de d .
contador (CE → NE) = 1 contador (G → P) = 1 1 contador (P → C) = 1
contador (NE → CE) = 1 contador (P → CE) = 1 contador (CP, P → G) = 2 contador (C (CE → C) =
3) Para cada atributo A, construir: lista (A) = {(Y → B) ∈ DF / A ∈ Y} lista (CE) = {CE → NE; CE → C} → CE} lista (P) = {P → CE; CP,P → G; P → C} lista (CP) = {CP,P → G}
4) Mientras ACTUAL ≠
lista
(NE)
=
{NE
lista (G) = {G → P} lista (C) = {∅}
∅
5) Seleccionar y eliminar un atributo A de ACTUAL ACTUAL = P (eliminamos CP)
6) Para cada dependencia d = Y → C de lista(A) lista (CP) = {CP,P → G}
7) Decrementar el contador ( d ) contador (CP, P → G) = 1
8) Si contador (d ) = 0 entonces:
Si C no está en X + X+ = X+ ∪ {C} ACTUAL = ACTUAL ∪ {C} No es el caso .
Volvemos al paso 4) y ahora ACTUAL = P En el 5) ACTUAL = ∅ (eliminamos P) En el 6) lista (P) = {P → CE; CP,P → G; P → C} En el 7) para P → CE ⇒ contador (P → CE) = 0 En el 8) C ≡ CE ∉ X+ ⇒ X+ = {CP, P} ∪ {CE} y ACTUAL = {∅} ∪ {CE} En el 7) para para CP,P CP,P → G ⇒ contador contador (CP,P → G) = 0 decrementado a 1)
( ya lo habíam habíamos os
En el 8) C ≡ G ∉ X+ ⇒ X+ = {CP,P,CE} ∪ {G} y ACTUAL = {CE} ∪ {G} En el 7) para P → C ⇒ contador (P → C) = 0 En el 8) C ≡ C ∉ X+ ⇒ X+ = {CP,P,CE,G} ∪ {C} {C} Volvemos al paso 4) y ahora ACTUAL = {CE,G,C} En el 5) ACTUAL = {G,C} (eliminamos CE) En el 6) lista (CE) = {CE → NE; CE → C} En el 7) para CE → NE ⇒ contador (CE → NE) = 0
y
ACTUAL = {CE,G} ∪
En el 8) C ≡ NE ∉ X+ ⇒ X+ = {CP, P,CE,G,C} ∪ {NE} ∪ {NE}
y
ACTUAL = {G,C}
En el 7) para CE → C ⇒ contador (CE → C) = 0 En el 8) C ≡ C que si ∈ X+ ⇒ X+ = {CP,P,CE,G, {CP,P,CE,G,C,NE} C,NE} {CE,G,C,NE}
y
ACTUAL ACTUAL =
Volvemos al paso 4) y ahora ACTUAL = {C,NE} En el 5) ACTUAL = {C,NE} (eliminamos G) En el 6) lista (G) = {G → P} En el 7) para G → P ⇒ contador (G → P) = 0 En el 8) C ≡ P que si ∈ X+ ⇒ {CP,P,CE,G,C,NE} y ACTUAL = {C,NE} Volvemos al paso 4) y ahora ACTUAL = {C,NE} En el 5) ACTUAL = {NE} (eliminamos C) En el 6) lista (C) = {∅} Volvemos al paso 4) y ahora ACTUAL = {NE} En el 5) ACTUAL = {∅} (eliminamos NE) En el 6) lista (NE) = {NE → CE} En el 7) para NE → CE ⇒ contador ( NE → CE) = -1 Volvemos al paso 4) y ahora ACTUAL = { ∅} Lo que implica que X+ ≡ (CP,P) + = {CP,P,CE,G,C,NE}
Así puede verse que la idea principal en la que se basa esta algoritmo, es la de añadir la parte derecha de las dependencias al cierre sólo cuando se tiene la certeza de que todos los atributos que forman la parte izquierda pertenecen a dicho cierre. De esta forma, cada dependencia es accedida una sola vez, por por lo que la complejidad del del algoritmo como ya se ha comentado es de O(n).
Algoritmo de cálculo del recubrimiento minimal Antes de mostrar el algoritmo por completo es preciso aportar una serie de conceptos nuevos seguidos de procesos para la eliminación de atributos extraños y de dependencias redundantes, algoritmos estos en los que se apoya el del cálculo del recubrimiento minimal.
Nuevos conceptos • DepForLHS (X) DepForLHS (X)
= {X → A ∈ DF} no contiene dependencias triviales ni duplicadas.
• LHS (DX) = {X / DepForLHS (X) ≠ ∅} •
ro-atributo: A es ro-atributo si A aparece en la parte
derecha de las dependencias.
•
rl-atributo: B es rl-atributo si no es ro-atributo.
• RO x = {A / X →
A ∈ DF y A es ro-atributo} • RL x = {A / X → A ∈ DF y A es rl-atributo} • R x = ROx ∪ RLx El r-cierre de X respecto a un conjunto de dependencias G, lo representamos como X ^G y es el conjunto de todos los atributos A tales que Y → A pertenece a G e Y pertenece a X +G. Por lo tanto, X^G es el conjunto de todos los atributos de las partes derechas de las dependencias derivados de X respecto a G. Así pues es fácil ver que X ^G está incluido en X +G y los únicos atributos que pueden no encontrarse en X ^G son los que forman X. El r-ci r-cier erre re apor aporta ta más más info inform rmac ació iónn que que el cierr cierree tran transi sitiv tivoo de un desc descri ript ptor or y es especia especialmen lmente te útil útil para para la elimin eliminació aciónn de atribu atributos tos extrañ extraños os imp implica licado doss y depend dependenc encias ias redundantes. Pero como es lógico esto se ve mejor con un ejemplo, de forma que ahora la relación es: R ({CE, NE, P, CP, C}, DF) donde: DF = {CE,NE → P, P → CP, NE → C, C → CP} Para hacer coincidir teoría y práctica vamos a hacer que DF ≡ G y que X ≡ (CE,NE), cuyo cierre transitivo hemos calculado previamente, de manera que:
X+G ≡ (CE,NE) +DF = {CE,NE,P,CP,C} Y volviendo a la teoría, recordamos que debemos buscar los atributos A tales que: Y → A ∈ G e Y ∈ X+G Empezamos por el primer atributo perteneciente a X+G, CE y vemos que no existe una dependencia tal que: CE → A ∈ G ( ≡ DF) lo que significa que ( por el estudio del atributo CE) CE ∉
X^G
Pasamos al siguiente, NE y vemos que existe una dependencia que cumplen la condición: NE → C ∈ G lo que significa que C ∈ X^G Seguimos con P y vemos que existe una dependencia: P → CP ∈ G lo que significa que que CP ∈ X^G El siguiente es CP y comprobamos que no existe: CP → A ∈ G (≡ DF) lo que significa que ( por por el estudio del atributo CP) CP ^ ∉ X G (sin embargo este ya estaba incluido cuando estudiamos el atributo P) El último es C y vemos que existe una dependencia: C → CP ∈ G lo que que significa significa que CP CP ∈ X^G (aunque eso ya lo sabíamos al estudiar P) De esta manera queda que:
X^G ≡ (CE,NE) ^DF = {CP,C}
Atributos extraños Se pueden dividir en dos tipos:
Implicados
•
B es un atributo extraño implicado en la dependencia X → A, si B es atributo extraño y además cumple que: si X = ZB, X ≠ B, entonces B pertenece a Z +DF. R ({CE, NE, P, CP, C}, DF)
donde:DF = {CE,NE
P, P
CP, NE
C, C
CP}
En la dependencia CE,NE,C → P el atributo C (≡ B) es extraño ya que CE,NE → P. Además si X = ZB (Z ≡ CE,NE y B ≡ C), X ≠ B (CE,NE,C ≠ C), debe cumplirse que: B ∈ Z+DF o lo que es lo mismo, que C ∈ CE,NE+DF, cosa que resulta ser cierta puesto que, como ya se resolvió en el apartado anterior CE,NE+DF = (CE,NE,P,CP,C).
No implicados
•
B es un atributo extraño no implicado en la dependencia X → A, si B es atributo extraño y además cumple que: si X = ZB, X ≠ B, entonces B no pertenece a Z +DF. La razón para una distinción así es que en una dependencia que contenga un atributo extraño no impl implic icad adoo se pued puedee afir afirma marr que, que, desp despué uéss de la elim elimin inac ación ión del del atri atribu buto to extra extraño ño,, la dependencia resultante es redundante.
Eliminación de atributos extraños La idea principal del algoritmo es eliminar todos los atributos extraños implicados para cada conjunto de dependencias con igual parte izquierda, de esta forma no se tratan dependencias individualmente. ;;------ENTRADAS----DF conjunto de dependencias funcionales elementales. ;;------SALIDAS----H, conjunto de dependencias sin atributos extraños implicados. ;;------MAIN----Para cada DepForLHS(X). Si |X| > 1
1)
Calcular r-cierre(X) = (X ∪ RLx)^DF
2)
Mientras |X| > 1 por cada B de X 2.1) Si B pertenece a X ∩ r-cierre(X) entonces X’ = X – B 2.2) Calcular X’+ DF 2.2) Si B pertenece a X’+ DF entonces X = X’
3)
Si X ha cambiado en el paso 2 Reemplazar X por el nuevo valor X’ en todas las dependencias de DepForLHS(X).
Ejemplo: Es preciso destacar que este será el que utilicemos durante todo el proceso, es decir, como ya se ha comentado, para ejecutar el algoritmo del cálculo del recubrimiento minimal es preciso eliminar del conjunto de dependencias los atributos extraños (cosa que haremos a
continuación) y posteriormente erradicar las dependencias redundantes (cosa que haremos en el siguiente subapartado, partiendo del resultado que obtengamos aquí). Una vez aclarado esto empecemos, dado el siguiente conjunto de dependencias DF: ABC → K AB → D
BN → H B→A
AB → E ABC → D
B→H AB → G
AB → F ABC → J
B→G D→A
Puesto que tendremos que tratar todas las DepForLHS(X) tal que |X| > 1, el listado sería el siguiente: DepForLHS(AB) DepForLHS(ABC) DepForLHS(BN) Empezamos por la primera: DepForLHS(AB). Calculamos el RLx ≡ RLAB y encontramos que existen 4 dependencias que tienen AB en la izqda. AB → E
AB → F
AB → D
AB → C
y que sólo D cumple que es rl-atributo, por lo que RLAB = D. Nos vamos al punto 1) y vemos que r-cierre (AB) = (AB ∪ D)^DF es igual (tras haberlo calculado) a {A, H, G}. Para Para el aparta apartado do 2) vemos vemos que sólo A puede puede ser ser un atribu atributo to extrañ extraño o implicado en X = AB ya que: A+ = {A}
y
B+ = {B, H, G, A}
y si nos vamos a la definición de atributo extraño implicado, sólo A ∈ B+DF, mientras que, por el contrario, B ∉ A+DF.. Nos vamos al punto 2.1) y comprobamos que A ∈ AB ∩ {A, H, G} ⇒ AB = AB – A = B Calculamos X’+ DF ≡ B+ DF = {B, H, G, A} y vemos que (apartado 2.3)) A ∈ B+ DF Por lo que según el apartado 3) debemos reemplazar AB por B en todas las DepForLHS(AB). Seguimos con: DepForLHS(ABC). En el apar aparta tado do 1) vemo vemos s que: que: r-ci r-cier erre re (ABC) (ABC) = (ABC (ABC ∪ D)^DF = {D,E,F,G,A,H} Para el apartado 2) vemos que sólo A puede ser un atributo extraño y A ∈ BC+DF, por lo tanto puede ser eliminado. Nos vamos al punto 2.1) y comprobamos que A ∈ ABC ∩ {D,E,F,G,A,H} ⇒ ABC = ABC – A = BC Calculamos X’+ DF ≡ BC+ DF = {B, C, H, G, A, D, J, K} y vemos que ( por por 2.3)) + A ∈ B DF Por lo que según el apartado 3) debemos reemplazar ABC por BC en todas las DepForLHS(ABC). Continuamos con: DepForLHS(BN). En el apartado 1) vemos que: r-cierre (BN) = (BN ∪ ∅ )^DF = {D,E,F,G,A,H} Para el apartado 2) vemos que ningún atributo puede ser atributo extraño implicado (N es un atributo extraño no implicado). Por lo que no se produce ningún cambio. Por lo tanto, el conjunto de dependencias resultantes, después de eliminar los atributos extraños implicados es:
BC → K B→D
BN → H B→A BC → D
B→E B→G
B→H BC → J
B→F D→A
Eliminación de dependencias dependencias redundantes El siguiente paso en el cálculo del recubrimiento minimal, tras la eliminación de los l os atributos extrañ extraños os es la supres supresión ión de las depend dependenc encias ias redund redundante antes, s, cuyo cuyo algori algoritmo tmo se detalla detalla a continuación:
;;--ENTRADA------DF conjunto de dependencias sin atributos extraños implicados. ;;--SALIDA------H recubrimiento minimal de DF. Proceso: 0)
H = DF
1)
Para cada DepForLHS(X)
2)
G = {H - DepForLHS(X)} crc(X) = ∅ Attr = X
3)
Para cada dependencia X → A de DepForLHS(X) Si A pertenece a crc(X) entonces borrar X → A de H si no Si A es un rl-atributo Attr = Attr ∪ {A} crc(X) = Attr ^G Si crc(X) = ∅ entonces crc(X) = X^G
4)
Para cada dependencia X → A de DepForLHS(X) ∩ H
5)
Si A pertenece a crc(X) Si A es ro-atributo ó Si A es rl-atributo y A pertenece a X+ respecto H – {X → A} entonces
Ejemplo: Como ya se ha comentado partimos del ejemplo que hemos empezado en el apartado anterior y al cual hemos librado de atributos extraños quedando el conjunto de dependencias DF como sigue: BC → K B→D D→A
BN → H B→A
B→ E BC → D
B→H B→G
B→F BC → J
En el apartado 0) hacemos H = DF y empezamos en el 1), así que para DepForLHS(B).
En el apar aparta tado do 2) vemo vemos s que que G = {H - DepF DepFor orLH LHS( S(B) B)} } por por lo que que elimin eliminam amos os de H todas todas las dependen dependencia cias s que tengan tengan a B como como único único atributo en la parte izqda. quedando: DepForLHS(B) = {B → D, B → A, B → E, B → H, B → F, B → G} G = {BC → D, BC → J, BC→ K, D → A, BN → H} crc(B) = ∅ y Attr = {B} Nos vamos vamos al punto punto 3) y para para cada cada depend dependenc encia ia de DepFo DepForLH rLHS(B S(B)) entramos en sus subapartados: Para B → D tenemos que D ∉ crc(B) y además D es rl-atributo, por lo que: Attr = {B} ∪ {D} y crc(B) = Attr^G = {A} Para B → A tenemos que A ∈ crc(B) por lo que dicha dependencia debe ser eliminada de H Para B → E tenemos que E ∉ crc(B) y como E no es rl-atributo y crc(B) ≠ ∅ ⇒ no debemos realizar ningún cambio. Para B → H tenemos que H ∉ crc(B) y como H no es rl-atributo y crc(B) ≠ ∅ ⇒ no debemos realizar ningún cambio. Para B → F tenemos que F ∉ crc(B) y como F no es rl-atributo y crc(B) ≠ ∅ ⇒ no debemos realizar ningún cambio. Para B → G tenemos que G ∉ crc(B) y como G no es rl-atributo y crc(B) ≠ ∅ ⇒ no debemos realizar ningún cambio. De forma que para el apartado 4) tenemos que: DepForLHS(B) ∩ H = {B → D, B → E, B → H, B → F, B → G} crc (B) = {A} En el apartado 5) observamos que no existe ninguna dependencia que cumpla la condición. Retornamos al apartado 1) con la siguiente: DepForLHS(BC). En el apartado 2) queda: DepForLHS(BC) = {BC → D, BC → J, BC→ K} G = {B → D, B → E, B → F, B → G, B → H, D → A, BN → H} crc(BC) = ∅
y Attr = {B, C}
Nos vamos al punto 3) y comprobamos que ninguna dependencia es eliminada quedando: crc(BC) = {D,E,F,G,H,A} De forma que para el apartado 4) tenemos que: DepForLHS(BC) ∩ H = DepForLHS(BC) En el apartado 5) sólo la dependencia BC → D es comprobada comprobada por si es redundante, para lo que es necesario calcular el cierre de BC respecto a H – {BC → D}, dando como resultado que es redundante y, por lo tanto, se elimina. Retornamos al apartado 1) con la siguiente: DepForLHS(BN). En el apartado 2) queda: DepForLHS(BN) = {BN → H}
G = {B → D, B → E, B → F, B → G, B → H, D → A, BC → J, BC → K} crc(BN) = ∅ y Attr = {B, N} Nos vamos al punto 3) y comprobamos que ninguna dependencia es eliminada quedando: crc(BN) = {D,E,F,G,H,A} De forma que para el apartado 4) tenemos que: DepForLHS(BN) ∩ H = DepForLHS(BN) En el apartado 5) sólo la dependencia BN → H es comprobada por si es redundante, y se elimina sin necesidad de calcular el cierre de BN ya que H es ro-atributo. Retornamos al apartado 1) con la siguiente: DepForLHS(D). En el apartado 2) queda: DepForLHS(D) = {D → A} G = {B → D, B → E, B → F, B → G, B → H, BN → H, BC → J, BC → K} crc(D) = ∅ y Attr = {D} Nos vamos al punto 3) y comprobamos que ninguna dependencia es eliminada quedando: crc(BN) = ∅ Los siguientes pasos no son necesarios puesto que crc(BN) = ∅. Por lo tanto, el conjunto de dependencias resultantes, después de eliminar las redundantes es: B→D B→G
B→E D→A
B→H BC → J
B→F BC → K
Además como se verá al exponer el cálculo del algoritmo de recubrimiento minimal, ya lo habremos obtenido con los pasos que hemos dado.
Algoritmo completo de cálculo de recubrimiento minimal El cual una vez vistos los anteriores resulta tremendamente sencillo: ;;---ENTRADA---DF conjunto de dependencias elementales. ;;---SALIDA---H recubrimiento minimal de DF. ;;---MAIN---1) Aplicar el algoritmo de eliminación de atributos extraños implicados. 2) Reconstruir los conjuntos DepForLHS(X), eliminando dependencias duplicadas.
3) Aplicar el algoritmo para eliminar las dependencias redundantes.
Algoritmo que hemos ido explicando con un ejemplo al que le hemos ido aplicando los diferentes apartados, de forma que, basta con retroceder hasta el punto “Eliminación de atributos extraños” para seguirlo con ayuda del ejemplo que ahí exponemos.
Algoritmo de determinación de claves Se basa en la idea de hacer que las superclaves contenidas en un conjunto de dependencias pasen a ser mínimas y, por lo tanto, se conviertan en claves. Sin embargo, antes de comenzar con la explicación es necesario explicar lo que es una:
Matriz de implicación Se emplea para representar un conjunto de dependencias y se construye de la siguiente forma: Dado el esquema R (A, DF), DF el cto. de dependencias funcionales formado por {X i → Yi}, el conjunto DF puede representarse mediante una matriz M en la que las columnas serían los elementos de A y las filas las X i de DF. De tal forma que un elemento m ij es: 1 si A i pertenece a (X i ∪ Yi) 0 si Ai no pertenece a (X i ∪ Yi) De manera que, sea el siguiente esquema de relación: R (A, B, C, D, E, G) donde AB → C D→G
BC → D CE → G
BE → C
CG → B
C→ A
D→E
La matriz de implicación correspondiente sería:
M:
A
B
C
D
E
F
AB
1
1
1
0
0
0
BC
0
1
1
1
0
0
BE
0
1
1
0
1
0
CG
0
1
1
0
0
1
CE
0
0
1
0
1
1
C
1
0
1
0
0
0
D
0
0
0
1
1
1
Puesto que A,B,C ∈ AB → C (Xi
El cierre transitivo de M (M +), se calcula de la siguiente forma:
1) M+ = M 2) Repetir hasta que M + no cambie
∪ Yi)
Para todo Xi ≠ X j de M+ Si para todo A k de X j mij = 1 entonces Copiar todas las entradas a ‘1’ de la fila X i en los lugares homólogos de la fila . X j Y siguiendo el algoritmo obtenemos M +: M:
A
B
C
D
E
F
AB
1
1
1
1
1
1
BC
1
1
1
1
1
1
BE
1
1
1
1
1
1
CG
1
1
1
1
1
1
CE
1
1
1
1
1
1
C
1
0
1
0
0
0
D
0
0
0
1
1
1
Y ahor ahoraa sí, sí, tras tras este este nece necesa sari rioo incis inciso, o, pasa pasamo moss a la expl explica icaci ción ón del del algo algori ritmo tmo de determinación de claves:
;;--ENTRADA-------
R (A, DF) esquema de relación. ;;--SALIDA
{K i}n conjunto de claves del esquema. ;;--MAIN---
1) 2)
Calcular M+, a partir del conjunto de dependencias DF.
3)
Construir M1
M1 = ∅ M1 = {X i ∪ Yi} para i = 1 … m donde Yi son los atributos con entrada a ‘0’ en la fila i
4)
Si con |Yi| < 2, |Y j| < 2 se tiene que (Xi ∪ Yi) ⊆ (X j ∪ Y j) para i ≠ j, borrar la entrada (X j ∪ Y j) de M1.
5)
Si para las demás entradas de M1, |Y j| < 2, el algoritmo concluye, M1 contiene todas las claves . En caso contrario:
6)
Para todo i, con |Yi| ≥ 2 calcular aij = Yi ∩ (X j ∪ Y j) para todo i ≠ j y |Y j| ≥ 0
7) 8)
Para todo i, borrar ai1 si ai1 ≥ aij con j ≠ 1 Sustituir las entradas (X i ∪ Yi) con |Yi| > 2 por los nuevos (X i ∪ aij)
Para el ejemplo vamos a emplear el esquema de relación utilizado para explicar la matriz de implicación, puesto que ya hemos calculado el valor de M +:
De manera que en el paso 2) haremos M1 = ∅. Y en el 3) tenemos que M1 = {AB, BC, BE, CG, CE, C ∪ BDEG, D ∪ ABC} Pasamos directamente al apartado 6) y vemos que: G
a61 = B a65 = E a73 = B
a62 = B a67 = BD a74 = C
63 = BE a71 = AB a75 = C
a64 = a72 = BC BC a76 = CB
En el paso 7) se eliminan por ser superconjuntos: a62, a63, a67, a71, a72, a75, a76 De tal forma que en el paso 8) M1 = {AB, BC, BE, CG, CE, CB, CG, CE, DB, DC} Y en el apar aparta tado do 9) elimin eliminam amos os los superc superconj onjunt untos, os, quedan quedando do el M1 definitivo:
{ AB, BC, BE, CG, CE, DB, DC }
Algoritmos de normalización normalización Estos algoritmos proponen un refinamiento de los esquemas relaciónales en base a las dependencias funcionales. Pueden ser de dos tipos: De Síntesis: ensamblan esquemas relacionales en 3FN agrupando atributos afines. Veremos el algoritmo propuesto por Bernstein. Bernstein. Descomposición: rompen los esquemas relacionales relacionales en De Descomposición: proyecciones independientes, para obtener esquemas relacionales en FNBC (aunque no siempre, este es el objetivo). Veremos algoritmos para determinar la forma normal del esquema relacional ( 2FN, 3FN, FNBC), FNBC), para descomposición de esquemas relacionales en FNBC sin pérdida, par paraa sabe saberr si las las proy proyec ecci cion ones es de una una desc descom ompo posi sici ción ón son son SPI (sist (sistema emass de proyecciones independientes mediante el algoritmo de ULLMAN) ULLMAN) y para saber si tras la descomposición se conservan las Dependencias Funcionales
ALGORITMO DE SINTESIS BERSTEIN (1976) propone como alternativa el proceso de descomposición. A partir de un conjunto de dependencias y un conjunto de atributos, construye relaciones de manera que: • todas las relaciones estén en 3NF ;;--ENTRADA------• el conjunto de relaciones sea mínimo. DF conjunto de dependencias funcionales.
El algoritmo es el siguiente: ;;--SALIDA------R (Ai, DFi) conjunto de esquemas en 3FN. ;;--MAIN------1)
Calcular el recubrimiento minimal H de DF aplicando el algoritmo anterior y almacenar todos los crc(X) para todo X.
2)
Agrupar las dependencias con igual parte izquierda (construir DepForLHS(X), para todo X).
3)
Reagrupar las dependencias. J=∅ Por cada implicante X que cumpla: X ∩ (X ∪ RLx)^G ≠
∅
determinar si X tiene una parte izquierda equivalente en H, es decir, si existe un Y que cumpla: Y ⊂ Y+DF, Y ⊂ X+DF Si se encuentra un implicante Y equivalente Agrupar los grupos de dependencias de X e Y en uno sólo. Añadir las dependencias X →Y, Y → X a J Borrar de H las dependencias X → A, si A ertenece a Y
4)
Eliminar dependencias redundantes. Por cada dependencia X → A de H Si A es un rl-atributo y cumple que A pertenece a (X ∪ RLx)^G (o lo que es lo mismo A pertenece a crc(X)) Comprobar si X → A es redundante en H ∪ J, es decir, calcular el cierre de X respecto a (H A}.
∪
J) – {X →
Si A pertenece a X+. Eliminar la dependencia X → A de H. Añadir cada dependencia de J a su grupo correspondiente. 5)
Formar relaciones. Cada grupo de dependencias forma una relación en 3FN, donde el conjunto de atributos de cada relación es
Ejemplo: Partiendo del conjunto de dependencias conseguido en el apartado anterior ya tendríamos cubierto el primer punto del algoritmo, por lo que no es necesario calcular el recubrimiento minimal, que sería este: B→D B→G
B→E D→A
B→ H BC → J
B→ F BC → K
En el apartado 2) construimos todos los DepForLHS(X): DepForLHS (B) = {B → D, B → E, B → H, B → F, B → G} DepForLHS (D) = {D → A} DepForLHS (BC) = {BC → J, BC→ K} Nos Nos vamo vamos s al apar aparta tado do 3), hacemos J = ∅ y realiz realizamo amos s la siguie siguiente nte comprobación: X ∩ (X ∪ RLx)^G ≠ ∅ de tal forma que: (B ∪ RLB)^G = {D,E,H,F,G} ⇒ B ∩ (B ∪ RLB)^G = ∅ (D ∪ RLD)^G = {A} ⇒ D ∩ (D ∪ RLD)^G = ∅ (BC ∪ RLBC)^G = {J,K} ⇒ BC ∩ (BC ∪ RLBC)^G = ∅ En el apartado 4) comprobamos que no existe ninguna relación X → A de H, en la cual A sea un rl-atributo y además se verifique que A pertenece a (X ∪ RLx)^G Y ya en el punto 5) se nos dice que cada grupo de dependencias (las distintas DepF DepFor orLH LHS( S(X) X))) form forman an rela relaci cion ones es en 3FN, 3FN, por por lo que, que, en este este caso caso,, el resu result ltad ado o fina finall coin coinci cide de con con el conj conjun unto to de depe depend nden enci cias as prop propue uest stas as inicialmente.
ALGORITMOS DE DESCOMPOSICIÓN Vamos a usar la descomposición como herramienta para normalizar los esquemas de relación en este caso. Vamos por tanto a ramificar esta clase de de algoritmos en tres tipos: •
determinan en que forma normal se encuentran los esquemas de relación.
•
descomponen un esquema de relación no óptimo en esquemas FNBC.
•
analizan si la descomposición fue sin pérdidas.
Algoritmos que determinan la forma normal en la que se encuentra un esquema de relación. En esta sección veremos algunos algoritmos que sirven para determinar la forma normal de un esquema relacional. Van a ser tres algoritmos de determinación determinación de forma normal; el primero comprobará si el algoritmo se encuentra en 2FN, el segundo comprobará si el esquema relacional está en 3FN y por último un tercer algoritmo que determinará si el algoritmo se encuentra en FNBC.
Determinación de 2NF Como ya sabemos, un esquema de relación R(AT,DEP) se encuentra en segunda forma normal si además de estar en 1NF, cada atributo no principal tiene dependencia funcional completa respecto de cada una de las claves de la relación. El algoritmo de determinación de 2NF se basa den la idea de que un esquema de relación no se encuentra en 2FN, 2FN , en cuanto que exista algún subconjunto propio de la(s) clave(s) del esquema en cuyo cierre transitivo aparezcan atributos no principales. El algoritmo generará todos los posibles subconjuntos de las claves candidatas, calculará su cierre transitivo y comprobará si en ese cierre transitivo transitivo existen atributos no principales. En caso de que en uno de los cierres transitivos calculados existan atributos no principales el algoritmo devolverá como respuesta que el esquema relacional no se encuentra en 2NF. En caso contrario seguirá comprobando cada uno de los cierres transitivos de los subconjuntos de la clave hasta encontrar un cierre transitivo donde se cumpla que ese cierre transitivo calculado contiene atributos no principales o hasta comprobar que para todos los subconjuntos de la clave ninguno de sus cierres transitivos contiene atributos no principales. Esta solución es bastante ineficiente como se puede demostrar fácilmente. Por ejemplo, si tuviéramos una clave candidata compuesta de 2 atributos, habría que calcular tan solo el cierre transitivo para dos atributos, los dos atributos que componen la clave candidata, puesto que el número de combinaciones sin repetición de 2
elementos tomados de 1 en 1 (puesto que quiero seleccionar solo los subconjuntos de la clave para ser comprobados, no la clave entera). Si en lugar de 2, la clave candidata tuviera 3 atributos, habría que calcular el cierre transitivo para 5 subconjuntos de la clave, es decir: C3,2 + C3,1 = 2 + 3 = 5 siendo Cm,k las combinaciones sin repetición de m elementos tomados de k en k. En el ejemplo anterior tenemos 2 conjuntos posibles de C3,2, puesto que son las combinaciones posibles sin repetición de 3 elementos tomados de dos en dos. Si la clave candidata estuviera conformada por 4 atributos, tendríamos que: C4,3 + C4,2 + C4,1 = 4 + 6 + 4 = 14 Por ejemplo, supongamos que tenemos la siguiente clave candidata: CC{A,B,C,D} serían:
Las combinaciones sin repetición que podríamos hacer de esta clave candidata C4,3
{A, B, C} {A, B, D}
{A, C, D} {B, C, D}
C4,2
{A, B} {A, C}
{A, D} {B, C}
C4,1
{A}
{B}
{C}
{B, D} {C, D}
{D}
Para cada una de estas combinaciones tendríamos que calcular el cierre transitivo y comprobar si hay atributos no principales en él. Con este último ejemplo, en el caso peor habría que ejecutar 14 cierres transitivos si en ninguno de los cierres anteriores hubieran aparecido atributos no principales. Es decir, que el tiempo que tarda en ejecutarse el algoritmo aumenta en los peores casos de forma exponencial. Para aliviar un poco esta carga algorítmica, se realizarán antes de empezar a calcular los cierres transitivos unas comprobaciones sencillas que determinan automáticamente si el esquema está o no en 2FN. Las comprobaciones previas son las siguientes: Si existe algún atributo que no es implicado ni implicante de ninguna dependencia, entonces el esquema no está en 2FN (paso 0 del algoritmo).
Si el conjunto Q de atributos no principales es vacío, entonces el esquema de relación está en 2FN (paso 5 del algoritmo).
Si todas la claves del esquema de relación tienen un solo atributo, entonces el esquema está en 2FN (paso 6 del algoritmo). algoritmo).
El algoritmo tendrá la siguiente forma:
ALGORITMO 2NF ;;------ENTRADA -----Un esquema de relación R(AT,DEP). ;;-------SALIDA---------- N(R). Forma Normal en la que está un esquema de relación. ;;------MAIN-----------0.- Si (U Xi,Yi )i= 1..n ⊂ AT entonces /* Si el conjunto unión de todos los implicados y los implicantes no son la totalidad de los ⊂ atributos (es decir, están contenidos, , en AT, pero no son todos los atributos que contiene el conjunto AT, lo que se indicaría con el símbolo ⊆ )*/
N(R)=1 Fin del algoritmo Fin_si 1.- DEP = Recubrimiento irredundante (DEP) 2,. N(R) = 2 3.- Obtener CLAVES 4.- Obtener los conjuntos P (atributos principales) y Q (atributos no principales) 5.- Si Q = Ø entonces Fin del algoritmo Fin_si 6.- Si (número de atributos de cada una de las claves es 1) entonces k = nº atributos de la clave C. Para j=k-1...1 hacer Mientras hay subconjuntos de C de longitud j Generar SUBj (subconjunto de longitud j). CIERRE = SUBj+DEP Si (CIERRE ∩ Q ≠ Ø) entonces /* Si el conjunto resultado de la intersección entre el cierre transitivo y el conjunto de atributos no principales es no nulo, es decir, en el c ierre están contenidos atributos no principales, no se encontrará el esquema relacional en 2NF, y podemos dar por finalizado el algoritmo*/ N(R) = 1. Fin del algoritmo Fin_si Fin_mientras Fin_para Fin ara cada clave
Como ejemplo de ejecución podemos poner la salida del algoritmo con el esquema de relación R(AT,DEP) donde: AT= {A,F,B,G,C,H,D,I,E} DEP= {A → F, F → A, B → G, G → B, C → H, H → C, D → I, I → D, ABCD→E} El paso 0 no se cumple, ya que todos los atributos pertenecen a un implicado o a un implicante, por lo tanto, el algoritmo continúa. En el paso 1 se calcula el recubrimiento irredundante del conjunto DEP, la salida es el propio conjunto DEP. Del paso 3 se obtienen 16 claves candidatas de este esquema, que son: CC = {ABCD,ABCI,ABHD,ABHI,AGCD,AGCI,AGHD,AGHI,FBCD,F {ABCD,ABCI,ABHD,ABHI, AGCD,AGCI,AGHD,AGHI,FBCD,FBCI,FBHD,FBHI,F BCI,FBHD,FBHI,F GCD,FGCO,FGHD,FGHI} En el paso 4 se calculan los conjuntos P y Q que son: P = {A, F, B, G, C, H, D, I} Q = {E} La condición impuesta en el paso 5 no se cumple, el conjunto Q de atributos no principales es no vacío, por lo tanto, el algoritmo continúa. La condición impuesta en el paso 6 tampoco se cumple, las claves candidatas del esquema de relación tienen más de un atributo, por lo tanto, el algoritmo continúa En el paso7 se generan los subconjuntos de cada clave. Para la primera de ellas, habría que calcular 14 cierres transitivos (C4,3 + C4,2 + C4,1). Para el resto de las claves, y puesto que las claves están solapadas, no hay que calcular los 14 cierres por cada una de ellas, puesto que algunos de ellos ya habrán sido generados y comprobados con la clave anterior.
En realidad sólo sería necesario hacer las comprobaciones para los subconjuntos de una única clave, ya que el resto de los atributos principales son equivalentes a los que forman parte de la clave. No se encuentra ningún subconjunto de las claves en cuyo cierre aparezcan atributos no principales. El algoritmo finaliza y el esquema de relación evaluado está en 2FN.
Determinación de 3FN Antes de meternos a explicar el algoritmo para determinar si un modelo relacional relacional está en 3NF recordaremos la definición definición de tercera forma normal: Para que un esquema relacional R(AT, DEP) se encuentre en 3NF se ha de cumplir que esté en 2NF, y que cualquier atributo no principal del esquema relacional esté implicado no transitivamente por una clave candidata. Un esquema relacional no estará en 3NF si no se cumple una de las dos siguientes condiciones:
No se encuentra en 2NF, es decir, existe algún atributo que no depende de forma completa de la clave. Posee algún atributo que depende transitivamente de alguna de sus claves.
ALGORITMO 3NF
El algoritmo que se expondrá a continuación está basado en la definición
;;--------ENTRADA-------anterior. Este algoritmo comproba rá a la vezDEP) si el esquema se encuentra en 2NF Un comprobará esquema de relación R(AT,
3NF.
;;----------SALIDA----------“Sí” o “No” para indicar si el esquema está o no en 3FN.
El algoritmo es el siguiente:
;;----------MAIN-------------1.- DEP = Recubrimiento_irredundante 2.- Calcular claves de R(AT, DEP)
3.- P = conjunto de atributos principales Q= conjunto de atributos no principales RESULTADO = SI 4.- Para toda X → Y ∈ DEP Si X no es superclave entonces Si Y ∈ Q
RESULTADO = NO Fin del algoritmo
Fin_si Fin_para_todo
Fin_si
y en
La salida del algoritmo para el siguiente esquema relacional es: Entrada: AT = {A, B, C, D, E} DEP = {AB → C, A→D, D → A, C → E} En el paso 1 se calcula el recubrimiento irredundante del conjunto DEP, la salida es el propio conjunto DEP. En el paso 2 se calculan las claves del esquema, que son AB Y DB. En el paso 3 se calculan los conjuntos de atributos principales y no principales, que son: P = {A, B, D} y Q = {C, E} Analizando cada una de las dependencias del esquema, vemos que para la dependencia C → E, se cumple que el implicante C no es clave (o superclave) y el atributo E es no principal. Por lo tanto, se encuentra una dependencia que viola la definición definición de 3FN. El esquema no está en 3FN.
Determinación de FNBC Un esquema relacional está en FNBC si todo determinante de ese esquema relacional es una clave candidata del mismo. Por lo tanto, en un esquema FNBC las únicas dependencias no triviales que se pueden dar (recordamos que las dependencias triviales son las dependencias en las que el atributo implicado es un subconjunto del conjunto de atributos que lo implican, normalmente, estas dependencias son implícitas al esquema y no se tienen en cuenta en la normalización) son aquellas en las que el determinante sea una clave candidata.
Ullman (1982) describió un algoritmo para determinar determinar si un esquema relacional se encontraba en FNBC, pero este algoritmo calculaba cuáles eran claves candidatas del esquema para posteriormente determinar determinar si cada uno de los atributos implicados tenía como determinante una clave candidata, y como ya sabemos, el algoritmo para determinar cuáles son las claves candidatas es un algoritmo muy costoso. Es por ello que Manila (1992) propuso un nuevo algoritmo para determinar si un esquema relacional relacional estaba o no en FNBC que se basa en determinar si todo atributo no principal está determinado por una clave, pero se decidirá si un implicante es una clave candidata si su cierre transitivo es el conjunto de todos los atributos del esquema, que en definitiva, es la definición de clave candidata. El algoritmo es el siguiente:
ALGORITMO FNBC ;;--------ENTRADA-------Un esquema de relación R(AT,DEP) ;;--------SALIDA-------Una decisión sobre si el esquema de relación está o no en FNBC. ;;--------MAIN-------0.- DEP = Recubrimiento irredundante. 1. RESULTADO = SI 2. Para toda X → Y de DEP CIERRE = X+DEP. Si (CIERRE ∩ AT) ≠ AT RESULTADO = ‘NO’ Fin del algoritmo
La complejidad de este algoritmo es polinomial al número de dependencia definidas en el esquema. Como se puede ver, no se calculan las claves sino los cierres transitivos de los determinantes. Este es un algoritmo bastante sencillo de determinación de forma normal de Boyce Codd, ya que lo único que hace es calcular el cierre transitivo de los determinantes para comprobar que son claves candidatas. Si lo son, el esquema se encontrará en BCNF. En caso de que algún determinante no posea en su cierre transitivo a todos los atributos del esquema, el esquema no se encontrará en BCNF.
ALGORI ALGORITMO TMOSS DE DESCOM DESCOMPOS POSICI ICIÓN ÓN DE UN ESQUEM ESQUEMA A DE RELACIÓN EN ESQUEMAS EN FNBC.
Descomposición en esquemas FNBC. El algoritmo de descomposición que se presenta a continuación es el algoritmo propuesto por Manila (1992). En él vamos a analizar un esquema relacional. relacional. Si existen dependencias que no cumplen la definición, proyectaremos el esquema en otros dos esquemas relacionales. A continuación seguiremos aplicando iterativamente este algoritmo a cada uno de los esquemas resultantes para seguir proyectándolos si hiciera falta.
ALGORITMO DESC_1 ;;------ENTRADA -----Esquema de relación R = (AT,DEP) ;;------SALIDA -----ESQ = R1..Rn conjunto de esquemas de relación en FNBC.. ;;------MAIN -----0)
Si (R (R est estáá en FNB FNBC) C) ent enton once cess ESQ = (R). Fin del algoritmo Fin_si
1)
ESQ = {}
2)
DEP = recubri recubrimie miento_ nto_irr irredud edudant ante(D e(DEP) EP).. Calcular las claves del esquema DEP-
3)
Mientras (existan dependencias X → Y ∈ DEP | X no es superclave ) 3.1 ATi = X U Y 3.2 AT = AT – Y 3.3 PR i = Proyección de DEP sobre ATi 3.4 DEP = Proyección de DEP sobre AT 3.5 R i = (ATi, PR i) 3.6 ESQ = ESQ U {R i}
Fin_mientras
El algoritmo finalizará cuando todos los esquemas generados estén en FNBC. Puede observarse que en el caso de que existan varias dependencias que violan la FNBC (paso 3), el algoritmo no dice nada acerca de cuál es la dependencia que se debe elegir y, por tanto, se puede elegir cualquiera. Más adelante veremos que según cual sea la
dependencia elegida en cada momento, la descomposición final será distinta, siendo en unos casos mejor que en otros. Podemos ver en el algoritmo expuesto como aplicamos Proyecciones de DEP sobre el conjunto de atributos AT i. En la siguiente sección veremos un algoritmo que explica como realizar esta proyección. proyección.
Proyección de un conjunto de dependencias sobre un conjunto de atributos. Cuando hacemos una proyección proyección de un esquema relacional relacional en otros dos, es tan importante saber cuáles son los atributos que conforman los dos nuevos esquemas como las dependencias asociadas a éstos. Al conjunto de dependencias de cada uno de los nuevos esquemas de relación proyectados se le conoce como proyección del conjunto DEP de dependencias de partida sobre el conjunto de atributos X del nuevo esquema. Definición: La proyección de un conjunto DEP de dependencias funcionales sobre un conjunto de atributos X, denotado como DEP[X] es el conjunto de dependencias Y de DEP para las que se cumple que YZ ⊆ X. Es decir: DEP[X] = {Y → Z | DEP|= Y → Z y YZ
⊆
→Z
X}
Es decir, para que una dependencia funcional que pertenezca al conjunto DEP, pertenezca a la proyección del conjunto DEP sobre otro conjunto de atributos X, tanto su implicante como su implicado tienen que pertenecer al conjunto X. Dicho de otra forma, todos los atributos que participan en esa dependencia deben pertenecer al conjunto X.
ALGORITMO DE PROYECCION
Una vez definida la proyección, vamos a ver el algoritmo propuesto ;;------ENTRADA -----Un conjunto DEP de (1992) para calcularlo. calcularlo. dependencias funcionales sobre un conjunto AT de atributos. Un subconjunto X ⊆ AT. ;;------SALIDA-----Un recubrimiento irredundante (DEP). ;;-------MAIN -----1) 2)
3)
G = Recu Recubri brimi mient entoo irred irredund undan ante te (DE (DEP) P) W = A T – X. Mientras (W ≠ Ø) 3.1) A = cualquier atributo de W. 3.2) W = W – A 3.3) H = {ZY → B | las dependencias Z,A → B Y Y → A están en G}. 3.4) Eliminar las dependencias triviales de H. 3.5) G = G – {f ∈ G | A ocurre en f} U H Fin_mientras
por Manila
Veamos el siguiente ejemplo de ejecución de este algoritmo para la proyección. AT = {C, D, E, I, J, K, L} DEP = {C → D, E → J, I → J, J → K, K → J, DK → L} La proyección de DEP sobre X = {C, E, I, L} se calcula como sigue: 1) G = {C → D, E → J, I → J, J → K, K → J, DK → L} 2) W = {D, J, J, K} K} 3) Mie Mientras ras (W ≠ Ø) 1ª Iteración A=D W = {J, K} H = {CK → L} G = G – {C → D, DK → L} U {CK → L} 2ª Iteración A=J W = K H = {I → K, E → K} G = G – {E → J, I → J, J → K, K → J } U {I → K, E → K} 3ª Iteración A = K W = {} H = {CI → L, CE → L} G = G – { CK → L , I → K, E → K} U {CI → L, CE → L} 4) DEP[ DEP[C, C, E, I, L] = {CI {CI → L, CE → L} El algoritmo finaliza finaliza después de |AT| - |X|
Algoritmo de descomposición de esquemas FNBC que mejora la eficiencia. Manila (1992) propone una mejora en la eficiencia del algoritmo consistente en considerar del conjunto de dependencias DEP sólo aquellas que realmente intervienen en el cálculo de la proyección. La determinación de este conjunto está basada en el concepto de antecedentes de un descriptor. Definición: Se el esquema de relación R(AT,DEP) y sea X AT. Se definen los antecedentes de X y se denota como X -DEP el conjunto de atributos de AT, que pueden ser usados para derivar una dependencia donde algún conjunto de estos atributos determina un atributo de X. El cálculo de este conjunto se define iterativamente de la siguiente forma: 1) Asignar a un conjunto inicial X, el conjunto de atributos atributos del que queremos queremos determinar sus antecedentes. 2) Mientras Mientras el conjunto conjunto de atrib atributos utos X i-1 obtenidos en la anterior iteración no sea igual al conjunto de atributos obtenidos en la iteración actual, X i, el proceso seguirá. Lo que se realizará en la iteración será asignarle al conjunto de atributos que ya tenemos, X i, los atributos del conjunto AT que impliquen a algún subconjunto de atributos del conjunto X i. En el siguiente ejemplo se puede ver fácilmente lo que son los antecedentes. Sea el esquema de relación R(AT,DEP) donde: AT = {A, B, C, D, E, F} DEP = {A → B, C → D, B,D → E, E → F} El cálculo de los antecedentes del atributo E (E -) será: E0- = {E} E1- = {E}U{B,D} E2- = {E,B,D} U{A,C} E3- = E2- = {E,B,D,A,C} Podemos ver como a partir de la iteración nº 3 el conjunto E - ya no se modificará más. Es por eso que a partir de la iteración 3 ya no hará falta que sigamos calculando los antecedentes.
Basado en el concepto de antecedentes de un descriptor, se puede afirmar que para calcular un recubrimiento de DEP[X] basta con considerar sólo las dependencias de DEP de la forma Y → B tales que para algún Z con B ∈ Z y Y → Z ∈ DEP, se cumple que YB ⊆ X+DEP ∩ X-DEP. Por lo tanto en el algoritmo PROY se incluye un paso inicial que es la selección del conjunto de dependencias que realmente interviene en el cálculo de la proyección, evitando así comprobar las dependencias que no aportan nada al cálculo. A continuación veremos un ejemplo de descomposición para el algoritmo de descomposición a FNBC visto antes. Como ya sabemos, no siempre que descomponemos un esquema relacional hasta la forma normal FNBC podremos conservar las dependencias funcionales, funcionales, aunque sí que conservaremos toda la información. Si tenemos el siguiente esquema de relación R(AT,DEP): AT = {A, B, C, D, E, F, X} DEP = {A → X, X → A, AB → C, AB → D, D → E, E → F} En el paso 2 del algoritmo se calcula el recubrimiento irredundante del conjunto DEP, el resultado es el propio conjunto DEP. Las claves de este esquema son AB y BX. Existen en este esquema varias dependencias cuyo implicante no es superclave. Éstas son: A → X, X → A, D → E y E → F. A continuación comenzamos la descomposición del esquema por cualquiera de las dependencias citadas. La única restricción que impone el algoritmo antes descrito para elegir la dependencia funcional es la de que el implicante de la dependencia elegida no sea superclave del esquema (ya que cumpliría las restricciones de la forma normal de Boyce-Codd). Vamos a comenzar por la dependencia D → E. Los esquemas resultantes serán: R1 (ATR(AT,DEP) 1, DEP1) R2(AT2, DEP2) AT1 =AT {D=, {A, E} B, C, D, E, F, X} AT2 = {A, B, C, D, F, X} DEP1 DEP = {D= → } X, X → A, AB → C, AB DE→PD, 2 =D {→AE,→E X, X → A, AB → C, → F} {AE→ AB → D, D → F} R2(AT2,DEP2) R1(AT1,DEP1) Ahora, tendremos dos esquemas de relación, R1 y R2. El esquema R1 estará en AT2 = {A, B, C, F, X} AT1pero = {D,elE esquema } BCNF R2 tendrá descriptores queD,no son claves del esquema. → → A, AB → C, AB → D, D → F} DEP2 = {A X, X → E} DEP1 = {D Continuaremos el proceso de descomposición con el esquema R2.
El proceso seguido se puede ver en la siguiente figura:
R3(AT3,DEP3) AT3 = { D, F} DEP3 = {D → F}
R5(AT5,DEP5) AT5 = {A, X} DEP5 = {A → X, X → A}
R4(AT4,DEP4) AT4 = {A, B, C, D, X} DEP4 = {A → X, X → A, AB → C, AB → D}
R6(AT6,DEP6) AT6 = {A, B, C, D } DEP6 = { AB → C, AB → D}
El esquema R2 no está en BCNF, por lo que volvemos a descomponer en R3 y en R4. Podemos elegir entre las siguientes dependencias, una para realizar la proyección: {A → X, X → A, D → F} Elegimos, por ejemplo la dependencia D →F para llevar a cabo la descomposición en los esquemas de relación R3 y r4 como se muestra en la figura anterior. El esquema R3 ya está en FNBC, pero el esquema R4 no. Teníamos dos opciones, elegir A → X o X→ A. Elegimos A → X, el esquema R4 se descompone como se ve en la figura anterior. De la descomposición de R4 aparecen la R5 y la R6. Estas dos últimas descomposiciones descomposiciones se encontrarán en la forma normal de Boyce-Codd. La descomposición descomposición será sin pérdida de información (SPI), pero la dependencia E → F, se ha perdido en la descomposición. Y ¿no existirá ninguna otra descomposición que no provoque pérdidas de dependencias funcionales? Como ya sabemos, pasar a la forma FNBC conlleva el riesgo de perder dependencias funcionales, aunque no información. Aunque más adelante veremos que, aunque no siempre se puede pasar a la forma normal de Boyce-Codd sin la pérdida de dependencias funcionales, hay algunos casos en los que escogiendo en otro orden las dependencias para realizar la descomposición, se puede llegar a esquemas FNBC que no hayan sufrido la pérdida de dependencias.
Nuevo algoritmo de descomposición que mejora la funcionalidad. Antes hemos visto como descomponíamos un esquema en varios esquemas BCNF. En esa descomposición perdíamos la dependencia E → F. En esta sección de los apuntes, veremos que hacer para que, en la medida de lo posible podamos solucionar solucionar el problema de la pérdida de dependencias funcionales y qué análisis previo debemos hacer del esquema para averiguar por donde deberíamos empezar a descompones.
Como veíamos antes, en el algoritmo DESC_1, que era el algoritmo de descomposición descomposición de un esquema relacional, relacional, para descomponer un esquema relacional en varios esquema relacionales escogíamos de entre un grupo de dependencias que no cumplieran la restricción restricción de FNBC una dependencia al azar para empezar a descomponer. En este caso vamos a intentar seguir unos criterios de selección de dependencias para intentar evitar en la medida de lo posible la pérdida de dependencias funcionales al descomponer descomponer un esquema relacional relacional en un esquema relacional en FNBC. Los criterios que vamos a imponer para evitar que se produzca pérdida de semántica en una descomposición afectan a dos grupos de dependencias. Éstos son: a) Dependen Dependencias cias que definen definen equivale equivalencia ncia entre entre atributos atributos no principale principales. s. Sea R(AT,DEP) un esquema de relación: AT = {CT, CA, NA, DT, E, I, I , O, HO} DEP = {CT → CA, CA → CT, CT → NA, NA → CT, CT → DT, DT → CT, E → NA, I → O, EI → HO, A → B, B → C, C → D, D → C} Los atributos equivalentes son CT, CA, NA y DT. Dichos atributos son no principales, pues la clave del esquema es I,D,E y además son implicados en otras dependencias. Podríamos elegir por pasos sucesivos las dependencias que definen la equivalencia equivalencia de atributos (por ejemplo CT →CA, CT→ NA, CT→DT) durante cada fase del proceso de descomposición. Cada vez que vayamos a descomponer el esquema relacional relacional tendremos que eliminar el atributo implicado en la dependencia dependencia a partir de la que queremos descomponer el esquema del esquema relacional. Para ello tendremos que renombrar, en las dependencias en las que aparezca este atributo en el esquema relacional principal, por otro atributo equivalente a éste. Así seguiríamos sucesivamente para todas estas dependencias, hasta que al final lleguemos a la última de estas dependencias (CT →DT) en la que nos encontramos que todas las dependencias cuyo implicado era alguno de estos atributos equivalentes, tendrán ahora el mismo atributo como implicado debido a los renombramientos sucesivos que ha sufrido. Este atributo que aparece en todas estas dependencias es el atributo que vamos a descomponer, por lo tanto tendremos que desaparecerán aquellas dependencias en las cuales aparecía este atributo. Para arreglar este problema, la propuesta es realizar una única descomposición, en lugar de varias sucesivas, en la que en la descomposición obtengamos dos esquemas relacionales en los que en el primer esquema relacional tengamos, no sólo los atributos de la dependencia por la que se descompone, sino todos los atributos equivalentes con las dependencias que lo definen. De esta forma, para nuestro ejemplo tendríamos para la primera de estas dependencias dependencias (CT→CA) n primer esquema relacional relacional formado por los atributos CT y
CA y por los equivalentes a éstos, DT y NA, y por las dependencias funcionales: { CT → CA, CA → CT, CT → NA, NA → CT, CT → DT, DT → CT }. b) Dependen Dependencias cias cuyos cuyos implica implicados dos no son son implicant implicantes es de otra otra dependencias. Cuando tenemos una dependencia cuyo implicado no es implicante de ningún otro atributo en el esquema relacional, la mejor opción para realizar la descomposición es elegir la dependencia donde se encuentra este atributo y descomponer en base a ella. Al descomponer, este atributo implicado desaparecerá del esquema relacional principal y pasará a formar parte del nuevo esquema relacional, relacional, junto a la dependencia en la que se encontraba, por lo que la dependencia en la que se encontraba no se transformará. Siempre que sea posible, las primeras dependencias que se elijan para la descomposición serán las dependencias cuyos implicados no son implicantes de otra dependencia. A continuación veremos como trata el algoritmo SELECCIONA estos casos.
SELECCIONA ;;------ENTRADA -----Un conjunto DEP de dependencias funcionales que violan la FNBC. ;;------SALIDA -----D dependencia seleccionada. TIPO: Tipo de la dependencia seleccionada ;;-------MAIN -----0) 1)
CONJUNTO CONJUNTO 1 = Dependen Dependencias cias que definen definen atributos atributos equival equivalentes entes no principal principales. es. Si CONJ CONJUN UNTO TO11 = Ø ento entonc nces es D = Cualquier dependencia de CONJUNTO1 TIPO = 1 Fin_algoritmo
2)
3)
IMP IMPLICA ICANTES = Ø Para toda X → Y de DEP Implicantes = Implicantes U X Fin_para_toda
4)
CANDIDATAS = Ø Para toda X → Y e DEP Si Y no pertenece a Implicantes entonces CANDIDATAS = CANDIDATAS U (X → Y) Fin_para_toda
5)
Si CAND CANDID IDAT ATAS AS = Ø ent enton once cess D = Cualquier dependencia de CANDIDATAS En caso contrario D = Cualquier dependencia de DEP
Este algoritmo realiza una selección de una dependencia de entre las dependencias funcionales que no cumplen la FNBC que se le pasan por parámetros, para seleccionar la dependencia funcional a partir e la cual se debería hacer la próxima descomposición. Si entre esas dependencias funcionales de entrada hay dependencias funcionales con implicados que no sean implicantes devolverá que el tipo de dependencia seleccionado es 1 y la dependencia seleccionada, ya que este tipo de dependencias funcionales tendrán prioridad para la descomposición frente a las dependencias que definen los atributos equivalentes. Si por el contrario, no hay ninguna dependencia funcional en la que haya un implicado implicado que no sea implicante, devolverá que el tipo es cualquier otra cosa excepto 1 (no se define una asignación para esta variable en ese caso) y devolverá una dependencia funcional para la descomposición cualquiera.
Anteriormente veíamos un algoritmo denominado DESC_1 en el que descomponíamos descomponíamos un esquema relacional en varios esquemas relacionales relacionales en FNBC. Como ya hemos advertido, el principal problema de este algoritmo es que selecciona una dependencia al azar de entre las que no cumplen las restricciones de la forma normal de Boyce-Codd. Esto puede producir que se produzcan pérdidas de dependencias funcionales en el conjunto final de esquemas partiendo de un esquema inicial en el que fuera posibleAobtener un conjunto final de esquemas relacionales en los LGORITMO DESC_2 que no se produzca pérdida de dependencias funcionales. ;;------ENTRADA -----Esquema de relación R = {AT,DEP}
A continuación se propone una modificación del algoritmo DESC_1 en el que se ;;------ENTRADA -----incluye el algoritmo SELECCIONA que permite seleccionar la dependencia funcional ESQUEMAS = r1, ..Rn conjunto de esquemas de relación en FNBC. adecuada con la que descomponer el esquema relacional. ;;------ENTRADA -----0) Si R est estáá en en FNB FNBC C ent enton once cess ESQ = {R} Fin del algoritmo
Fin_si 1) 2)
ESQ = {} DEP = Recubr Recubrimi imient entoo irre irredund dundant antee (DEP (DEP))
Calcular las claves del esquema DEP
3)
Mientras existan dependencias X → Y ∈ DEP|X no es superclave 3.1) X → Y O Salida del algoritmos SELECCIONA 3.2) Si (TIPO=1) entonces AT1 = X U Y Y {Atributos equivalentes} En caso contrario AT1 = X U Y Fin_si 3.3) AT = AT – X 3.4) PR i = Proyección de DEP sobre ATi 3.5) DEP’ = Proyección de DEP sobre AT 3.6) R i = {ATi,PR i} 3.7) ESQ = ESQ U {R i} Fin_mientras
4)
ESQUEMAS = ESQ
Veamos un ejemplo Tenemos el siguiente esquema de relación: AT = {A, B, D, E, F, X} DEP = {A→X, X→A, AB →C, AB → D, D→E, E→F } Siguiendo el algoritmo DESC_2, este algoritmo haría lo siguiente con este esquema relacional: R(AT,DEP) AT = {A, B, C, D, E, F, X} DEP = {A → X, X → A, AB → C, AB → D, D → E, E → F}
R1(AT1,DEP1) AT1 = {E, F } DEP1 = {E → F}
R3(AT3,DEP3) AT3 = { D, E} DEP3 = {D → E}
R2(AT2,DEP2) AT2 = {A, B, C, D, E, X} DEP2 = {A → X, X → A, AB → C, AB → D, D → E}
R4(AT4,DEP4) AT4 = {A, B, C, D, X} DEP4 = {A → X, X → A, AB → C, AB → D}
R5(AT5,DEP5) AT5 = {A, X} DEP5 = {A → X, X → A}
R6(AT6,DEP6) AT6 = {A, B, C, D } DEP6 = { AB → C, AB → D}
Lo que ocurre en este algoritmo es: Se le aplica el algoritmo SELECCIONA al conjuntote dependencias: E →F, D→E, A→X, X→A. Como se puede observar fácilmente, la dependencia E → F es la única que contiene un implicado que no sea implicante. Por ello se escoge esta dependencia para llevar a cabo la descomposición, dando como resultado R2 y R3.
R1 ya será un esquema FNCB. No así el esquema R2 que tendrá las dependencias {A →X, X→A, D→E} para las que no se cumplen las restricciones del esquema FNBC. En este conjunto de dependencias dependencias existe una dependencia, dependencia, la dependencia D →E, en la que el implicado no es implicante en ninguna otra dependencia, por lo tanto seleccionaremos esta dependencia y realizaremos la descomposición a través de ella. Los esquemas resultantes de cada una de las descomposiciones son R3 y R4. Volvemos a comprobar que R3 se encuentra en FNBC, mientras que R4 no se encuentra en BCNF, ya que las dependencias que no cumplen las propiedades de los esquemas BCNF son: A → X, y X →A. En este caso vemos que no existe ningún implicando que no sea implicante, pero sí se produce que existen dependencias que definen atributos equivalentes, que son las dos dependencias que no cumplen las restricciones de la FNBC. Por lo tanto, el algoritmo SELECCIONA seleccionará una de las dos dependencias funcionales 1y descompondrá en base a esta dependencia funcional. La dependencia funcional escogida para la descomposición es la X esquemas relacionales resultantes son el R5 y el R6.
→A. Los
Como se puede ver, la descomposición es SPI (sin pérdida de información) y además conserva todas las dependencias del esquema de partida.
Algoritmos que analizan si una descomposición se hace sin pérdidas de información. En el proceso de normalización, vemos que si un esquema posee redundancias, ambigüedades, etc, podemos hacer que alcance las formas normales deseadas mediante descomposición descomposición en proyecciones proyecciones . El mayor problema que se presenta con este método de erradicar los vicios de nuestro esquema relacional es que se pierda información como efecto de proyectar un esquema relacional en varios esquemas relacionales. La pérdida de información puede ser desde pérdida de atributos hasta pérdida de semántica de datos (perder dependencias funcionales, multivaluadas, de combinación, combinación, etc).
Determinación de si una descomposición es SPI RISSANEN (1979) introduce el término de proyecciones proyecciones independientes, independientes, que es un método sencillo de comprobar que la descomposición de un esquema en 2 no
posee pérdida de información. Por tanto, si un sistema de esquemas relacionales es un Sistema de Proyecciones Proyecciones Independientes (SPI), (SPI) , no hay pérdida de información. ULLMAN (1982) propone un algoritmo que permita, dado un esquema relacional, y el conjunto de las proyecciones en las que se descompone éste, comprobar si ese conjunto de proyecciones es un SPI o no lo es. Véase que Ullman propone un esquema de carácter general, para cualquier número de esquemas, aunque en realidad el término de Proyecciones Proyecciones Independientes se aplique solo a descomposiciones de esquema en dos partes. Este algoritmo es el siguiente:
;;---- ENTRADAS ---R = (Atrib (Atributo utos, s, DepF DepFunc unc)) ;; Atri Atribut butos os =Con =Conjun junto to de de Atrib Atributos utos del esquem esquemaa origi original nal R ;; DepFunc = Conjunto de Dependencias Funcionales del esquema R PROY = R1 ..... Rn Rn ;;P ;;PROY= conjunto de de proy proyeecciones en que se descom compone one R ;;----- SALIDAS -----True False
;; PROY es un SPI ;; PROY no es un SPI
;; ---- MAIN ----- NCOL = número de atributos de R NFIL = número de esquemas en que se descompone R (nº esquemas en PROY, o sea, n) Construir Matriz = - Filas NFIL (cada fila i representa al esquema proyectado Ri) - Columnas NCOL (cada columna j representa al atributo j del esquema R) Para todo elemento de la matriz Matiz * si el Atributo j está en la proyección Ri, se le asigna “aj” * si el Atributo j no está en la proyección Ri, se le asigna “bij” Mientras la Matriz cambie, y no haya una fila de la matriz con todos sus valores “a”: Opción A: Para toda X Y perteneciente a DepFunc en cualquier orden. Opción B: 4.1 Orden(DepFunc) 4.2 Para toda XY perteneciente a DepFunc ordenado mediante Orden. Orden. Seleccionar las Filas [1], tal que los elementos de la columna que coincide con el Atributo X implicante en XY seleccionado, sean iguales. Para las filas seleccionadas, modificar los valores de la columna que coincide con el atributo Y en la X—Y seleccionada, de la siguiente manera: Si hay algún “ ai” entre esos valores Poner todos los valores a “ ai”. En caso contrario poner todos los valores a un bij cualquiera. Fin para toda X Y Fin Mientras Si en alguna fila de la matriz, todos los valores son “ a’s”, devolver TRUE, FALSE en caso contrario.
Véase que en azul se plantean dos maneras de elegir las Dependencias funcionales del conjunto DepFunc: DepFunc: una sin orden ninguno (fue la primera versión del algoritmo) y otra según un determinado orden (versión propuesta por LOPEZ por motivos de eficiencia). Para entender este algoritmo, vamos a proponer un ejemplo sencillo, considerando que se toman las dependencias X Y sin orden alguno del conjunto
DepFunc (opción A). Después veremos en que consiste la función
Orden(DepFunc)
propuesta por LOPEZ. Ejemplo:
R1 = ({A,B} {A B}) R2 = ({B,C} {BC}) =
R = ({ A, B, C, D} {A B, BC , C D}) PROY = (R1, R2, R3) (3 proyecciones)
1.- NCOL = 4 2.- NFIL = 3 3.- MAT3x4 =
R1 R2
A a1
B a2
C b1 3 a3
D b14
b2 a2 b24 1 R3 b3 b3 a3 a4 4.- Si elijo como orden de 1 testeo 2 de las dependencias siguiente: 1º C D, 2º BC, 3º AB, resulta:
funcionales el
CD : Filas en las que MATi3 = MATj3. R1 R2 R3
R1 R2 R3
R1 R2 R3
A a1
B a2
b2 1 b3 1
a2
D b14
R1
b24
R2
b3 a3 a4 R3 2 BC : Filas en las que MATi2 = MATj2.
A a1
B a2
b2 1 b3 1 A a1 b2 1 b3 1
C b1 3 a3
D b14
a2
C b1 3 a3
B a2 a2
C a3 a3
D b 14 a4
R1 R2
b3 2
a3
a4
R3
R1 R2
a4
R3 b3 a3 a4 2 AB : Filas en las que MATi2 = MATj2.
A a1
B a2
b2 1 b3 1
a2
A a1 b2 1 b3 1
A a1 b2 1 b3 1
C b1 3 a3
D b14
b3 2
a3
a4
B a2 a2
C a3 a3
D b14 a4
b3 2
a3
a4
B a2 a2
C a3 a3
D b1 4 a4
b3 2
a3
a4
a4
No se ha llegado a una fila todo a ‘a’, y la matriz si se ha modificado en esta iteración, por tanto otra iteración del mientras. CD : Filas en las que MATi2 = MATj2. R1 R2 R3
A a1 b2 1 b3 1
B a2 a2
C a3 a3
D b14 a4
R1 R2
b3 2
a3
a4
R3
A a1 b2 1 b3 1
B a2 a2
C a3 a3
D a4 a4
b3 2
a3
a4
Como
vemos, la primera fila correspondiente a R1 tiene todos los elementos como “a’s”, por ello, elsistema de proyecciones si es SPI. Fin de algoritmo.
Sin embargo, esto mismo se ha podido hacer con solo tres dependencias funcionales funcionales (3 iteraciones), iteraciones), si se hubieran ordenado de la forma A B, B C, C D.
Por ello, LOPEZ propuso la modificación hecha en la OpciónB: ordenar las dependencias dependencias previo a las evaluaciones del mientras, de forma que el orden sea lo más eficiente posible (menor número de iteraciones). Por ejemplo: si un implicante X es compuesto de dos atributos, tienen que
;;--------- ENTRADAS --------coincidir DepFunc en esos dos atributos lasdefilas en [1] para que ;; conjunto dependencias funcionales
sean seleccionadas y modificadas. Si X2 no fuese compuesto, solo tienen que coincidir las filas en 1 ;; --------- SALIDAS --------atributo (menos más posibilidades de cambio). Siicie la dependencia de ORDE ORDEN N restricciones, ;; con conjunt junto o de depe de pend nden enci cias as func funcio ion nales ales ord ordenad enadas as efic ef ient ntem eme ente nte. X2 la empleamos antes, más se modifica la matriz y antes llegará a su fin el ;; --------- MAIN--------algoritmo. Agrupar las dependencias funcionales de DepFunc en función del número de atributos que forma el implicante (CONJUNTO1 = 1 atrib. implicante; CONJUNTO2= 2 atrib. implicantes.)
Basado en reglas como estas, Orden(DepFunc) opera de la siguiente manera las dependencias en DepFunc: DepFunc:
Paraordenar cada CONJUNTOi , desde 1 más hasta n,eficiente hacer: para de la forma
Para cada dependencia XY perteneciente a CONJUNTOi VAL=0 CONJUNTOXY = (Atributos de X) UNION (Atributos (Atributos de Y) Para cada AT, AT, siendo AT un atributo de CONJUNTOXY: Caso AT: AT: AT siempre implicante en CONJUNTOi => VAL= VAL + 0 AT como implicante e implicado en CONJUNTOi => VAL= VAL + 1 AT siempre como implicado en CONJUNTOi => VAL= VAL + 2 Fin Para cada AT VALOR(DEP) =VAL Fin para cada dependencia Añadir al final del conjunto ORDEN cada una de las dependencias DFk pertenecientes a CONJUNTOi, ordenada en función de su VALOR VALOR(DFk). [2] Fin Para todo CONJUNTOi
Por ejemplo: Sea DepFunc = {A
C, C D, B
C, CE A, DE C}
1. CONJUNTO1 = {AC, C D, BC} CONJUNTO2 = {CE A, DE C}
CONJUNTO1 Valor 1
2.
(AC) Valor (CD) Valor (BC)
CONJUNTO2 Valor 3 (CEA) Valor (DEC)
3 1
1
3. Ordenar dependencias , de forma que salgan antes las que son de un conjunto menor, y dentro de estas, la que tenga menor valor: CONJUNTO2
CONJUNTO1
ORDEN= {A
C, B
C, C D, DE C, CE A}
Determinación de si una descomposición preserva las Dependencias Funcionales El algoritmo anterior se basa en la definición de proyecciones proyecciones independientes, independientes, que parte de la descomposición de un esquema en 2 proyecciones. Cuando un esquema se descompone en mayor número de proyecciones, ¿cómo aplicar las condiciones de proyecciones independientes?. Se puede hacer de 2 en 2 (para lo que surge el problema de ¿Qué combinaciones de esquemas usar para hacer parejas?), pero puede ser que una descomposición sea SPI, y sin embargo, al aplicar el método por parejas resulte darnos ¡que no es SPI¡. Dadas estas limitaciones, limitaciones, ULLMAN (1982) ( 1982) propone un algoritmo no basado en el cálculo del cierre de un conjunto de dependencias funcionales, y por tanto, no es exponencial, sino que es polinomial su coste con respecto al número de dependencias funcionales. ;; ---------ENTRADAS--------R= (Atr (Atrib ibut utos os,, Dep DepFun Func) c) PROY= R1…Rn ;; --------- SALIDAS --------RESU RESULT LTAD ADO O = TRUE TRUE RESU RESULT LTAD ADO O = FAL FALSE SE
;;At ;;Atri ribut butos os:: atr atrib ibut utos os del del esq esquem uemaa ori origi ginal nal R ;;DepFunc: dependencias funcionales del esquema original R ;;PROY: conjunto de de proyecciones de R ;; PROY PROY es una desc descom ompos posic ició iónn que que pres preser erva va depe depend ndenc encia iass de de R ;; PPRO ROY Y no es una desc descom ompos posic ició iónn que que pres preser erva va depe depend ndenc encia iass de de R
;; --------- MAIN --------1. G=
∪ DEP [Ri]i = 1 .. n
;; En G se meten todas las dependencias que hay en las distintas ;; proyecciones, desde la primera (R1) hasta la última (Rn).
2. RESULTADO = TRUE 3. Para toda X Y que pertenece a DepFunc
;; para toda dependencia funcional del R de partida
Z=X Mientras Z cambie Para i= 1..n hacer Z=Z ∪ ((Z∩Ri)+ ∩ Ri) Fin Para Fin mientras Si Y ⊄ Z entonces RESULADO =FALSE Fin si
Si nos damos cuenta, en el punto 3 lo que hace es: calcular el cierre transitivo del implicante X ( Z= X+G) con respecto al total de dependencias funcionales que hay en las proyecciones, o sea, en G. Una vez obtenido este cierre, que son todos los atributos que pueden ser determinados determinados por X (directa o indirectamente) indirectamente) a través de las dependencias que se dan en las proyecciones, si la Y está contenida en éste (Z = X +G), entonces significa que X Y se puede deducir a través de las dependencias en las proyecciones, por tanto se conserva esa dependencia funcional del esquema original. Si no está la Y en el cierre X +G, entonces no se puede deducir X Y a partir de las proyecciones, por tanto se perdieron dependencias funcionales(devuelve FALSE). Por ejemplo: R=({A,B,C,D} R=({A,B,C,D} {A B, BC, C D, D A}) PROY= [
R1=({A, B} {A B, B A}) R2=({B, C} {BC, C B}) R3=({C, D} {C D, DC})
] De las dependencias originales, parece que falta la dependencia D A. Apliquemos Apliquemos el algoritmo tomando esa dependencia directamente (las otras daran que RESULTADO=TRUE) 1.- G = (A B, B A, BC, C B, C D, DC) 2.- Como tomamos D A del conjunto inicial de R Z sobre R1 Z= {A,B,C,D} Z sobre R1 Z= {D} 3. Z sobre R2 Z= {A,B,C,D} Z sobre R2 Z= {D} Z sobre R3 Z= {C, D} Z sobre R1 Z= {C, D} Z sobre R2 Z= {B, C , D} Z sobre R3 Z= {B, C, D}
Z={D}
Z sobre R3 Z= {A,B,C,D} Z sobre R1 Z= {A,B,C,D} Z sobre R2 Z= {A,B,C,D} Z sobre R3 Z= {A,B,C,D}
4.- Como en el cierre transitivo de D +G se encuentra A, quiere decir que se puede deducir D A a partir de las dependencias de las proyecciones, por tanto, se han conservado todas las dependencias funcionales del esquema inicial.
Algoritmos ALTERNATIVOS Por ahora hemos trabajado con el diseño lógico de la base de datos, refinando un primer esquema relacional mediante el concepto de las formas normales y las proyecciones independientes. Sin embardo, la normalización normalización no es el único método de refinamiento de la base de datos, ni puede conseguir todos sus objetivos (que es representar un mundo real lo más fidedigna posible).
Particionamiento Vertical En este ámbito, aparece el Particionamiento Vertical como una metodología de refinamiento de la base de datos, pero ya no solo a nivel lógico, sino a caballo entre el nivel lógico y el físico. eficiencia. Para ello, va a Por tanto, el objetivo de esta metodología es la eficiencia. descomponer un esquema relacional en conjuntos de atributos que sean accedidos en conjunto por gran número de transacciones. Que se presenten en la misma proyección permite permite realizar menor número de accesos a disco para traer los datos a memoria principal. Previo a ver el algoritmo gráfico, vamos a definir unos términos: Matriz de utilización de atributos: las columnas son los atributos de la relación que se va a particionar. Las filas son las transacciones respecto a las cuales se particionará. En cada posición ij de la columna va un 1 si el atributo j correspondiente es usado por la transacción i correspondiente, cero en caso contrario.
Matriz de afinidad: Se enfrenta cada atributo (columnas) con todos los atributos de la relación (fila), de manera que el resultado de la casilla ij es, de las transacciones comunes en las que aparece tanto el atributo i como el j, el tiempo de acceso por cada transacción coincidente. * Mide Fuerza de enlace entre atributos en la misma transacción. * En la diagonal ( un atributo consigo mismo) se mide la fuerza del atributo debida a su utilización por el conjunto de transacciones. Grafo de Afinidad: representar la matriz de afinidad mediante un grafo, donde los nodos son los atributos, y los arcos entre un nodo i y un nodo j, es la fuerza de enlace entre los atributos i y j de la matriz dicha. -
Ciclo primitivo: cualquier ciclo del grafo
-
Nodo Ciclo: nodo del arco que completa el ciclo
Ciclo de Afinidad: un ciclo primitivo que no tiene arco anterior, o si lo tiene, su peso es menor o igual que el peso de todos los arcos del ciclo. Arco anterior: arco seleccionado entre el último corte y el nodo ciclo. Extensión de un ciclo: ciclo : ciclo que se extiende pivotando en un nodo ciclo. La condición para extender un ciclo es que el peso del arco considerado o del arco que completa sea mayor o igual que cualquiera de los arcos que forman el ciclo. El algoritmo para el Particionamiento vertical es el siguiente: ;; --------- ENTRADAS--------AT ;; conjunto de atributos ;; --------- SALIDAS --------PROY PROY
;; ;;co conj njun untto de de es esquem quemas as en los los que que se divi divide de el esqu esquem emaa ori origi gina nall con con atr atrib ibut utos os AT.
;; --------- MAIN --------1.- Construir Grafo de afinidad 2.- Empezar por cualquier nodo 3.- Seleccionar un arco, tal que esté linealmente conectado al arbol construido hasta ahora, y posea el valor mayor de afinidad de los arcos de los extremos extremos del árbol. Esta iteración acaba cuando se seleccionan todos los nodos. 4.- Si ese siguiente arco forma un ciclo: * Si el nodo ciclo no existe, verificar las posibilidades de un ciclo de afinidad, y si se cumplen, marcarlo como un ciclo de afinidad y considerarlo partición candidata. * Si el nodo ciclo ya existe, descartar este arco y volver a 3. 5.- Si el siguiente arco no forma un ciclo y existe una partición candidata *Si no existe un arco anterior, verificar si se puede extender. Si no se puede, cortar el arco y considerar el ciclo como una partición ( ya no es candidata, ya es real). *Si existe un arco anterior, cambiar el nodo ciclo al nodo donde se extendió el arco, y verificar la posibilidad de extensión del ciclo con el arco anterior. Si no hay posibilidad, cortar el arco
Vamos a poner un ejemplo sencillo del Particionamiento vertical: Ejemplo: Partimos del esquema LIBRO, LIBRO, con los atributos “código, título, idioma, idioma, lema, número, año, editorial, precio, editor, observaciones”. Obtenemos el grafo de la manera siguiente:
Ejemplos de transacciones con sus retardos
Matriz de afinidad Grafo de afinidades
Comenzamos por Código. A partir de aquí tomamos arcos con mayor afinidad. El siguiente es Código-Título , el siguiente mayor del árbol ya formado es Título-año , y el siguiente año-editorial. editorial-código ). Estamos en el caso 4, la Aquí tenemos que parar, puse se ha formado un ciclo ( editorial-código primera opción ( no existe nodo ciclo), por tanto, como cumple condiciones del ciclo de afinidad (no hay arco anterior), es un ciclo de afinidad y por tanto partición candidata= Código, Titulo, Año, Editorial. Códigose convierte en nodo ciclo. El siguiente arco de extremos con mayor afi nidad es editorial-editor . Estamos antes el caso 5 debido a este arco, y como no existe arco anterior, comprobamos que no se puede extender, pues el arco nuevo editorial-editor y el que completa el ciclo editor-código tiene valor 25, menor que cualquier arco de la partición candidata. Se debe cortar por este arco y considerar el ciclo como partición definitivamente (ya no hay partición candidata).
El siguiente arco escogido es editor-idioma. No hay ciclo ni partición candidata, por tanto seguimos cogiendo el mayor, tomando idioma-tema , y finalmente editor-tema. Se ha formado un ciclo, por lo que estamos en 4, y como se cumplen condiciones de ciclo de afinidad ( pues no hay Editor,Idioma,Tema. arcos anteriores) esta se convierte en una partición candidata= Editor,Idioma,Tema El siguiente arco es código-observaciones. Nos sitúa en el caso 5, la primera opción (pues no hay arco anterior), y como no se cumple condición de extensión de ciclo (pues tema,idioma observación , no incluye al nodo ciclo) se produce corte entre código-observaciones , , y se considera la partición candidata como partición final. =Observaciones, Finalmente, a partir de observaciones se obtiene la partición candidata =Observaciones, Número, Precio , que como no hay mas nodos, se completa como partición. Por tanto, finalmente hemos descompuesto LIBRO en las particiones: LIBRO1={Código, título, editorial, año}; LIBRO2={Código,editor,idioma,tema}¸ LIBRO2={Código,editor,idioma,tema}¸ LIBRO3= LIBRO3= {Código, observaciones ,precio, número}. Véase que en cada partición se incluye el nodo ciclo correspondiente, que en este caso es el mismo para los tres. Númer o
1
5
5
Observ.
Precio
1 Código
3
4
Títul o
3
Editoria l
2
Editor
Año
1
1
Particionamiento Horizontal
3
Tema Idioma
1
Es un método de estructuración lógica, fuera de la normalización, normalización, que suprime los valores nulos “de riesgo” que pueden aparecer en las relaciones, bien por que no se ha detectado subtipos de una entidad, o bien por haber reunido tipos y subtipos en una sola relación en el paso del modelo E/I al modelo R. PERSONA , que se define de Por ejemplo: Se da el esquema relacional PERSONA {Nombre, Apellido1, Apellido2, Nacionalidad, DNI } la forma PERSONA: {Nombre,
Si una persona es de Nacionalidad extranjera, no española, no puede tener DNI, por ello DNI debe aceptar nulos (No es aplicable a extranjeros). Sin embargo, no puede haber un español que no tenga DNI. Véase que DNI es obligadamente nulo para personas de Nacionalidad extranjera, y obligatoriamente no nulo para españoles. Esto genera problemas de mantenimiento de la Base de Datos: nadie me impide insertar un extranjero con un DNI, ni un español sin DNI, puesto que DNI debe aceptar nulos para coger ambos casos. Algo similar sucede con Apellido2, que no puede aparecer por ejemplo en un americano (vamos a suponer que los españoles son los únicos en el mundo que usan dos apellidos), al no ser aplicable a extranjeros. El problema radica en que al generar la base de datos, no hemos sabido reconocer que en realidad se daba un supertipo PERSONA , con un nombre,
Apellido1 y dos subtipos : EXTRANJEROS,
con una Nacionalidad, Nacionalidad, además del nombre y apellido1 que hereda de PERSONA, PERSONA, y ESPAÑOLES, ESPAÑOLES, con un Apellido2 y DNI, DNI, además de lo heredado de PERSONA. PERSONA. PERSONA Nombre, Apellido1
EXTRANJEROS Nombre, Apellido1, Apellido1, Nacionalidad
ESPAÑOLES Nombre, Apellido1, Apellido1, Apellido2, DNI
Este es el Particionamiento horizontal.
Conclusiones En el Diseño lógico de una Base de datos, la simple aplicación de las reglas de transformación transformación para pasar del esquema conceptual conceptual (diagramas Entidad /Interrelación) /Interrelación) al esquema relacional es insuficiente, ya que resulta un conjunto de esquemas relacionales redundantes y que no refleja adecuadamente la semántica de los datos. Esto implica una fase de refinamiento del esquema relacional obtenido inicialmente. Dado el carácter sistemático de este refinamiento, y su estructura secuencial, la mejor manera de realizarla es algorítmicamente, lo cual implica: - Método sistemático. - Facilmente implementable. - Su implementación software permite una automatización. - Diseñador de la Base de Datos puede centrarse en otros aspectos del diseño.
La desventaja de los algoritmos, y el handicap en la generación de algoritmos para este fin, es el tiempo de costo de los mismos, ya que de nada sirve una herramienta que no se puede usar en la práctica. Otra desventaja es que estos algoritmos no tienen en cuenta la semántica de datos, por lo que en muchas ocasiones se llegan a resultados absurdos semánticamente, pero teóricamente correctos (ya que las transformaciones de datos son de carácter sintáctico).
Hoy en día, el uso de estos algoritmos se dan sobre todo en procesos de rediseños o ampliaciones de bases de datos, ya que se hace muy costoso comprobar manualmente el impacto de la variación de las dependencias del esquema relacional. En general, la eficiencia de estos algoritmos está en función del conjunto de dependencias del esquema del que se parte.