Definición: Supongamos que tenemos una relación con tres conjuntos de
atributos: X, Y y Z, y las siguientes dependencias X -> Y
, Y -> Z
,
Y -> |X
. Es decir X determina Y e Y determina Z, pero Y no determina X. En ese caso,
decimos que Z tiene dependencia transitiva con respecto a X, a través de Y.
Intentaremos aclarar este concepto tan teórico con un ejemplo. Si tenemos esta relación:
Ciudades(ciudad, población, superficie, renta, país, continente)
Los atributos como población, superficie o renta tienen dependencia funcional de ciudad, así que de momento no nos preocupan.
En esta relación podemos encontrar también las siguientes dependencias:
ciudad -> país
, país -> continente
. Además, país -> |ciudad
.
Es decir, cada ciudad pertenece a un país y cada país a un continente, pero
en cada país puede haber muchas ciudades. En este caso continente tiene una
dependencia funcional transitiva con respecto a ciudad, a través de país. Es decir, cada
ciudad está en un país, pero también en un continente. (¡Ojo! las dependencias
transitivas no son siempre tan evidentes :-).
La tercera forma normal consiste en eliminar las dependencias transitivas.
Definición: Una base de datos está en 3FN si está en 2FN y además todas las columnas que no sean claves dependen de la clave completa de forma no transitiva.
Pero esto es una definición demasiado teórica. En la práctica significa que se debe eliminar cualquier relación que permita llegar a un mismo dato de dos o más formas diferentes.
Tomemos el ejemplo que usamos para ilustrar las dependencias funcionales transitivas. Tenemos una tabla donde se almacenen datos relativos a ciudades, y una de las columnas sea el país y otra el continente al que pertenecen. Por ejemplo:
Ciudades(ID_ciudad(PK), Nombre, población, superficie, renta, país, continente)
Un conjunto de datos podría ser el siguiente:
Ciudades ID_ciudad Nombre población superficie renta país continente 1 Paris 6000000 15 1800 Francia Europa 2 Lion 3500000 9 1600 Francia Europa 3 Berlin 7500000 16 1900 Alemania Europa 4 Pekin 19000000 36 550 China Asia 5 Bonn 6000000 12 1900 Alemania Europa
Podemos ver que para cada aparición de un determinado país, el continente siempre es el mismo. Es decir, existe una redundancia de datos, y por lo tanto, un peligro de integridad.
Existe una relación entre país y continente, y ninguna de ellas es clave candidata. Por lo tanto, si queremos que esta table sea 3FN debemos separar esa columna:
Ciudades(ID_ciudad(PK), Nombre, población, superficie, renta, nombre_pais) Paises(nombre_pais(PK), nombre_continente)
Ciudades ID_ciudad Nombre población superficie renta país 1 Paris 6000000 15 1800 Francia 2 Lion 3500000 9 1600 Francia 3 Berlin 7500000 16 1900 Alemania 4 Pekin 19000000 36 550 China 5 Bonn 6000000 12 1900 Alemania Paises país continente Francia Europa Alemania Europa China Asia
Esta separación tendría más sentido si la tabla de paises contuviese más información, tal como está no tiene mucho sentido separar estas tablas, aunque efectivamente, se evita redundancia.
Definición: Una relación está en FNBC si cualquier atributo sólo facilita información sobre claves candidatas, y no sobre atributos que no formen parte de ninguna clave candidata.
Esto significa que no deben existir interrelaciones entre atributos fuera de las claves candidatas.
Para ilustrar esta forma normal volvamos a uno de nuestros ejemplos anteriores, el de las ocupaciones de habitaciones de un hotel.
Ocupación(No_cliente, Nombre_cliente, No_habitación, fecha_entrada) Habitación(No_habitación(PK), precio_noche, tipo_habitación)
En la primera relación los atributos No_cliente y Nombre_cliente sólo proporcionan información entre ellos mutuamente, pero ninguno de ellos es una clave candidata.
Intuitivamente ya habremos visto que esta estructura puede producir redundancia, sobre todo en el caso de clientes habituales, donde se repetirá la misma información cada vez que el mismo cliente se aloje en el hotel.
La solución, como siempre, es simple, y consiste en separar esta relación en dos diferentes:
Ocupación(No_cliente, No_habitación, fecha_entrada) Cliente(No_cliente(PK), Nombre_cliente) Habitación(No_habitación(PK), precio_noche, tipo_habitación)
Definición: se dice que un atributo es multivaluado cuando para una misma entidad puede tomar varios valores diferentes, con independencia de los valores que puedan tomar el resto de los atributos.
Se representa como X ->-> Y
, y se lee como X multidetermina Y.
Un ejemplo claro es una relación donde almacenemos contactos y números de teléfono:
Agenda(nombre, fecha_nacimiento, estado_civil, teléfono)
Para cada nombre de la agenda tendremos, en general, varios números de teléfono, es
decir, que nombre multidetermina teléfono: nombre ->-> teléfono
.
Además, nombre determina funcionalmente otros atributos, como la fecha_nacimiento o estado_civil.
Por otra parte, la clave candidata no es el nombre, ya que debe ser unívoca, por lo tanto debe ser una combinación de nombre y teléfono.
En esta relación tenemos las siguientes dependencias:
nombre -> fecha_nacimiento
nombre -> estado_civil
nombre ->-> teléfono
, o lo que es lo mismo (nombre,teléfono) ->
teléfono
Es decir, la dependencia multivaluada se convierte, de hecho, en una dependencia funcional trivial.
Este tipo de atributos implica redundancia ya que el resto de los atributos se repiten tantas veces como valores diferentes tenga el atributo multivaluado:
Agenda nombre fecha_nacimiento estado_civil teléfono Mengano 15/12/1985 soltero 12322132 Fulano 13/02/1960 casado 13321232 Fulano 13/02/1960 casado 25565445 Fulano 13/02/1960 casado 36635363 Tulana 24/06/1975 soltera 45665456
Siempre podemos evitar el problema de los atributos multivaluados separandolos en relaciones distintas. En el ejemplo anterior, podemos crear una segunda relación que contenga el nombre y el teléfono:
Agenda(nombre(PK), fecha_nacimiento, estado_civil) Teléfonos(nombre, teléfono(PK))
Para los datos anteriores, las tablas quedarían así:
Agenda nombre fecha_nacimiento estado_civil Mengano 15/12/1985 soltero Fulano 13/02/1960 casado Tulana 24/06/1975 soltera Teléfonos nombre teléfono Mengano 12322132 Fulano 13321232 Fulano 25565445 Fulano 36635363 Tulana 45665456
© Diciembre de 2004 Salvador Pozo, salvador@conclase.net