Bases de datos – 4. Formas normales

Bienvenidos a nuestro blog tecnológico queridos rooters. Espero que hayáis podido descansar como se merece en este parón navideño, y de paso felicitaros el año nuevo. En este primer rootie de este 2017 voy a retomar la saga de bases de datos, siguiendo pues por donde lo dejamos: las formas normales.

¿Qué son las formas normales?

Las formas normales son una serie de mecanismos que proporcionan criterios para detectar anomalías e inconsistencias en nuestras tablas. Existen desde la 1FN hasta la 6FN, además de haber una FN especial demoninada forma normal de dominio/clave. Cuanto más alta sea la forma normal aplicable a una tabla, menos vulnerable será a inconsistencias y anomalías.

La numeración de las formas normales no significa que sea un proceso restrictivo por el cual haya que pasar sí o sí. Con la práctica, es probable que nuestros diseños de bases de datos estén al menos en la 3FN y no haya hecho falta normalizar desde 1FN hasta 2FN y después 3FN.

Para las 3 primeras formas normales podemos decir que tienen como requerimiento que todos los atributos no-clave sean dependientes en «la clave, la clave completa, y nada excepto la clave».

PRIMERA FORMA NORMAL

La 1FN es la forma mínima en la que se encuentran nuestras tablas. Consiste en añadir una tabla adicional para satisfacer los criterios mínimos de integridad, consistencia y concurrencia. Esta forma normal se utiliza para representar una relación básica y evitar grupos repetitivos. Una tabla está en 1FN si y solo si se cumplen las siguientes cinco condiciones:

  1. No hay orden de arriba-a-abajo en las filas.
  2. No hay orden de izquierda-a-derecha en las columnas.
  3. Sin filas duplicadas. Puede darse, por ejemplo, si no hay clave primaria.
  4. Cada intersección de fila-y-columna contiene exactamente un valor del dominio aplicable (y nada más). Si permitimos valores nulos, esta condición podría no cumplirse.
  5. Todas las columnas son regulares; es decir, las filas no tienen componentes como IDs de fila, IDs de objeto, o timestamps ocultos.

Veamos un ejemplo. Supongamos que tenemos que guardar el nombre y el teléfono de nuestros clientes. La primera idea sería crear una tabla así:

Clientes
ID Cliente Nombre Apellido Teléfono 1
123 Rachel Ingram 555-861-2025
456 James Wright 555-403-1659
789 Cesar Dure 555-808-9633

Pero entonces nos damos cuenta de que un cliente puede tener varios números de teléfono. Dos maneras poco eficientes de resolver esta necesidad serían las siguientes:

Manera poco eficiente: crear tantas columnas como campos necesitemos

Clientes
ID Cliente Nombre Apellido Teléfono 1 Teléfono 2
123 Rachel Ingram 555-861-2025
456 James Wright 555-403-1659 555-637-182
789 Cesar Dure 555-808-9633

Esta representación hace uso de columnas que permiten valores nulos, y por lo tanto no se conforman con la definición de la 1FN.

Manera poco eficiente: guardar varios registros en el mismo campo

Clientes
ID Cliente Nombre Apellido Teléfono
123 Rachel Ingram 555-861-2025
456 James Wright 555-403-1659, 555-637-182
789 Cesar Dure 555-808-9633

Este diseño es probablemente la peor opción. Semánticamente no es claro, ya que no sigue la filosofía de la tabla. Además de complicar muchísimo futuras consultas a dicha tabla.

Por tanto, la manera correcta es adherir una nueva tabla a nuestra tabla clientes, relacionándose entre ellas mediante el ID único de cliente.

Clientes
ID Cliente Nombre Apellido
123 Rachel Ingram
456 James Wright
789 Cesar Dure
Teléfonos de clientes
ID Cliente Teléfono
123 555-861-2025
456 555-403-1659
456 555-637-182
789 555-808-9633

Así evitamos grupos repetidos y campos vacíos. Cada cliente podrá tener, o no, varios teléfonos.

SEGUNDA FORMA NORMAL

Una tabla que está en la primera forma normal debe satisfacer criterios adicionales para calificar que se encuentra en la segunda forma normal. Específicamente: una tabla 1FN está en 2FN si y solo si, dada una clave primaria y cualquier atributo que no sea un constituyente de la clave primaria, el atributo no clave depende de toda la clave primaria en vez de sólo de una parte de ella.

Supongamos que tenemos que almacenar empleados de nuestra empresa, lugar de trabajo y sus habilidades personales. Podríamos considerar una tabla así:

