====== 02 - Normalización ====== La **normalización** comprueba que los datos están bien repartidos entre tablas: cada dato se guarda **una sola vez**. El diseño parte del diagrama de clases (tema 01); estas reglas lo **validan** y detectan los errores que la traducción no muestra. ===== 1. Una tabla mal diseñada ===== ¿Qué pasa si libros y editoriales se mezclan en una única tabla? Los datos de la editorial se repiten en todas sus filas: CREATE TABLE book ( id BIGINT AUTO_INCREMENT PRIMARY KEY, title VARCHAR(200) NOT NULL, price DECIMAL(10,2) NOT NULL, publisher_name VARCHAR(100) NOT NULL, publisher_city VARCHAR(100) NOT NULL ); ^ Anomalía ^ Con esta tabla ^ | **Inserción** | No se puede guardar una editorial sin que tenga libros: no hay fila donde poner sus datos | | **Actualización** | Cambiar la ciudad de una editorial obliga a actualizar **todas** sus filas; si una se queda atrás, la tabla se contradice | | **Borrado** | Borrar el último libro de una editorial borra también sus datos | La redundancia es la causa: el mismo dato, copiado en muchas filas, se actualiza — o se pierde — de forma incompleta. Se corrige al llegar a la **tercera forma normal**. ===== 2. Primera forma normal (1FN) ===== Cada valor debe ser **atómico**: una columna guarda un dato simple, no una colección: -- mal: la colección de autores dentro de la fila del libro CREATE TABLE book ( id BIGINT AUTO_INCREMENT PRIMARY KEY, title VARCHAR(200) NOT NULL, author_names VARCHAR(400) NOT NULL -- 'Robert Martin, Martin Fowler' ); Tampoco valen los **grupos repetitivos**: columnas gemelas tipo ''author1'', ''author2''..., que obligan a estimar cuántas hacen falta y dejan huecos vacíos. La solución es la del modelo relacional: las colecciones se convierten en **tablas**. En este caso, la tabla de unión ''book_author'' vista en el tema 01. ===== 3. Segunda forma normal (2FN) ===== Con **clave primaria compuesta**, cada columna debe depender de la clave **completa**, no de una parte: CREATE TABLE book_author ( book_id BIGINT NOT NULL, author_id BIGINT NOT NULL, author_nationality VARCHAR(80), -- depende solo de author_id PRIMARY KEY (book_id, author_id) ); ''author_nationality'' cambia con el **autor**, no con el par (libro, autor): se repetiría en todos los libros de un autor y una actualización a medias lo rompería. La columna pertenece a la tabla ''author'', cuya clave es la que la determina. ===== 4. Tercera forma normal (3FN) ===== Cada columna debe depender **solo de la clave primaria**, no de otra columna no clave (dependencia **transitiva**). En la tabla del apartado 1: ''id'' → ''publisher_city'' → ''publisher_name''. La corrección crea una tabla para la editorial y deja en ''book'' solo la clave foránea: CREATE TABLE publisher ( id BIGINT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(100) NOT NULL, city VARCHAR(100) NOT NULL ); CREATE TABLE book ( id BIGINT AUTO_INCREMENT PRIMARY KEY, title VARCHAR(200) NOT NULL, price DECIMAL(10,2) NOT NULL, publisher_id BIGINT NOT NULL, FOREIGN KEY (publisher_id) REFERENCES publisher (id) ); Cada dato se guarda una sola vez: la editorial existe por sí misma y sus libros la referencian. ===== 5. Resumen ===== ^ Forma ^ Comprueba que ^ Solución típica ^ | **1FN** | Los valores son atómicos | Tabla propia para la colección | | **2FN** | Con clave compuesta, todo depende de la clave completa | La columna se va con la tabla de la parte que la determina | | **3FN** | Nadie depende de otra columna no clave | Tabla propia para la entidad dependiente | El diseño sale del diagrama de clases y la traducción del tema 01 ya suele dar tablas casi normalizadas. Repasar 1FN–3FN es la comprobación final: si algo falla, falta — o sobra — una entidad o un atributo en el diagrama.