Base de datos relacional: JOIN y normalización
Al finalizar este tema
Podrás explicar por qué se dividen las tablas y escribirás consultas SQL para combinar datos mediante JOIN.
Una sola tabla no es suficiente
Imagina que estás creando una tienda en línea. ¿Qué pasaría si colocaras toda la información de los pedidos en una única tabla?
orders (toda la información en una tabla):
+----+--------+-------+----------+--------+
| id | cliente | email | producto | precio |
+----+--------+-------+----------+--------+
| 1 | Ana | a@ex | portátil | 1500 € |
| 2 | Ana | a@ex | ratón | 50 € |
| 3 | Luis | l@ex | teclado | 100 € |
+----+--------+-------+----------+--------+¿Observa el problema?
- Duplicación: "Kim Hun" y "h@ex" se repiten en cada pedido.
- Riesgo de modificación: Si Kim Hun cambia su correo electrónico, deberá corregir todas las filas; si omite alguna, habrá inconsistencias.
- Riesgo de eliminación: Si elimina todos los pedidos de Kim Hun, la información del cliente desaparecerá por completo.
Separación de tablas: el principio básico de la normalización
La solución consiste en separar los datos relacionados en tablas diferentes.
tabla users: tabla orders:
+----+--------+-------+ +----+---------+----------+--------+
| id | name | email | | id | user_id | product | price |
+----+--------+-------+ +----+---------+----------+--------+
| 1 | Ana | a@ex | | 1 | 1 | portátil | 1500 € |
| 2 | Luis | l@ex | | 2 | 1 | ratón | 50 € |
+----+--------+-------+ | 3 | 2 | teclado | 100 € |
+----+---------+----------+--------+orders.user_id hace referencia a users.id. Esto es una clave externa (Foreign Key), el enlace que conecta dos tablas.
El proceso de eliminar redundancias y separar las tablas se denomina normalización.
JOIN: combinar tablas separadas
Ahora que hemos dividido las tablas, necesitamos un método para volver a unirlas. Ese método es JOIN.
-- Consultar la lista de pedidos junto con el nombre del cliente
SELECT users.name, orders.product, orders.price
FROM orders
JOIN users ON orders.user_id = users.id;Resultado:
+--------+----------+--------+
| name | product | price |
+--------+----------+--------+
| Ana | portátil | 1500 € |
| Ana | ratón | 50 € |
| Luis | teclado | 100 € |
+--------+----------+--------+JOIN ... ON especifica la columna que se utilizará como criterio de coincidencia. orders.user_id = users.id — combina las filas en las que el user_id del pedido coincide con el ID del usuario.
Tipos de JOIN
-- INNER JOIN: solo las filas que coinciden en ambas tablas (opción predeterminada)
SELECT * FROM orders JOIN users ON orders.user_id = users.id;
-- LEFT JOIN: todas las filas de la tabla izquierda y solo las coincidencias de la derecha
-- También incluye a clientes sin pedidos
SELECT users.name, orders.product
FROM users
LEFT JOIN orders ON users.id = orders.user_id;
-- Resultado: para clientes sin pedidos, product aparece como NULL| Tipo de JOIN | Descripción |
|---|---|
INNER JOIN | Solo las filas que coinciden en ambas tablas |
LEFT JOIN | Todas las filas de la tabla izquierda, más las coincidencias de la tabla derecha cuando existen |
RIGHT JOIN | Todas las filas de la tabla derecha, más las coincidencias de la tabla izquierda cuando existen |
En la práctica, se utilizan más frecuentemente INNER JOIN y LEFT JOIN.
Normalización: ¿Por qué dividir los datos?
El principio fundamental de la normalización es simple: cada dato debe almacenarse en un solo lugar.
| Antes de la normalización | Después de la normalización | Efecto |
|---|---|---|
| El nombre del cliente se repite en cada pedido | Se almacena una sola vez en la tabla users | Eliminación de duplicados |
| Al cambiar el correo electrónico, se deben modificar varias filas | Solo se modifica una fila | Garantía de consistencia |
| Al eliminar un pedido, se pierde la información del cliente | El cliente existe de forma independiente | Conservación de los datos |
La normalización no siempre es la mejor opción: si las tablas se dividen en demasiadas partes, las operaciones JOIN pueden volverse complejas y el rendimiento puede disminuir. En la práctica, a veces se permite intencionalmente la redundancia para mejorar el rendimiento (desnormalización). Sin embargo, la normalización es la base.