Modelado físico avanzado relacional de bases de datos
En este módulo, aplicaremos lo aprendido en procedimientos almacenados, funciones y triggers mediante casos prácticos. Además, desarrollaremos un proyecto final para consolidar conocimientos.
1. Caso Práctico: Automatización de Procesos con Procedimientos Almacenados
📌 Escenario:
Una empresa quiere automatizar el cálculo de salarios considerando bonificaciones del 10% para empleados con más de 5 años de antigüedad.
Solución con Procedimiento Almacenado
1DELIMITER // 2 3CREATE PROCEDURE CalcularSalario(IN emp_id INT, OUT salario_final DECIMAL(10,2)) 4BEGIN 5 DECLARE salario_base DECIMAL(10,2); 6 DECLARE antiguedad INT; 7 8 -- Obtener salario base y antigüedad del empleado 9 SELECT sueldo, TIMESTAMPDIFF(YEAR, fecha_contratacion, NOW()) 10 INTO salario_base, antiguedad 11 FROM empleados WHERE id = emp_id; 12 13 -- Aplicar bonificación si corresponde 14 IF antiguedad > 5 THEN 15 SET salario_final = salario_base * 1.10; 16 ELSE 17 SET salario_final = salario_base; 18 END IF; 19END // 20 21DELIMITER ; 22 23-- Uso: 24CALL CalcularSalario(1, @salario); 25SELECT @salario;
2. Caso Práctico: Seguridad y Control con Triggers
📌 Escenario:
Queremos evitar que un empleado con rol de "Admin" pueda ser eliminado accidentalmente.
Solución con Trigger
1CREATE TRIGGER PrevenirEliminacionAdmin 2BEFORE DELETE ON empleados 3FOR EACH ROW 4BEGIN 5 IF OLD.rol = 'Admin' THEN 6 SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'No puedes eliminar a un administrador'; 7 END IF; 8END;
3. Proyecto Final: Implementación de una Lógica de Negocio Completa
📌 Escenario:
Desarrollaremos un sistema para gestionar ventas y stock en una tienda.
El sistema deberá:
✅ Registrar una nueva venta.
✅ Verificar si hay stock disponible antes de realizar la venta.
✅ Descontar el stock del producto vendido.
✅ Guardar un registro de auditoría con cada venta realizada.
📌 Diseño de Tablas
1CREATE TABLE productos ( 2 id INT PRIMARY KEY AUTO_INCREMENT, 3 nombre VARCHAR(50), 4 stock INT NOT NULL, 5 precio DECIMAL(10,2) NOT NULL 6); 7 8CREATE TABLE ventas ( 9 id INT PRIMARY KEY AUTO_INCREMENT, 10 producto_id INT, 11 cantidad INT NOT NULL, 12 fecha TIMESTAMP DEFAULT CURRENT_TIMESTAMP, 13 FOREIGN KEY (producto_id) REFERENCES productos(id) 14); 15 16CREATE TABLE auditoria_ventas ( 17 id INT PRIMARY KEY AUTO_INCREMENT, 18 mensaje TEXT, 19 fecha TIMESTAMP DEFAULT CURRENT_TIMESTAMP 20);
📌 Procedimiento para Registrar Ventas
1DELIMITER // 2 3CREATE PROCEDURE RegistrarVenta(IN prod_id INT, IN cantidad INT) 4BEGIN 5 DECLARE stock_actual INT; 6 7 -- Obtener stock actual 8 SELECT stock INTO stock_actual FROM productos WHERE id = prod_id; 9 10 -- Verificar si hay stock suficiente 11 IF stock_actual >= cantidad THEN 12 -- Registrar la venta 13 INSERT INTO ventas (producto_id, cantidad) VALUES (prod_id, cantidad); 14 -- Actualizar stock 15 UPDATE productos SET stock = stock - cantidad WHERE id = prod_id; 16 ELSE 17 SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Error: Stock insuficiente'; 18 END IF; 19END // 20 21DELIMITER ; 22 23-- Uso: 24CALL RegistrarVenta(1, 3);
📌 Trigger para Registrar Auditoría
1CREATE TRIGGER RegistrarAuditoriaVenta 2AFTER INSERT ON ventas 3FOR EACH ROW 4BEGIN 5 INSERT INTO auditoria_ventas (mensaje) VALUES (CONCAT('Venta realizada de ', NEW.cantidad, ' unidades del producto ', NEW.producto_id)); 6END;
4. Optimización y Buenas Prácticas
✅ Usar Índices
1CREATE INDEX idx_producto_id ON ventas(producto_id);
✅ Evitar Cursores cuando sea posible
Usar JOIN en lugar de cursores para consultas eficientes.
✅ Validaciones en la Aplicación y en la Base de Datos
Es recomendable validar datos tanto en la aplicación como en la base de datos.