En entradas anteriores hablamos del modelo de datos dimensional, en ésta vamos a hablar del modelo relacional y de las formas normales principales a la hora de normalizar una base de datos.
Normalización
La normalización de base de datos es una técnica de modelado consistente en designar y aplicar una serie de reglas a las relaciones obtenidas tras el paso del modelo entidad-relación al modelo relacional.
Objetivos
|
Requerimientos
Para que una tabla sea considerada una relación tiene que cumplirse lo siguiente:
|
Conceptos
A continuación vamos a definir una serie de conceptos fundamentales para comprender las formas normales que explicaremos después:
Dependencia Funcional: Es una conexión entre uno o más atributos DNI → Nombre y apellidos |
Dependencia Funcional Reflexiva: Si “Y” está incluido en “X” entonces X → Y Si dirección y nombre están incluidos en DNI entonces con el DNI se puede recuperar la dirección y el nombre |
Dependencia Funcional Aumentativa: Si “X” → “Y” entonces “XZ” → «YZ” DNI → Nombre DNI, Dirección → Nombre, Dirección |
Dependencia Funcional Transitiva: Si “X” → “Y” → «Z” entonces “X” → “Z” Fecha de nacimiento → Edad Edad → Conducir Fecha de nacimiento → Edad → Conducir |
Ejemplo:
Para explicar las formas normales vamos a poner una tabla de ejemplo de Empleados. La siguiente tabla muestra la información de una empresa cuyos puestos de trabajo están regulados por el Estado, de modo que el salario de cada empleado depende del puesto. Datos empleados: ID, nombre, puesto salario e email, siendo ID la clave primaria.
ID (Pk) | Nombre | Puesto | Salario | Emails |
1 | Juan Pérez | Jefe de área | 3000 | juan@test.com;jefe1@test.com |
2 | José Sánchez | Administrativo | 1500 | jsanchez@test.com |
3 | Ana Díaz | Administrativo | 1500 | adiaz@test.com;admin@test.com |
Tabla 1. Empleados
1FN
Una tabla está en primera forma normal si:
- Sus atributos contienen valores atómicos (esto quiere decir que tienen que ser indivisibles)
En el ejemplo podemos ver que no se cumple para el atributo «Emails»
ID (Pk) | Nombre | Puesto | Salario | Emails |
1 | Juan Pérez | Jefe de área | 3000 | juan@test.com;jefe1@test.com X |
2 | José Sánchez | Administrativo | 1500 | jsanchez@test.com |
3 | Ana Díaz | Administrativo | 1500 | adiaz@test.com;admin@test.com X |
Tabla 1. Empleados
Para solucionarlo existen 2 opciones:
1. Duplicar registros con valores repetidos:
- Se elimina el atributo «Emails» que violaba la condición
- Se incluye un nuevo atributo «Email» que sí sea indivisible. Por lo que se crea una nueva clave primaria con este nuevo atributo
La nueva clave primaria será «ID-Email»
ID (Pk) | Nombre | Puesto | Salario | Emails (Pk) |
1 | Juan Pérez | Jefe de área | 3000 | juan@test.com |
1 | Juan Pérez | Jefe de área | 3000 | jefe1@test.com |
2 | José Sánchez | Administrativo | 1500 | jsanchez@test.com |
3 | Ana Díaz | Administrativo | 1500 | adiaz@test.com |
3 | Ana Díaz | Administrativo | 1500 | admin@test.com |
Tabla 2. Empleados (a)
2. Separar atributo «Email» en otra tabla:
- Se crea una nueva tabla Empleados (b) que no contenga el atributo «Email»
ID (Pk) | Nombre | Puesto | Salario |
1 | Juan Pérez | Jefe de área | 3000 |
1 | Juan Pérez | Jefe de área | 3000 |
2 | José Sánchez | Administrativo | 1500 |
Tabla 3. Empleados (b)
- Se crea una nueva tabla EMAILS con clave primaria ID-Email. Las tablas Emails y Empleados se relacionan por el campo ID
ID | Emails (Pk) |
1 | juan@test.com |
1 | jefe1@test.com |
2 | jsanchez@test.com |
3 | adiaz@test.com |
3 | admin@test.com |
Tabla 4. Emails
2FN
Una tabla está en 2FN si:
- Está en 1FN
- Todos los atributos que no son clave primaria tienen dependencia funcional completa con respecto a todas las claves existentes en el esquema. Para recuperar un atributo no clave, se necesita acceder por la clave completa, no por una subclave
- Las 2FN aplican a las relaciones con claves primarias compuestas por dos o más atributos
ID (Pk) | Emails (Pk) | Nombre | Puesto | Salario |
1 | juan@test.com | Juan Pérez | Jefe de área | 3000 |
1 | jefe1@test.com | Juan Pérez | Jefe de área | 3000 |
2 | jsanchez@test.com | José Sánchez | Administrativo | 1500 |
3 | adiaz@test.com | Ana Díaz | Administrativo | 1500 |
3 | admin@test.com | Ana Díaz | Administrativo | 1500 |
Tabla 2. Empleados (a)
En la tabla de Empleados (a) se pueden ver las dependencias de los atributos:
ID → Nombre, puesto, salario Puesto → Salario |
Observamos que los atributos nombre, puesto y salario dependen únicamente del campo ID, por lo que no cumple la 2FN.
Para solucionarlo:
→ Actuar sobre los atributos con dependencias incompletas:
- Eliminar los atributos con dependencias incompletas
- Crear nueva tabla con los atributos y la clave de la que depende
ID (Pk) | Nombre | Puesto | Salario |
1 | Juan Pérez | Jefe de área | 3000 |
1 | Juan Pérez | Jefe de área | 3000 |
2 | José Sánchez | Administrativo | 1500 |
Tabla 3. Empleados (b)
ID | Emails (Pk) |
1 | juan@test.com |
1 | jefe1@test.com |
2 | jsanchez@test.com |
3 | adiaz@test.com |
3 | admin@test.com |
Tabla 4. Emails
Se llega a la misma solución que con la 1FN.
3FN
Una tabla está en 3FN si:
- Está en 2FN
- Todos los atributos que no son clave primaria no dependen transitivamente de ésta
Por tanto hay que buscar dependencias funcionales entre atributos que no estén en la clave.
ID (Pk) | Nombre | Puesto | Salario |
1 | Juan Pérez | Jefe de área | 3000 |
2 | José Sánchez | Administrativo | 1500 |
3 | Ana Díaz | Administrativo | 1500 |
Tabla 3. Empleados (b)
Las dependencias transitivas son:
ID → Puesto Puesto → Salario |
Observamos como la dependencia Puesto – Salario tiene dependencia transitiva con la clave primaria.
Para solucionarlo:
→ Actuar sobre los atributos con dependencias transitivas
- Separar en una tabla adicional los atributos que tienen dependencia transitiva con la clave (Salario) y establecer como Pk el campo que define la transitividad (Puesto)
Puesto (Pk) | Salario |
Jefe de área | 3000 |
Administrativo | 1500 |
Tabla 5. Puestos
ID (Pk) | Nombre | Puesto (Pk) |
1 | Juan Pérez | Jefe de área |
2 | José Sánchez | Administrativo |
3 | Ana Díaz | Administrativo |
Tabla 6. Empleados (c)
- Se añade el campo «Puesto» como Foreign Key:
ID (Pk) | Nombre | Puesto (Pk) |
1 | Juan Pérez | Jefe de área |
2 | José Sánchez | Administrativo |
3 | Ana Díaz | Administrativo |
1 comentario
Hola, muchas gracias… pero he detectado algo: al final dices:
«Se añade el campo “Puesto” como Foreign Key:»
«ID (Pk) Nombre Puesto (Pk)»
En este último caso, la PK seria ID, Puesto no seria necesario como PK, ya que nos basta con ID para identificar un empleado. Efectivamente Puesto seria FK.
Gracias!