¿Te resulta más fácil leer con fondo crema, un tono de color, más contraste o un texto más grande? Elige tus colores y tu texto una sola vez, para todas las páginas.

Lección gratuita

Normalización: quitar datos repetidos

Después de esta lección: Puedo quitar los datos repetidos de un diseño dividiéndolo en tablas.

Lección de 45 min9 comandosLaboratorio de MySQL y phpMyAdmin con una base de datos de una tienda para practicar SQL

El tutor que cambió de nombre

Una hoja de excursiones escribe el nombre del tutor en cada fila. Cuando cambia el tutor de un grupo, hay que corregir cien filas, y siempre se olvida alguna.

La normalización es el método para ordenar las tablas de modo que cada dato se escriba una sola vez. Así, un cambio se hace en un solo sitio.

Al terminar esta lección

Nota

Puedo quitar los datos repetidos de un diseño dividiéndolo en tablas.

Palabras clave

PalabraQué significa
Redundanciael mismo dato escrito en más de un sitio
Normalizacióndividir las tablas para que cada dato se guarde una vez
Anomalíaun fallo que causa un dato repetido al cambiar, añadir o borrar
Primera forma normalun solo valor en cada celda y sin campos repetidos
Tercera forma normalcada campo depende solo de la clave primaria
DISTINCTdeja una sola copia de cada resultado repetido

Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.

Un dato repetido es un fallo esperando

Mira la hoja de excursiones. El tutor de Lucia sale en tres filas y el coste de la visita al museo sale en tres filas también. Son datos redundantes.

Esa redundancia causa tres anomalías. Al cambiar un dato, hay que cambiarlo en todas partes. Al añadir un lugar nuevo, no cabe sin una excursión. Al borrar la última excursión de un lugar, desaparece el lugar.

Ejemplo resuelto: la hoja plana con sus repeticiones

trip_nostudenttutorplacecost
1Lucia PerezSra OrtegaMuseo12
2Lucia PerezSra OrtegaGranja9
3Mario GilSr VegaMuseo12
8Lucia PerezSra OrtegaAcuario15

Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.

Pruébalo: contar las repeticiones

Código: sql
-- Cuántas veces sale cada tutor en la hoja plana.
SELECT tutor, COUNT(*) AS veces FROM trips_flat GROUP BY tutor;
-- Un tutor que se repite es un dato escrito muchas veces.
-- Cambia tutor por place y mira qué otro dato se repite.

Las formas normales ordenan el diseño

Primera forma normal: un solo valor en cada celda. Nada de "Museo, Granja" en una misma celda, ni de campos como place1 y place2.

Segunda forma normal: cada campo depende de toda la clave, no de una parte.

Tercera forma normal: cada campo depende solo de la clave, y no de otro campo. El tutor depende del alumno y no del número de excursión.

Ejemplo resuelto: de una hoja a tres tablas

TablaCamposClave primariaQué guarda una vez
studentsname, tutornameEl tutor de cada alumno
placesplace, costplaceEl coste de cada lugar
bookingstrip_no, student, placetrip_noQuién fue a dónde

Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.

Preparar el terminal

Nota

Con el laboratorio iniciado, ejecuta las líneas siguientes. Crean tu base student_library si todavía no existe y usan una hoja plana nueva. Ninguna toca la tienda.

Aceptar el certificado del servidor

Comando
printf '[client]\nssl-verify-server-cert=0\n' > ~/.my.cnf

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Crear tu base si falta

Comando
mariadb -h db -u student -pstudent -e "CREATE DATABASE IF NOT EXISTS student_library"

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Un nombre corto para ella

Comando
alias lib='mariadb -h db -u student -pstudent student_library -t -e'

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Empezar de cero

Comando
lib "DROP TABLE IF EXISTS flat_loans, students, books, loans"

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Crear la hoja plana de préstamos

Comando
lib "CREATE TABLE flat_loans (loan_id INT PRIMARY KEY, student VARCHAR(40), tutor VARCHAR(40), title VARCHAR(40), author VARCHAR(40))"

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Llenarla con seis préstamos

Comando
lib "INSERT INTO flat_loans VALUES (1, 'Lucia Perez', 'Sra Ortega', 'Don Quijote', 'Cervantes'), (2, 'Lucia Perez', 'Sra Ortega', 'La Celestina', 'Rojas'), (3, 'Mario Gil', 'Sr Vega', 'Don Quijote', 'Cervantes'), (4, 'Mario Gil', 'Sr Vega', 'Rimas', 'Becquer'), (5, 'Sara Vidal', 'Sr Vega', 'La Celestina', 'Rojas'), (6, 'Lucia Perez', 'Sra Ortega', 'Rimas', 'Becquer')"

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Dividir una tabla es copiar sin repetir

Para dividir, crea una tabla nueva con solo los campos que pertenecen a una cosa. DISTINCT deja una sola copia de cada fila repetida.

La hoja tiene seis préstamos, pero solo tres alumnos y tres libros. Las tablas nuevas tendrán tres filas cada una.

La tabla de alumnos, sin repetir

Comando
lib "CREATE TABLE students AS SELECT DISTINCT student AS name, tutor FROM flat_loans"

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

La tabla de libros, sin repetir

Comando
lib "CREATE TABLE books AS SELECT DISTINCT title, author FROM flat_loans"

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Ver la tabla de alumnos

Comando
lib "SELECT name, tutor FROM students ORDER BY name"

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Pruébalo: filas sin repetir

Código: sql
-- Cada alumno y su tutor, una sola vez.
SELECT DISTINCT student, tutor FROM trips_flat ORDER BY student;
-- Cámbialo para sacar cada lugar con su coste, una sola vez.

Un error frecuente

Advertencia

Mucha gente cree que dividir una tabla es solo cortarla en trozos. Falta lo más importante: cada tabla necesita su clave primaria, y la tabla que enlaza guarda las claves de las otras. Si no, no puedes volver a unir los datos.

Para ir más lejos: la lista de compra

Una hoja guarda en cada fila un pedido con su cliente, el teléfono del cliente, el producto y el precio del producto. Escribe en papel qué tablas saldrían.

Para cada tabla, di cuál es la clave primaria. Después busca en la tienda del laboratorio qué tabla guarda cada uno de esos datos.

Sobre este laboratorio y su código: Laboratorio de MySQL y phpMyAdmin con una base de datos de una tienda para practicar SQL

¿Enseñas a una clase? Asigna este módulo a tus alumnos con guía del profesor, tareas con corrección automática y un laboratorio para cada alumno.