Alters

A buscar M!nas: MSAccess - normalización

Buenas!

Nos adentramos de lleno en la fase final de la construcción de nuestra base de datos primitiva.

Así, hoy veremos el paso final antes de implementar nuestro modelo; la normalización.

Este proceso, como su nombre indica, "normaliza" el modelo relacional, de manera que será más definido y útil.

El proceso es gradual, es decir, no se puede llegar a una forma normal (FN) si no está en la FN anterior (y así recursivamente...)

Conceptos previos:

Antes de entrar en el proceso, vamos a definir unos conceptos, que nunca viene mal:

  • O: durante esta entrada, para referirnos a un conjunto de valores originales usaremos la letra "o" mayúscula (no confundir con cero).
  • I: se trata de un conjunto imagen.
  • Intención: es la descripción "fija" de una tabla. Contiene los descriptores de la tabla así como las restricciones. Se puede representar como R(A1, A2, A3, ... , An)
  • Extensión: es el conjunto de tuplas ("filas") de una tabla en un momento determinado.


Ahora que tenemos los términos básicos definidos, podemos pasar a definir qué es una dependencia funcional:


  • Dependencia funcional: Restricción sobre una relación con intención R(A1, A2, A3, ... , An) que representa un esquema {x} -> {y} donde {x} e {y} son subconjuntos de la intención que garantiza que dado un valor de {x}, es determinado de manera única un valor de {y}*.

* Esto se puede representar (de un modo aproximado) como;

[{x}, {y} c (A1, A2, A3, ... , An) | Xi <-> Yj]


Vista esta pequeña introducción, podemos pasar a la normalización:

Normalización:

Como comentaba, se trata de un proceso progresivo. De esta manera, empezaré con la primera forma normal (1FN) e iré avanzando hacia modelos más normalizados. Empecemos:

  • 1FN: se dice que una relación está en 1FN si ningún atributo de la relación es en si mismo una relación, es decir, si todo atributo de la relación es atómico, no descomponible y no es un grupo repetitivo (solo tiene ciertos valores)
Ejemplificando: supongamos la siguiente tabla: Alumno(DNI, nombre, notas). En este caso, las notas son algo no atómico, descomponible y tiene parte de grupo repetitivo. Ampliando la información, sería:

 - No atómico: "notas" es un registro que puede estar repetido dentro de un mismo registro. Por ejemplo para el DNI1 puede haber algo así como "castellano primer trimestre: 5, inglés primer trimestre..." dentro del mismo registro.

 - Descomponible: se puede dividir en varias secciones. Por ejemplo: nota, asignatura, trimestre.

 - Grupo repetitivo: las asignaturas, la nota y el trimestre son de por sí grupos repetitivos.

Alumno(DNI, nombre, notas) ==> Alumno(DNI, nombre, asignatura, nota, trimestre)

Al normalizar se ha tenido que expandir la PK, para que no haya duplicados.
  • 2FN: se dice que una relación está en 2FN si está en 1FN y todo atributo no clave depende funcionalmente, en forma completa de la PK.
Esto quiere decir que todo aquel atributo que dependa de algo que no sea la TOTALIDAD de la PK de la tabla tendrá que ser modificado, de manera que ese atributo pasará a ser una tabla. La tabla que fue normalizada incorporará como FK la PK de la nueva tabla.

  • 3FN: se dice que una relación está en 3FN si está en 2FN y ningún atributo no clave depende funcionalmente de ningún otro conjunto de atributos no clave.
¿Qué significa esto? Puede parecer algo lioso, pero de vez en cuando se ve. Veamos un ejemplo:

Direccion(ID, calle, ciudad, provincia)

En este caso (y refiriéndonos a un modelo local, es decir, suponiendo que solo se tiene en cuenta un país) sabiendo la ciudad se sabe la provincia. Por eso, esta tabla no está en 3FN.

Direccion(ID, calle, ciudad, provincia) ==> Direccion(ID, calle, idCiudad)  Ciudad(ciudad, provincia)

Se crea una nueva tabla y se asigna una nueva FK


  • FNBC: esta forma normal es "especial", ya que está a caballo entre la 3FN y la 4FN. Normalmente se acepta una base de datos normalizada hasta la FNBC. No obstante nosotros veremos hasta la 5FN. 