Habilidades de los empleados
Empleado Habilidad Lugar actual de trabajo
Jones Mecanografía 114 Main Street
Jones Taquigrafía 114 Main Street
Jones Tallado 114 Main Street
Bravo Limpieza ligera 73 Industrial Way
Ellis Alquimia 73 Industrial Way
Ellis Malabarismo 73 Industrial Way
Harrison Limpieza ligera 73 Industrial Way

La única clave candidata de la tabla es {Empleado, Habilidad}.

El atributo restante, Lugar actual de trabajo, es dependiente solo en parte de la clave candidata, llamada Empleado. Por lo tanto la tabla no está en 2FN. Existe redundancia en la manera en que son representadas los Lugares actuales de trabajo: nos dicen tres veces que Jones trabaja en la 114 Main Street, y dos veces que Ellis trabaja en 73 Industrial Way. Esta redundancia hace a la tabla vulnerable a anomalías de actualización: por ejemplo, es posible actualizar el lugar del trabajo de Jones en sus registros «Mecanografía» y «Taquigrafía» y no actualizar su registro «Tallado». Los datos resultantes implicarían respuestas contradictorias a la pregunta «¿Cuál es el lugar actual de trabajo de Jones?».

Una alternativa 2FN a este diseño representaría la misma información en dos tablas:

Empleados
Empleado Lugar actual de trabajo
Jones 114 Main Street
Bravo 73 Industrial Way
Ellis 73 Industrial Way
Harrison 73 Industrial Way
Habilidades de los empleados
Empleado Habilidad
Jones Mecanografía
Jones Taquigrafía
Jones Tallado
Bravo Limpieza ligera
Ellis Alquimia
Ellis Malabarismo
Harrison Limpieza ligera

Las anomalías de actualización no pueden ocurrir en estas tablas, las cuales están en 2FN. Esta forma normal es el buen camino hacia la 3FN, ya que todavía es mejorable este diseño a nivel estructural.

TERCERA FORMA NORMAL

La definición de Codd indica que una tabla está en 3FN si y solo si las tres condiciones siguientes se cumplen:

  • La tabla está en la segunda forma normal (2FN)
  • Ningún atributo no-primario de la tabla es dependiente transitivamente de una clave primaria
  • Es una relación que no incluye ningún atributo clave

Un atributo no-primario es un atributo que no pertenece a ninguna clave candidata. Una dependencia transitiva es una dependencia funcional XZ en la cual Z no es inmediatamente dependiente de X, pero sí de un tercer conjunto de atributos Y, que a su vez depende de X. Es decir, XZ por virtud de XY e YZ.

Cómo hemos mencionado antes, cada atributo no-clave «debe proporcionar un hecho sobre la clave, la clave entera, y nada más excepto la clave».

Imaginad que debemos almacenar información de torneos de tenis, año en el que se celebran, ganador y fecha de nacimiento del ganador.

Ganadores del torneo
Torneo Año Ganador Fecha de nacimiento del ganador
Indiana Invitational 1998 Al Fredrickson 21 de julio de 1975
Cleveland Open 1999 Bob Albertson 28 de septiembre de 1968
Des Moines Masters 1999 Al Fredrickson 21 de julio de 1975
Indiana Invitational 1999 Chip Masterson 14 de marzo de 1977

La única clave candidata es {Torneo, Año}.

La violación de la 3FN ocurre porque el atributo no primario Fecha de nacimiento del ganador es dependiente transitivamente de {Torneo, Año} vía el atributo no primario Ganador. El hecho de que la Fecha de nacimiento del ganador es funcionalmente dependiente en el Ganador hace la tabla vulnerable a inconsistencias lógicas, pues no hay nada que impida a la misma persona ser mostrada con diferentes fechas de nacimiento en diversos registros.

Para expresar los mismos hechos sin violar la 3FN, es necesario dividir la tabla en dos:

Ganadores del torneo
Torneo Año Ganador
Indiana Invitational 1998 Al Fredrickson
Cleveland Open 1999 Bob Albertson
Des Moines Masters 1999 Al Fredrickson
Indiana Invitational 1999 Chip Masterson
Fecha de nacimiento del jugador
Ganador Fecha de nacimiento
Chip Masterson 14 de marzo de 1977
Al Fredrickson 21 de julio de 1975
Bob Albertson 28 de septiembre de 1968

Las anomalías de actualización no pueden ocurrir en estas tablas, las cuales están en 3NF. Como veis, aplicando un poco de lógica desde el principio -y con práctica- es fácil conseguir que nuestras tablas estén en la tercera forma normal y no haya que hacer el proceso de normalización.

Si tenéis cualquier duda sobre formas normales no dudéis en escribir un comentario y lo contestaremos lo antes posible.

¡Nos vemos en el siguiente rootie!

 

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *