graph LR
A["👤 Cliente Web"] --> S[Sistema TechStyle]
B["👤 Vendedor"] --> S
C["👤 Gerente de Ventas"] --> S
D["👤 Gerente de Logística"] --> S
E["⚙️ Sistema de Pago Externo"] --> S
S --> F["⚙️ Sistema de Despacho"]
Modelo Relacional Completo, UML y MySQL Workbench · Semana 5 · Unidad II
2026-01-01
El trabajo de hoy es el último paso de diseño antes de construir.
TechStyle acaba de cerrar su proceso de rediseño de sistemas. María (Gerente de Marketing) y Carlos (Gerente de Logística) tienen nuevas demandas para Juan el analista de datos:
El modelo de W04 no cubre ninguna de estas necesidades. Hay que ampliarlo — y hacerlo bien antes de escribir una sola línea de SQL.
El error más común en diseño de bases de datos: empezar a crear tablas sin entender quién usa el sistema y para qué.
La herramienta para evitar ese error es el Diagrama de Casos de Uso (UML).
Responde tres preguntas antes de diseñar:
| Elemento | Símbolo | Descripción |
|---|---|---|
| Actor | Figura humana (stick figure) | Persona o sistema externo que interactúa |
| Caso de Uso | Elipse con texto | Acción que el sistema realiza para el actor |
| Asociación | Línea simple | Conecta actor con su caso de uso |
| Límite del sistema | Rectángulo grande | Separa lo que está dentro del sistema de lo externo |
Regla clave: el actor usa el sistema pero no vive dentro de él. Un cliente, un gerente, un sistema de pago externo son actores.
graph LR
A["👤 Cliente Web"] --> S[Sistema TechStyle]
B["👤 Vendedor"] --> S
C["👤 Gerente de Ventas"] --> S
D["👤 Gerente de Logística"] --> S
E["⚙️ Sistema de Pago Externo"] --> S
S --> F["⚙️ Sistema de Despacho"]
Cada actor tiene necesidades distintas → accede a funcionalidades distintas → necesita datos distintos → genera entidades distintas.
%%{init: {
'theme': 'base',
'themeVariables': {
'mainBkg': '#f8fafc',
'clusterBkg': '#dbeafe',
'clusterBorder': '#2563eb',
'titleColor': '#1e3a5f',
'nodeBkg': '#ffffff',
'nodeBorder': '#2563eb'
}
}}%%
graph TB
subgraph Sistema["Sistema TechStyle"]
UC1(["Registrar Venta"])
UC2(["Consultar Stock"])
UC3(["Gestionar Clientes"])
UC4(["Registrar Despacho"])
UC5(["Procesar Devolución"])
UC6(["Generar Reporte de Ventas"])
UC7(["Gestionar Proveedores"])
end
Cliente["👤 Cliente Web"] --> UC1
Vendedor["👤 Vendedor"] --> UC1
Vendedor --> UC2
Vendedor --> UC3
Logistica["👤 Gte. Logística"] --> UC4
Logistica --> UC2
Ventas["👤 Gte. Ventas"] --> UC6
Ventas --> UC5
Admin["👤 Administrador"] --> UC7
%% This line forces the background color of the subgraph %%
style Sistema fill:#f0f9ff,stroke:#2563eb,stroke-width:2px
Cada caso de uso que guarda o consulta información genera al menos una entidad en el modelo de datos.
| Caso de Uso | Entidades que genera |
|---|---|
| Registrar Venta | VENTA, DETALLE_VENTA |
| Gestionar Clientes | CLIENTE |
| Registrar Despacho | DESPACHO |
| Procesar Devolución | DEVOLUCION |
| Gestionar Proveedores | PROVEEDOR, PROVEEDOR_PRODUCTO |
Conclusión: el modelo de W04 (4 tablas) es incompleto para el sistema real de TechStyle. Necesitamos ampliarlo.
Para el caso de uso “Procesar Devolución”:
El Modelo Relacional es la representación final del diseño antes de implementar en SQL. Se expresa en notación textual:
TABLA(atributo1, atributo2, ...)
Ejemplo — TechStyle base (W04):
CLIENTE(cliente_id, nombre, apellido, email, region, segmento)
VENTA(venta_id, fecha, *cliente_id*)
PRODUCTO(producto_id, nombre_producto, categoria, precio_venta, stock)
DETALLE_VENTA(*venta_id*, *producto_id*, cantidad, precio_unitario, descuento_pct)
Roberto quiere saber qué proveedor abastece cada producto.
¿Cuál es la cardinalidad entre PROVEEDOR y PRODUCTO?
PROVEEDOR_PRODUCTO.erDiagram
PROVEEDOR {
INT proveedor_id PK
VARCHAR nombre_proveedor
VARCHAR rut
VARCHAR contacto
VARCHAR email
VARCHAR telefono
}
PROVEEDOR_PRODUCTO {
INT proveedor_id FK
INT producto_id FK
DECIMAL precio_compra
INT plazo_entrega_dias
BOOLEAN proveedor_principal
}
PRODUCTO {
INT producto_id PK
VARCHAR nombre_producto
}
PROVEEDOR ||--o{ PROVEEDOR_PRODUCTO : "abastece"
PRODUCTO ||--o{ PROVEEDOR_PRODUCTO : "es abastecido por"
Carlos necesita rastrear cada despacho: desde que sale de bodega hasta que llega al cliente.
erDiagram
VENTA {
INT venta_id PK
DATE fecha
INT cliente_id FK
}
DESPACHO {
INT despacho_id PK
INT venta_id FK
VARCHAR direccion_entrega
DATE fecha_despacho
DATE fecha_entrega_estimada
DATE fecha_entrega_real
VARCHAR estado
}
VENTA ||--o| DESPACHO : "genera"
¿Por qué 1:1 y no 1:N? En este negocio, cada venta genera exactamente un despacho. Si en el futuro TechStyle permite despachos parciales, cambia a 1:N — pero el modelo actual refleja la realidad de hoy.
erDiagram
VENTA {
INT venta_id PK
}
DEVOLUCION {
INT devolucion_id PK
INT venta_id FK
INT producto_id FK
DATE fecha_devolucion
INT cantidad_devuelta
VARCHAR motivo
VARCHAR estado
DECIMAL monto_reembolsado
}
PRODUCTO {
INT producto_id PK
}
VENTA ||--o{ DEVOLUCION : "puede originar"
PRODUCTO ||--o{ DEVOLUCION : "referencia"
Nota de diseño: DEVOLUCION referencia directamente PRODUCTO porque se devuelve un ítem específico, no toda la venta.
TechStyle quiere agregar un módulo de categorías con jerarquía. Ejemplo:
- Categoría padre: “Ropa”
- Subcategorías: “Poleras”, “Pantalones”, “Chaquetas”
erDiagram
CLIENTE {
INT cliente_id PK
VARCHAR nombre
VARCHAR apellido
VARCHAR email
VARCHAR region
VARCHAR segmento
DATE fecha_registro
}
VENTA {
INT venta_id PK
DATE fecha
INT cliente_id FK
}
DETALLE_VENTA {
INT venta_id FK
INT producto_id FK
INT cantidad
DECIMAL precio_unitario
DECIMAL descuento_pct
}
PRODUCTO {
INT producto_id PK
VARCHAR nombre_producto
INT categoria_id FK
DECIMAL precio_venta
DECIMAL costo_unitario
INT stock
}
CATEGORIA {
INT categoria_id PK
VARCHAR nombre_categoria
INT categoria_padre_id FK
}
PROVEEDOR {
INT proveedor_id PK
VARCHAR nombre_proveedor
VARCHAR email
VARCHAR telefono
}
PROVEEDOR_PRODUCTO {
INT proveedor_id FK
INT producto_id FK
DECIMAL precio_compra
BOOLEAN proveedor_principal
}
DESPACHO {
INT despacho_id PK
INT venta_id FK
VARCHAR direccion_entrega
DATE fecha_despacho
VARCHAR estado
}
DEVOLUCION {
INT devolucion_id PK
INT venta_id FK
INT producto_id FK
DATE fecha_devolucion
INT cantidad_devuelta
VARCHAR motivo
VARCHAR estado
}
CLIENTE ||--o{ VENTA : "realiza"
VENTA ||--|{ DETALLE_VENTA : "contiene"
PRODUCTO ||--o{ DETALLE_VENTA : "aparece en"
PRODUCTO }o--|| CATEGORIA : "pertenece a"
CATEGORIA ||--o{ CATEGORIA : "tiene subcategoría"
PROVEEDOR ||--o{ PROVEEDOR_PRODUCTO : "abastece"
PRODUCTO ||--o{ PROVEEDOR_PRODUCTO : "es abastecido por"
VENTA ||--o| DESPACHO : "genera"
VENTA ||--o{ DEVOLUCION : "puede originar"
PRODUCTO ||--o{ DEVOLUCION : "referencia"
MySQL Workbench es la herramienta oficial de Oracle para diseñar e implementar bases de datos MySQL.
Analogía: Workbench es a la base de datos lo que AutoCAD es a la arquitectura. Diseñas en el plano digital y el sistema genera los planos de construcción.
Pasos básicos:
Al crear la tabla CLIENTE en Workbench, la herramienta genera automáticamente:
CREATE TABLE IF NOT EXISTS `techstyle`.`clientes` (
`cliente_id` INT NOT NULL AUTO_INCREMENT,
`nombre` VARCHAR(50) NOT NULL,
`apellido` VARCHAR(50) NOT NULL,
`email` VARCHAR(100) NOT NULL,
`region` VARCHAR(50) NOT NULL,
`segmento` VARCHAR(20) NULL,
`fecha_registro` DATE NOT NULL,
PRIMARY KEY (`cliente_id`),
UNIQUE INDEX `email_UNIQUE` (`email` ASC)
) ENGINE=InnoDB;Observa: Workbench agrega AUTO_INCREMENT en la PK entera → MySQL genera el ID automáticamente al insertar. No necesitas calcularlo manualmente.
-- Sin AUTO_INCREMENT: tú calculas el siguiente ID
INSERT INTO clientes VALUES (1, 'Juan', 'Pérez', ...);
INSERT INTO clientes VALUES (2, 'María', 'López', ...);
-- Con AUTO_INCREMENT: MySQL lo calcula solo
INSERT INTO clientes (nombre, apellido, email, ...)
VALUES ('Juan', 'Pérez', 'juan@mail.com', ...);
-- MySQL asigna cliente_id = 1 automáticamente
INSERT INTO clientes (nombre, apellido, email, ...)
VALUES ('María', 'López', 'maria@mail.com', ...);
-- MySQL asigna cliente_id = 2 automáticamente¿Por qué es importante? Elimina el riesgo de IDs duplicados cuando múltiples usuarios insertan simultáneamente (lo que ocurre en todo sistema real).
Cuando conectas VENTA → CLIENTE en Workbench con la herramienta 1:N:
CREATE TABLE IF NOT EXISTS `techstyle`.`ventas` (
`venta_id` INT NOT NULL AUTO_INCREMENT,
`fecha` DATE NOT NULL,
`cliente_id` INT NOT NULL,
PRIMARY KEY (`venta_id`),
INDEX `fk_ventas_clientes_idx` (`cliente_id` ASC),
CONSTRAINT `fk_ventas_clientes`
FOREIGN KEY (`cliente_id`)
REFERENCES `techstyle`.`clientes` (`cliente_id`)
ON DELETE RESTRICT
ON UPDATE CASCADE
) ENGINE=InnoDB;ON DELETE RESTRICT: MySQL impide eliminar un cliente que tiene ventas.
ON UPDATE CASCADE: si cambia el cliente_id, se actualiza en VENTAS automáticamente.
| Opción | Comportamiento |
|---|---|
RESTRICT (por defecto) |
Bloquea la operación si hay registros dependientes |
CASCADE |
Propaga el cambio/eliminación a las filas hijas |
SET NULL |
Pone NULL en la FK cuando se elimina/modifica el padre |
NO ACTION |
Similar a RESTRICT, evaluado al final de la transacción |
Regla práctica para TechStyle:
ON DELETE RESTRICT (no borrar cliente con ventas).ON DELETE CASCADE (si se cancela la venta, se borran sus líneas).ON DELETE RESTRICT (no borrar venta con devoluciones).La tabla DESPACHO tiene la columna estado que puede ser: ‘Pendiente’, ‘En tránsito’, ‘Entregado’, ‘No entregado’.
VARCHAR(20) con CHECK y ENUM para este caso?El script DDL (Data Definition Language) es el conjunto ordenado de CREATE TABLE que construye toda la base de datos.
Regla de orden: crea primero las tablas que no tienen FK, luego las que sí.
1. CATEGORIA (no tiene FK externa)
2. CLIENTES (no tiene FK)
3. PROVEEDOR (no tiene FK)
4. PRODUCTO (FK → CATEGORIA)
5. VENTAS (FK → CLIENTES)
6. DETALLE_VENTA (FK → VENTAS, PRODUCTO)
7. PROVEEDOR_PRODUCTO (FK → PROVEEDOR, PRODUCTO)
8. DESPACHO (FK → VENTAS)
9. DEVOLUCION (FK → VENTAS, PRODUCTO)
Si creas VENTAS antes que CLIENTES, MySQL lanzará un error: la tabla referenciada no existe.
Un índice es una estructura auxiliar que MySQL mantiene para encontrar filas rápidamente sin escanear toda la tabla.
WHERE, JOIN).El CMI de Roberto que carga en 3 segundos vs. el que carga en 4 minutos depende, en parte, de los índices bien diseñados.
AUTO_INCREMENT garantiza unicidad de IDs en sistemas multiusuario.ON DELETE / ON UPDATE definen qué pasa con los datos hijos cuando cambia el padre — son decisiones de negocio, no solo técnicas.Lab W05: Diseñando el Modelo Completo en MySQL Workbench
El entregable de hoy es el plano de arquitectura de la base de datos de TechStyle. Las semanas 6 y 7 lo convertirán en realidad.
Big Data y Analytics · USS · 2026