La FNBC dice que dada una dependencia funcional {x} -> {y}, todo elemento de "x" es considerado como clave candidata.

Una definición así cuesta ver, así que dejo un ejemplo:

Notas(DNI, codAsig, codMatr, nota)

En esta tabla, DNI y codAsig son la PK. No obstante, el atributo "codMatr" es una clave candidata (es decir, podría servir como PK). Así, surgen cuatro opciones para normalizar esta situación:

a) Notas(DNI, codAsig, nota)
    Alumno(DNI, codMatr)

b) Notas(DNI, codAsig, nota)
    Alumno(codMat, DNI)

c) Notas(DNI, codAsig, nota)
    Alumno(codMat, DNI)

d) Notas(DNI, codAsig, nota)
    Alumno(DNI, codMat)


  • 4FN: para saber si una relación está en 4FN tenemos que comprobar que no existan DMI (Dependencia Multievaluada Independiente) y está en FNBC.
Una DMI se define como:

Sea "R" una relación con esquema R(A1, A2, A3, ..., An), y siendo {x}, {y} y {z} atributos de "R", se dará la DMI {x} ->> {y} si y solo si el conjunto de valores posibles de {y} para un par {x, z} depende únicamente del valor de "x" y es independiente del valor de "z".

Visto desde el punto de vista relacional, significa simplemente que las relaciones "n-arias" pasan a ser "n" relaciones con relación "n : n".

  • 5FN: una relación está en 5FN si y solo si está en 4FN y cumple que no tiene PK descomponible.
Para verlo mejor, un ejemplo:

Profesor(ID, nombre)
Asignatura(ID, nombre)
Centro(ID, nombre)

Ensenanza(IdPro, IdAsi, IdCen)  ==> PA(IdPro, IdAsig) PC(IdPro, IdCen)

Ahora ya sabemos en qué consiste normalizar; vamos a aplicarlo a nuestro modelo:

usuario(nick, nombre, apellido1, apellido2, email, password)
estadistica(gana, tiempo, dificultad, opcion, autenticacion, minas, clicks, id_estadistica)
juego(nick, id_estadistica, fecha)


  •  1FN: en la tabla estadistica tenemos varios grupos repetitivos: "gana", "dificultad", "opcion", "autenticacion", "minas"). A continuación se describen los grupos repetitivos:
 - Gana:
   * Sí (1)
   * No (2)

 - Dificultad:
   * Fácil (1)
   * Medio (2)
   * Difícil (3)

- Opción:
   * Opción 1 (1)
   * Opción 2 (2)

 - Autenticación:
   * Registrado (1)
   * Anónimo (2)

 - Minas:
   * 10 (1)
   * 40 (2)
   * 99 (3)

Para deshacer los grupos repetitivos trasladamos todos los valores a numéricos, empezando siempre por 1 y llegando hasta el último valor disponible. Éstos valores se colocan arriba entre paréntesis.
  • 2FN: El modelo está en 2FN.
  • 3FN: Se puede apreciar en la tabla usuario cómo el campo "email", si no es nulo sirve para identificar a un usuario. Por ello realizamos la siguiente modificación:


usuario(nick, nombre, apellido1, apellido2, email, password) ==> usuario(nick, nombre, apellido1, apellido2, idE, password) email(idE, email)

  • FNBC: Se ha eliminado la clave candidata (email) en la tabla usuario (realmente no era clave candidata puesto que podría ser un dato vacío). Por tanto, estamos en FNBC.
  • 4FN: Está en 4FN
  • 5FN: Está en 5FN.
De este modo, tenemos por fin nuestro modelo relacional normalizado, siendo el siguiente:

usuario(nick, nombre, apellido1, apellido2, idE, password) 
email(idE, email)
estadistica(gana, tiempo, dificultad, opcion, autenticacion, minas, clicks, id_estadistica)
juego(nick, id_estadistica, fecha)

Con esto dejamos la base preparada para el próximo paso: la programación.

Así, en la próxima entrega veremos cómo pasar este esquema al SQL, y más adelante haremos las ampliaciones necesarias en nuestro juego de VB.net.

Espero no se os haya hecho muy pesada la lectura.

¡Hasta la próxima!