Relación muchos a muchos en MariaDB: productos y proveedores
En este tutorial vamos a ver cómo modelar una relación muchos a muchos en MariaDB usando una tabla intermedia, partiendo de una base de datos ya existente con las tablas:
familiasproductosclientes
El objetivo es permitir que un producto pueda tener varios proveedores y que un proveedor pueda servir varios productos.
Tabla de contenidos
1. Crear la tabla proveedores
Primero creamos la tabla de proveedores:
CREATE TABLE proveedores (
id INT AUTO_INCREMENT PRIMARY KEY,
nombre VARCHAR(120) NOT NULL,
telefono VARCHAR(20),
email VARCHAR(120)
);
Insertamos algunos proveedores de ejemplo:
INSERT INTO proveedores (nombre, telefono, email) VALUES
('Ingram Micro', '971111111', 'ventas@ingrammicro.com'),
('Tech Data', '971222222', 'contacto@techdata.com'),
('Esprinet', '971333333', 'info@esprinet.com'),
('Amazon Business', '971444444', 'b2b@amazon.com'),
('Distribuciones PC Mallorca', '971555555', 'ventas@pcmallorca.com');
Comprobamos:
SELECT * FROM proveedores;
2. Por qué necesitamos una tabla intermedia
En la tabla productos ya tenemos una clave foránea hacia familias, lo que implica que:
- Un producto solo puede pertenecer a una familia
- Pero un producto puede tener varios proveedores
Esto no se puede resolver con una sola clave foránea, así que necesitamos una tabla intermedia.
3. Crear la tabla intermedia productos_proveedores
Esta tabla relaciona productos y proveedores y además guarda información extra: el precio de compra.
CREATE TABLE productos_proveedores (
id_producto INT NOT NULL,
id_proveedor INT NOT NULL,
precio_compra DECIMAL(10,2),
PRIMARY KEY (id_producto, id_proveedor),
FOREIGN KEY (id_producto) REFERENCES productos(id)
ON DELETE CASCADE,
FOREIGN KEY (id_proveedor) REFERENCES proveedores(id)
ON DELETE CASCADE
);
Puntos importantes:
- La clave primaria compuesta evita duplicar la misma relación.
ON DELETE CASCADEborra automáticamente las relaciones si se elimina un producto o proveedor.
4. Error típico al insertar datos (clave foránea)
Si intentamos insertar relaciones usando IDs de productos que no existen, obtendremos un error:
INSERT INTO productos_proveedores (id_producto, id_proveedor, precio_compra)
VALUES (1, 1, 95.00);
Error:
Cannot add or update a child row: a foreign key constraint fails
Esto ocurre porque el producto con id 1 no existe.
5. Insertar datos correctamente
Primero comprobamos los IDs reales:
SELECT id, nombre FROM productos;
SELECT id, nombre FROM proveedores;
Usando IDs existentes, el insert funciona:
INSERT INTO productos_proveedores (id_producto, id_proveedor, precio_compra) VALUES
(2, 1, 150.00),
(2, 2, 152.50),
(5, 1, 120.00),
(5, 3, 118.00);
Comprobamos:
SELECT * FROM productos_proveedores;
6. Consultar datos con JOIN
La tabla intermedia solo contiene IDs, así que para ver información útil necesitamos un JOIN.
SELECT
p.nombre AS producto,
pr.nombre AS proveedor,
pp.precio_compra
FROM productos_proveedores pp
JOIN productos p ON p.id = pp.id_producto
JOIN proveedores pr ON pr.id = pp.id_proveedor;
Esta consulta nos permite ver:
- Qué proveedor vende cada producto
- A qué precio de compra
- Comparar proveedores para el mismo producto
7. Conclusión
- Las relaciones muchos a muchos se resuelven con tablas intermedias
- Las claves foráneas garantizan la integridad de los datos
- Los errores de clave foránea indican que estamos usando IDs inexistentes
- Los
JOINson imprescindibles para obtener información legible
En el siguiente paso trabajaremos estas relaciones con esquemas y ejercicios prácticos.