SEÑAL — RECEPCIÓN — 局 03.6 CARGANDO BITÁCORA
霧
M3S1 · Programación · Periodo Febrero–Julio 2026

Soluciones Completas SECUENCIAS 02 — 12 · BITÁCORA DE EVIDENCIAS

Registro íntegro de los casos, modelos entidad-relación, código SQL, diseño multidimensional y conclusiones trabajadas a lo largo del semestre. Cada apartado conserva un espacio reservado para capturas y evidencia fotográfica.

Mtro. Enrique Badillo Barranco — registro compilado para entrega final

Nota de apertura

Este documento reúne, secuencia por secuencia, el trabajo resuelto durante el curso de Programación (M3S1): modelado entidad-relación, lenguaje SQL para creación y consulta de bases de datos, normalización, diseño multidimensional (OLAP) y el proceso ETL. Concluyendo con el proyecto final, la base de datos y el sistema CRUD.

Secuencia 02

「Modelo Entidad-Relación」

9 — 13 de febrero de 2026

Ejercicios integradores. Para cada caso se identifican entidades, atributos, relaciones y cardinalidad.

Caso 1 — Sistema de Renta de Vehículos

ENTIDADES · ATRIBUTOS · CARDINALIDAD

Entidades y atributos

EntidadAtributos
CLIENTEid_cliente (PK), nombre, apellido, telefono, correo, direccion, fecha_nacimiento, licencia, tipo_licencia
VEHICULOid_vehiculo (PK), placa, marca, modelo, anio, color, tipo, kilometraje, precio_dia, disponible
CONTRATOid_contrato (PK), fecha_inicio, fecha_fin, total, deposito, estado, id_cliente (FK), id_vehiculo (FK), lugar_entrega, observaciones

Relaciones y cardinalidad

  • CLIENTE — realiza → CONTRATO (1:N) — un cliente puede tener muchos contratos.
  • VEHICULO — aparece en → CONTRATO (1:N) — un vehículo puede tener muchos contratos en distintas fechas.

Descripción del diagrama E-R

CLIENTE (óvalo con atributos) —[realiza]— CONTRATO —[pertenece a]— VEHICULO. Cardinalidad: CLIENTE 1:N CONTRATO ; VEHICULO 1:N CONTRATO.

Evidencia — Caso 1 meow.

Caso 2 — Sistema de Eventos y Boletos

ENTIDADES · ATRIBUTOS · CARDINALIDAD

Entidades y atributos

EntidadAtributos
CLIENTEid_cliente (PK), nombre, apellido, correo, telefono, direccion, fecha_registro, tipo_usuario, metodo_pago
EVENTOid_evento (PK), nombre, descripcion, fecha, hora, lugar, capacidad, precio_general, organizador, categoria
BOLETOid_boleto (PK), codigo, tipo_asiento, precio, fecha_compra, estado, id_cliente (FK), id_evento (FK), numero_asiento, forma_pago

Relaciones y cardinalidad

  • CLIENTE — compra → BOLETO (1:N) — un cliente puede comprar muchos boletos.
  • EVENTO — tiene → BOLETO (1:N) — un evento puede tener muchos boletos.
  • CLIENTE ↔ EVENTO vía BOLETO (N:M).
Evidencia — Caso 2 meow.

Caso 3 — Sistema de Gimnasio

ENTIDADES · ATRIBUTOS · CARDINALIDAD

Entidades y atributos

EntidadAtributos
SOCIOid_socio (PK), nombre, apellido, telefono, correo, fecha_inscripcion, tipo_membresia, fecha_nacimiento, peso, estatura
ENTRENADORid_entrenador (PK), nombre, apellido, especialidad, certificacion, telefono, correo, anos_experiencia, horario, salario
RUTINAid_rutina (PK), nombre, descripcion, nivel_dificultad, duracion_minutos, objetivo, fecha_creacion, id_entrenador (FK), tipo_ejercicio, frecuencia_semanal

Relaciones y cardinalidad

  • ENTRENADOR — crea → RUTINA (1:N) — un entrenador puede crear muchas rutinas.
  • SOCIO ↔ RUTINA (N:M) — un socio puede tener varias rutinas y una rutina puede asignarse a muchos socios.
  • Tabla intermedia: ASIGNACION(id_asignacion PK, id_socio FK, id_rutina FK, fecha_asignacion, estado).
Evidencia — Caso 3
galería adicional — secuencia 02
Evidencia extra 01
Evidencia extra 02
Evidencia extra 03
Secuencia 03 y 04

「Diseño Lógico con SQL」

16 — 27 de febrero de 2026

Código SQL completo para los cinco ejercicios planteados: creación de bases de datos, tablas, llaves foráneas y datos de ejemplo.

Ejercicio 1 — Sistema de Biblioteca Intercultural

RELACIÓN N:M ENTRE AUTOR Y LIBRO
sql · BibliotecaIntercultural
      
CREATE DATABASE BibliotecaIntercultural;
USE BibliotecaIntercultural;

CREATE TABLE Autor (
    id_autor INT PRIMARY KEY AUTO_INCREMENT,
    nombre VARCHAR(100) NOT NULL,
    nacionalidad VARCHAR(50)
);

CREATE TABLE Libro (
    ISBN VARCHAR(20) PRIMARY KEY,
    titulo VARCHAR(150) NOT NULL,
    anio INT
);

-- Relacion N:M entre Autor y Libro
CREATE TABLE Autor_Libro (
    id_autor INT,
    ISBN VARCHAR(20),
    PRIMARY KEY (id_autor, ISBN),
    FOREIGN KEY (id_autor) REFERENCES Autor(id_autor),
    FOREIGN KEY (ISBN) REFERENCES Libro(ISBN)
);

CREATE TABLE Usuario (
    id_usuario INT PRIMARY KEY AUTO_INCREMENT,
    nombre VARCHAR(100) NOT NULL,
    correo VARCHAR(100)
);

CREATE TABLE Prestamo (
    id_prestamo INT PRIMARY KEY AUTO_INCREMENT,
    fecha_inicio DATE,
    fecha_devolucion DATE,
    id_usuario INT,
    ISBN VARCHAR(20),
    FOREIGN KEY (id_usuario) REFERENCES Usuario(id_usuario),
    FOREIGN KEY (ISBN) REFERENCES Libro(ISBN)
);

-- Datos de ejemplo
INSERT INTO Autor (nombre, nacionalidad) VALUES
('Gabriel Garcia Marquez', 'Colombiana'),
('Octavio Paz', 'Mexicana'),
('Isabel Allende', 'Chilena');

INSERT INTO Libro (ISBN, titulo, anio) VALUES
('978-1', 'Cien Anos de Soledad', 1967),
('978-2', 'El Laberinto de la Soledad', 1950),
('978-3', 'La Casa de los Espiritus', 1982);

INSERT INTO Autor_Libro VALUES (1,'978-1'), (2,'978-2'), (3,'978-3');

INSERT INTO Usuario (nombre, correo) VALUES
('Maria Lopez', 'maria@mail.com'),
('Pedro Ruiz', 'pedro@mail.com');

INSERT INTO Prestamo (fecha_inicio, fecha_devolucion, id_usuario, ISBN) VALUES
('2025-09-01', '2025-09-15', 1, '978-1'),
('2025-09-05', NULL, 2, '978-2');
Evidencia — Ejercicio 1meow.

Ejercicio 2 — Centro de Desarrollo Infantil

RELACIÓN N:M NIÑO – ACTIVIDAD
sql · CentroInfantil
      
CREATE DATABASE CentroInfantil;
USE CentroInfantil;

CREATE TABLE Educadora (
    clave INT PRIMARY KEY AUTO_INCREMENT,
    nombre VARCHAR(100) NOT NULL,
    especialidad VARCHAR(80)
);

CREATE TABLE Actividad (
    codigo INT PRIMARY KEY AUTO_INCREMENT,
    nombre VARCHAR(100) NOT NULL,
    horario VARCHAR(50),
    clave_educadora INT,
    FOREIGN KEY (clave_educadora) REFERENCES Educadora(clave)
);

CREATE TABLE Nino (
    matricula INT PRIMARY KEY AUTO_INCREMENT,
    nombre VARCHAR(100) NOT NULL,
    edad INT
);

-- Relacion N:M Nino - Actividad
CREATE TABLE Nino_Actividad (
    matricula INT,
    codigo INT,
    PRIMARY KEY (matricula, codigo),
    FOREIGN KEY (matricula) REFERENCES Nino(matricula),
    FOREIGN KEY (codigo) REFERENCES Actividad(codigo)
);

INSERT INTO Educadora (nombre, especialidad) VALUES
('Lupita Gomez', 'Musica'), ('Rosa Medina', 'Arte');

INSERT INTO Actividad (nombre, horario, clave_educadora) VALUES
('Musica y ritmo', 'Lunes 9:00', 1),
('Pintura creativa', 'Martes 10:00', 2),
('Canto coral', 'Miercoles 9:00', 1);

INSERT INTO Nino (nombre, edad) VALUES
('Sofia R.', 4), ('Diego M.', 5), ('Camila P.', 4);

INSERT INTO Nino_Actividad VALUES (1,1),(1,2),(2,1),(2,3),(3,2);
Evidencia — Ejercicio 2meow.

Ejercicio 3 — Sistema de Huerto Escolar

RELACIÓN N:M ESTUDIANTE – PARCELA
sql · HuertoEscolar
-- 
CREATE DATABASE HuertoEscolar;
USE HuertoEscolar;

CREATE TABLE Parcela (
    numero_parcela INT PRIMARY KEY AUTO_INCREMENT,
    tamanio DECIMAL(8,2)   -- metros cuadrados
);

CREATE TABLE Cultivo (
    codigo INT PRIMARY KEY AUTO_INCREMENT,
    nombre VARCHAR(80) NOT NULL,
    tipo VARCHAR(50),
    numero_parcela INT,
    FOREIGN KEY (numero_parcela) REFERENCES Parcela(numero_parcela)
);

CREATE TABLE Estudiante (
    id_estudiante INT PRIMARY KEY AUTO_INCREMENT,
    nombre VARCHAR(100) NOT NULL,
    grupo VARCHAR(20)
);

-- N:M Estudiante - Parcela
CREATE TABLE Estudiante_Parcela (
    id_estudiante INT,
    numero_parcela INT,
    PRIMARY KEY (id_estudiante, numero_parcela),
    FOREIGN KEY (id_estudiante) REFERENCES Estudiante(id_estudiante),
    FOREIGN KEY (numero_parcela) REFERENCES Parcela(numero_parcela)
);

INSERT INTO Parcela (tamanio) VALUES (20.5),(15.0),(30.0);

INSERT INTO Cultivo (nombre, tipo, numero_parcela) VALUES
('Jitomate','Hortaliza',1),('Chile','Hortaliza',1),
('Cilantro','Hierba',2),('Maiz','Cereal',3);

INSERT INTO Estudiante (nombre, grupo) VALUES
('Ana P.','3A'),('Luis Q.','3B'),('Fernanda R.','3A');

INSERT INTO Estudiante_Parcela VALUES (1,1),(1,3),(2,2),(3,1),(3,2);
Evidencia — Ejercicio 3meow.

Ejercicio 4 — Plataforma de Cursos de Programación

RELACIÓN N:M ESTUDIANTE – CURSO
sql · PlataformaCursos
CREATE DATABASE PlataformaCursos;
USE PlataformaCursos;

CREATE TABLE Instructor (
    id_instructor INT PRIMARY KEY AUTO_INCREMENT,
    nombre VARCHAR(100) NOT NULL,
    especialidad VARCHAR(80)
);

CREATE TABLE Curso (
    codigo INT PRIMARY KEY AUTO_INCREMENT,
    nombre VARCHAR(100) NOT NULL,
    duracion INT,   -- horas
    id_instructor INT,
    FOREIGN KEY (id_instructor) REFERENCES Instructor(id_instructor)
);

CREATE TABLE Estudiante (
    id_estudiante INT PRIMARY KEY AUTO_INCREMENT,
    nombre VARCHAR(100) NOT NULL,
    correo VARCHAR(100)
);

-- N:M Estudiante - Curso
CREATE TABLE Inscripcion (
    id_estudiante INT,
    codigo INT,
    fecha_inscripcion DATE,
    PRIMARY KEY (id_estudiante, codigo),
    FOREIGN KEY (id_estudiante) REFERENCES Estudiante(id_estudiante),
    FOREIGN KEY (codigo) REFERENCES Curso(codigo)
);

INSERT INTO Instructor (nombre, especialidad) VALUES
('Carlos Vega', 'Python'), ('Ana Rios', 'Web');

INSERT INTO Curso (nombre, duracion, id_instructor) VALUES
('Python Basico', 40, 1),('HTML y CSS', 30, 2),('Python Avanzado', 60, 1);

INSERT INTO Estudiante (nombre, correo) VALUES
('Pedro M.', 'pedro@mail.com'),('Laura S.', 'laura@mail.com');

INSERT INTO Inscripcion VALUES
(1,1,'2025-09-01'),(1,3,'2025-09-15'),(2,2,'2025-09-01'),(2,1,'2025-09-10');
Evidencia — Ejercicio 4meow.

Ejercicio 5 — Clínica Comunitaria

RELACIÓN 1:N PACIENTE / MEDICO – CONSULTA
sql · ClinicaComunitaria
CREATE DATABASE ClinicaComunitaria;
USE ClinicaComunitaria;

CREATE TABLE Paciente (
    num_expediente INT PRIMARY KEY AUTO_INCREMENT,
    nombre VARCHAR(100) NOT NULL,
    edad INT
);

CREATE TABLE Medico (
    cedula INT PRIMARY KEY AUTO_INCREMENT,
    nombre VARCHAR(100) NOT NULL,
    especialidad VARCHAR(80)
);

CREATE TABLE Consulta (
    id_consulta INT PRIMARY KEY AUTO_INCREMENT,
    fecha DATE NOT NULL,
    diagnostico VARCHAR(200),
    num_expediente INT,
    cedula INT,
    FOREIGN KEY (num_expediente) REFERENCES Paciente(num_expediente),
    FOREIGN KEY (cedula) REFERENCES Medico(cedula)
);

INSERT INTO Paciente (nombre, edad) VALUES
('Juan Torres', 45),('Maria Garcia', 30),('Pedro Soto', 60);

INSERT INTO Medico (nombre, especialidad) VALUES
('Dr. Lopez', 'General'),('Dra. Ruiz', 'Cardiologia');

INSERT INTO Consulta (fecha, diagnostico, num_expediente, cedula) VALUES
('2025-10-01','Hipertension leve',1,2),
('2025-10-02','Gripe comun',2,1),
('2025-10-03','Control de rutina',3,2);
Evidencia — Ejercicio 5meow.
galería adicional — secuencia 03–04
Evidencia extra 01
Evidencia extra 02
Evidencia extra 03
Evidencia extra 04
Secuencia 05

「Normalización — Galería de Arte」

2 — 6 de marzo de 2026

Identificación de entidades y atributos, cardinalidades, código SQL normalizado y demostración del cumplimiento de las cinco formas normales.

Entidades y atributos identificados

EntidadAtributosPK
PERSONAid_persona, nombre, correo, telefonoid_persona
ARTISTA (subconjunto de Persona)id_persona (FK), estilo_predominanteid_persona
OBRAnum_registro, titulo, estilo, precio_salida, id_artista (FK)num_registro
PROPIETARIO_OBRAid_persona (FK), num_registro (FK)id_persona + num_registro
EXPOSICIONid_exposicion, titulo, descripcion, fecha_inauguracion, fecha_clausuraid_exposicion
OBRA_EXPOSICIONnum_registro (FK), id_exposicion (FK)num_registro + id_exposicion
OFERTAid_oferta, monto, fecha, id_persona (FK), num_registro (FK)id_oferta

Relaciones y cardinalidades

  • PERSONA — es artista de → OBRA (1:N) — una persona-artista puede crear muchas obras.
  • PERSONA — posee → OBRA (N:M) — una persona puede poseer varias obras; una obra tiene un propietario.
  • EXPOSICION ↔ OBRA (N:M) — una exposición tiene muchas obras; una obra puede estar en varias exposiciones.
  • PERSONA — hace → OFERTA (1:N) — una persona puede hacer muchas ofertas.
  • OBRA — recibe → OFERTA (1:N) — una obra puede recibir muchas ofertas.

Código SQL — Galería de Arte (cumple 5FN)

sql · GaleriaArte
CREATE DATABASE GaleriaArte;
USE GaleriaArte;

-- 1FN, 2FN, 3FN: Sin grupos repetidos, sin dependencias parciales ni transitivas
CREATE TABLE Persona (
    id_persona INT PRIMARY KEY AUTO_INCREMENT,
    nombre VARCHAR(100) NOT NULL,
    correo VARCHAR(100),
    telefono VARCHAR(20)
);

-- Especializacion: una persona puede ser artista
CREATE TABLE Artista (
    id_persona INT PRIMARY KEY,
    estilo_predominante VARCHAR(80),
    FOREIGN KEY (id_persona) REFERENCES Persona(id_persona)
);

CREATE TABLE Exposicion (
    id_exposicion INT PRIMARY KEY AUTO_INCREMENT,
    titulo VARCHAR(150) NOT NULL,
    descripcion TEXT,
    fecha_inauguracion DATE,
    fecha_clausura DATE
);

CREATE TABLE Obra (
    num_registro INT PRIMARY KEY AUTO_INCREMENT,
    titulo VARCHAR(150) NOT NULL,
    estilo VARCHAR(80),
    precio_salida DECIMAL(12,2),
    id_artista INT,
    FOREIGN KEY (id_artista) REFERENCES Artista(id_persona)
);

-- Una obra tiene un propietario actual (puede ser distinto al artista)
CREATE TABLE Propietario_Obra (
    id_persona INT,
    num_registro INT,
    PRIMARY KEY (id_persona, num_registro),
    FOREIGN KEY (id_persona) REFERENCES Persona(id_persona),
    FOREIGN KEY (num_registro) REFERENCES Obra(num_registro)
);

-- N:M Obra - Exposicion
CREATE TABLE Obra_Exposicion (
    num_registro INT,
    id_exposicion INT,
    PRIMARY KEY (num_registro, id_exposicion),
    FOREIGN KEY (num_registro) REFERENCES Obra(num_registro),
    FOREIGN KEY (id_exposicion) REFERENCES Exposicion(id_exposicion)
);

CREATE TABLE Oferta (
    id_oferta INT PRIMARY KEY AUTO_INCREMENT,
    monto DECIMAL(12,2) NOT NULL,
    fecha DATE NOT NULL,
    id_persona INT,
    num_registro INT,
    ganadora BOOLEAN DEFAULT FALSE,
    FOREIGN KEY (id_persona) REFERENCES Persona(id_persona),
    FOREIGN KEY (num_registro) REFERENCES Obra(num_registro)
);

-- Datos de ejemplo
INSERT INTO Persona (nombre, correo) VALUES
('Frida Mendez','frida@art.mx'),
('Diego Vargas','diego@art.mx'),
('Carlos Rios','carlos@col.mx'),
('Laura Vega','laura@col.mx');

INSERT INTO Artista VALUES (1,'Surrealismo'),(2,'Muralismo');

INSERT INTO Exposicion (titulo, descripcion, fecha_inauguracion, fecha_clausura) VALUES
('Arte Moderno MX','Exposicion de arte contemporaneo mexicano','2025-11-01','2025-11-30');

INSERT INTO Obra (titulo, estilo, precio_salida, id_artista) VALUES
('Sueno Roto','Surrealismo',50000.00,1),
('Raices','Muralismo',80000.00,2);

INSERT INTO Propietario_Obra VALUES (1,1),(2,2);
INSERT INTO Obra_Exposicion VALUES (1,1),(2,1);

INSERT INTO Oferta (monto, fecha, id_persona, num_registro) VALUES
(52000,'2025-11-25',3,1),
(85000,'2025-11-26',4,2);

Demostración de formas normales

Forma normalCumplimiento
1FN — Valores atómicosTodos los campos son atómicos, sin grupos repetidos ni listas.
2FN — Sin dependencias parcialesLas claves compuestas (Propietario_Obra, Obra_Exposicion) no tienen atributos con dependencia parcial.
3FN — Sin dependencias transitivasNo hay atributos que dependan de otros atributos no clave.
4FN — Sin dependencias multivaluadasPropietario y Exposicion son tablas independientes, sin multivaluados.
5FN — Sin dependencias de joinCada relación N:M se maneja con tabla intermedia; no hay información perdida al descomponer.
Evidencia — Secuencia 05meow.
porsilasmoscas

meow.

"Una base de datos bien normalizada no olvida nada — solo guarda cada cosa en el lugar que le corresponde."

Secuencia 06

「Caso Clínica — Ejercicios SQL」

9 — 13 de marzo de 2026

Planteamiento 1 — Pacientes mayores de 20 años

sql
-- Mostrar nombre, direccion y edad de pacientes con edad > 20
SELECT nombre, direccion, edad
FROM Paciente
WHERE edad > 20;
Resultado esperado: Carlos López (30), María Torres (25), José Martínez (40).

Planteamiento 2 — Todas las citas registradas

sql
-- Mostrar fecha, hora y motivo de todas las citas
SELECT fecha, hora, motivo
FROM Cita;
Resultado esperado: las tres citas insertadas — Consulta general, Dolor de pecho, Revisión pediátrica.
Evidencia — Secuencia 06meow.
Secuencia 07

「Caso Hotel — Consultas SQL」

16 — 20 de marzo de 2026

Planteamiento 1 — Reservas de más de 2 días

sql
-- Mostrar clientes y fechas de reservas que duran mas de 2 dias
SELECT
    Cliente.nombre AS Cliente,
    Reserva.fecha_entrada,
    Reserva.fecha_salida,
    DATEDIFF(Reserva.fecha_salida, Reserva.fecha_entrada) AS dias_estancia
FROM Reserva
INNER JOIN Cliente ON Reserva.id_cliente = Cliente.id_cliente
WHERE DATEDIFF(Reserva.fecha_salida, Reserva.fecha_entrada) > 2;
Resultado esperado: Ana López (3 días) es la única que cumple la condición. Rodolfo Pérez y Luis García tienen exactamente 2 días, por lo que no aparecen ya que la condición exige estrictamente más de 2.

Planteamiento 2 — Habitaciones tipo Doble

sql
-- Mostrar habitaciones de tipo Doble
SELECT numero, tipo, precio
FROM Habitacion
WHERE tipo = 'Doble';
Resultado esperado: habitación 102, tipo Doble, $800.00.

Actividad 3 — Sistema de Viajes (diagrama E-R: Viajero–Viaje–Destino–Origen)

VIAJERO 1:N VIAJE · VIAJE 1:1 DESTINO · VIAJE 1:1 ORIGEN
sql · SistemaViajes
CREATE DATABASE SistemaViajes;
USE SistemaViajes;

CREATE TABLE Origen (
    codigo INT PRIMARY KEY AUTO_INCREMENT,
    nombre VARCHAR(100) NOT NULL,
    otros VARCHAR(100)
);

CREATE TABLE Destino (
    codigo INT PRIMARY KEY AUTO_INCREMENT,
    nombre VARCHAR(100) NOT NULL,
    otros VARCHAR(100)
);

CREATE TABLE Viajero (
    DNI INT PRIMARY KEY,
    nombre VARCHAR(100) NOT NULL,
    direccion VARCHAR(150),
    telefono VARCHAR(20)
);

CREATE TABLE Viaje (
    codigo INT PRIMARY KEY AUTO_INCREMENT,
    num_plazas INT NOT NULL,
    fecha_del_viaje DATE NOT NULL,
    otros VARCHAR(100),
    DNI_viajero INT,
    codigo_destino INT,
    codigo_origen INT,
    FOREIGN KEY (DNI_viajero) REFERENCES Viajero(DNI),
    FOREIGN KEY (codigo_destino) REFERENCES Destino(codigo),
    FOREIGN KEY (codigo_origen) REFERENCES Origen(codigo)
);

-- Datos de ejemplo
INSERT INTO Origen (nombre, otros) VALUES
('Ciudad de Mexico','Capital'),
('Guadalajara','Jalisco'),
('Monterrey','Nuevo Leon');

INSERT INTO Destino (nombre, otros) VALUES
('Cancun','Quintana Roo'),
('Los Cabos','Baja California Sur'),
('Oaxaca','Oaxaca');

INSERT INTO Viajero (DNI, nombre, direccion, telefono) VALUES
(1001,'Luis Hernandez','Av. Reforma 100','7711234567'),
(1002,'Ana Martinez','Calle Juarez 45','7717654321'),
(1003,'Carlos Perez','Col. Centro 200','7719876543');

INSERT INTO Viaje (num_plazas, fecha_del_viaje, DNI_viajero, codigo_destino, codigo_origen) VALUES
(2,'2025-12-20',1001,1,1),
(1,'2025-12-25',1002,2,2),
(4,'2026-01-05',1003,3,3);

-- Consultas de ejemplo: ver viajes con viajero, origen y destino
SELECT
    V.nombre AS Viajero,
    Vi.fecha_del_viaje,
    Vi.num_plazas,
    O.nombre AS Origen,
    D.nombre AS Destino
FROM Viaje Vi
INNER JOIN Viajero V ON Vi.DNI_viajero = V.DNI
INNER JOIN Origen O ON Vi.codigo_origen = O.codigo
INNER JOIN Destino D ON Vi.codigo_destino = D.codigo;
Evidencia — Secuencia 07meow.
galería adicional — secuencia 06–07
Evidencia extra 01
Evidencia extra 02
Evidencia extra 03
Secuencia 08

「Consumo de Energía Eléctrica」

23 — 27 de marzo de 2026

Ejercicio 3: modelo multidimensional para el análisis del consumo eléctrico.

Modelo multidimensional

ElementoDetalle
HechoConsumo (kWh)
Dimensión Tiempomes, año
Dimensión Zonatipo: urbana / rural
Dimensión Tipo de usuariohogar, negocio, industria

¿Qué permite analizar este modelo?

  • Patrones de consumo: cuánto se consume por mes o año y en qué temporadas hay mayor uso.
  • Diferencias por tipo de usuario: comparar consumo entre hogares, negocios e industrias.
  • Distribución geográfica: qué zonas, urbanas o rurales, consumen más energía.
  • Tendencias: incrementos o disminuciones en el consumo a lo largo del tiempo.
  • Toma de decisiones: optimizar el suministro, implementar estrategias de ahorro y planificar infraestructura.

Código SQL — Consumo de Energía

sql · EnergiaDW
CREATE DATABASE EnergiaDW;
USE EnergiaDW;

-- Dimension Tiempo
CREATE TABLE Tiempo (
    id_tiempo INT PRIMARY KEY AUTO_INCREMENT,
    mes VARCHAR(20),
    anio INT
);

-- Dimension Zona
CREATE TABLE Zona (
    id_zona INT PRIMARY KEY AUTO_INCREMENT,
    tipo VARCHAR(20) CHECK (tipo IN ('urbana','rural'))
);

-- Dimension Tipo de Usuario
CREATE TABLE TipoUsuario (
    id_tipo INT PRIMARY KEY AUTO_INCREMENT,
    categoria VARCHAR(30) CHECK (categoria IN ('hogar','negocio','industria'))
);

-- Tabla de Hechos: Consumo
CREATE TABLE Consumo (
    id_consumo INT PRIMARY KEY AUTO_INCREMENT,
    id_tiempo INT,
    id_zona INT,
    id_tipo INT,
    kwh DECIMAL(10,2),
    FOREIGN KEY (id_tiempo) REFERENCES Tiempo(id_tiempo),
    FOREIGN KEY (id_zona) REFERENCES Zona(id_zona),
    FOREIGN KEY (id_tipo) REFERENCES TipoUsuario(id_tipo)
);

-- Insertar datos
INSERT INTO Tiempo (mes, anio) VALUES
('Enero',2025),('Febrero',2025),('Marzo',2025),
('Abril',2025),('Mayo',2025),('Junio',2025);

INSERT INTO Zona (tipo) VALUES ('urbana'),('rural');

INSERT INTO TipoUsuario (categoria) VALUES
('hogar'),('negocio'),('industria');

INSERT INTO Consumo (id_tiempo, id_zona, id_tipo, kwh) VALUES
(1,1,1,1200),(1,1,2,3500),(1,1,3,9000),
(1,2,1,800),(1,2,2,1500),(1,2,3,4000),
(2,1,1,1100),(2,1,2,3200),(2,1,3,8500),
(3,1,1,950),(3,2,1,780),(3,2,2,1400),
(4,1,3,9500),(5,1,1,1050),(6,1,2,3800);

-- CONSULTAS OLAP

-- Consumo total por tipo de usuario (decidir donde enfocar ahorro)
SELECT
    TipoUsuario.categoria,
    SUM(Consumo.kwh) AS total_kwh
FROM Consumo
INNER JOIN TipoUsuario ON Consumo.id_tipo = TipoUsuario.id_tipo
GROUP BY TipoUsuario.categoria
ORDER BY total_kwh DESC;

-- Consumo por mes (detectar temporadas pico)
SELECT
    Tiempo.mes,
    Tiempo.anio,
    SUM(Consumo.kwh) AS total_kwh
FROM Consumo
INNER JOIN Tiempo ON Consumo.id_tiempo = Tiempo.id_tiempo
GROUP BY Tiempo.mes, Tiempo.anio
ORDER BY total_kwh DESC;

-- Consumo por zona
SELECT
    Zona.tipo AS zona,
    SUM(Consumo.kwh) AS total_kwh
FROM Consumo
INNER JOIN Zona ON Consumo.id_zona = Zona.id_zona
GROUP BY Zona.tipo;

Toma de decisiones

  • ¿A qué sector enfocar campañas de ahorro? → Al sector industria, que consume más kWh.
  • ¿En qué meses reforzar el suministro? → Abril y junio, meses con mayor consumo.
  • ¿Qué zona requiere mayor inversión en infraestructura? → La zona urbana por mayor demanda total.
Evidencia — Secuencia 08meow.
Secuencia 09

「Modelos Multidimensionales — Ejercicios 1, 2 y 3」

13 — 17 de abril de 2026

Ejercicio 1 — Ventas de Supermercado

¿Qué permite analizar?

  • Productos más vendidos por categoría y sucursal.
  • Ventas por período de tiempo (día, mes, año).
  • Qué sucursal tiene mayor rendimiento.
  • Toma de decisiones: ajustar inventario y mejorar estrategias de venta por sucursal.
sql · SupermercadoDW
CREATE DATABASE SupermercadoDW;
USE SupermercadoDW;

CREATE TABLE Tiempo (
    id_tiempo INT PRIMARY KEY AUTO_INCREMENT,
    dia INT, mes VARCHAR(20), anio INT
);

CREATE TABLE Producto (
    id_producto INT PRIMARY KEY AUTO_INCREMENT,
    nombre VARCHAR(80),
    categoria VARCHAR(50)
);

CREATE TABLE Sucursal (
    id_sucursal INT PRIMARY KEY AUTO_INCREMENT,
    nombre VARCHAR(80),
    ciudad VARCHAR(50)
);

CREATE TABLE Ventas (
    id_venta INT PRIMARY KEY AUTO_INCREMENT,
    id_tiempo INT, id_producto INT, id_sucursal INT,
    cantidad INT, total DECIMAL(10,2),
    FOREIGN KEY (id_tiempo) REFERENCES Tiempo(id_tiempo),
    FOREIGN KEY (id_producto) REFERENCES Producto(id_producto),
    FOREIGN KEY (id_sucursal) REFERENCES Sucursal(id_sucursal)
);

INSERT INTO Tiempo (dia, mes, anio) VALUES
(1,'Enero',2025),(15,'Enero',2025),(5,'Febrero',2025),
(20,'Febrero',2025),(10,'Marzo',2025);

INSERT INTO Producto (nombre, categoria) VALUES
('Leche Lala 1L','Lacteos'),
('Pan Bimbo','Panaderia'),
('Coca-Cola 600ml','Bebidas'),
('Arroz 1kg','Granos'),
('Aceite 1L','Aceites');

INSERT INTO Sucursal (nombre, ciudad) VALUES
('Sucursal Norte','Pachuca'),
('Sucursal Centro','Pachuca'),
('Sucursal Sur','Tulancingo');

INSERT INTO Ventas (id_tiempo,id_producto,id_sucursal,cantidad,total) VALUES
(1,1,1,50,750),(1,2,1,30,450),(2,3,2,80,960),
(3,4,3,40,600),(4,1,2,60,900),(5,5,1,25,875),
(3,2,3,45,675),(4,3,1,90,1080);

-- CONSULTAS

-- Productos mas vendidos
SELECT
    p.nombre, p.categoria,
    SUM(v.cantidad) AS unidades_vendidas,
    SUM(v.total) AS total_ventas
FROM Ventas v
INNER JOIN Producto p ON v.id_producto = p.id_producto
GROUP BY p.nombre, p.categoria
ORDER BY total_ventas DESC;

-- Ventas por sucursal
SELECT
    s.nombre AS sucursal,
    SUM(v.total) AS total_ventas
FROM Ventas v
INNER JOIN Sucursal s ON v.id_sucursal = s.id_sucursal
GROUP BY s.nombre
ORDER BY total_ventas DESC;
Evidencia — Ejercicio 1uwu.

Ejercicio 2 — Asistencia Escolar

¿Qué permite analizar?

  • Patrones de asistencia y ausentismo por alumno, grupo y fecha.
  • Días o meses con mayor ausentismo.
  • Comparar asistencia entre grupos.
  • Toma de decisiones: implementar tutorías y seguimiento para mejorar la asistencia.
sql · AsistenciaEscolarDW
CREATE DATABASE AsistenciaEscolarDW;
USE AsistenciaEscolarDW;

CREATE TABLE Alumno (
    id_alumno INT PRIMARY KEY AUTO_INCREMENT,
    nombre VARCHAR(100)
);

CREATE TABLE Fecha (
    id_fecha INT PRIMARY KEY AUTO_INCREMENT,
    dia INT, mes VARCHAR(20), anio INT
);

CREATE TABLE Grupo (
    id_grupo INT PRIMARY KEY AUTO_INCREMENT,
    nombre VARCHAR(20),
    grado VARCHAR(20)
);

-- Tabla de Hechos
CREATE TABLE Asistencias (
    id_asistencia INT PRIMARY KEY AUTO_INCREMENT,
    id_alumno INT, id_fecha INT, id_grupo INT,
    presente TINYINT(1),   -- 1 = asistio, 0 = falto
    FOREIGN KEY (id_alumno) REFERENCES Alumno(id_alumno),
    FOREIGN KEY (id_fecha) REFERENCES Fecha(id_fecha),
    FOREIGN KEY (id_grupo) REFERENCES Grupo(id_grupo)
);

INSERT INTO Alumno (nombre) VALUES
('Juan Perez'),('Maria Lopez'),('Carlos Ruiz'),
('Ana Torres'),('Pedro Soto');

INSERT INTO Fecha (dia, mes, anio) VALUES
(7,'Abril',2025),(8,'Abril',2025),(9,'Abril',2025),
(10,'Abril',2025),(14,'Abril',2025);

INSERT INTO Grupo (nombre, grado) VALUES
('4A','Cuarto'),('4B','Cuarto'),('4C','Cuarto');

INSERT INTO Asistencias (id_alumno,id_fecha,id_grupo,presente) VALUES
(1,1,1,1),(1,2,1,1),(1,3,1,0),(1,4,1,1),(1,5,1,0),
(2,1,1,1),(2,2,1,0),(2,3,1,1),(2,4,1,1),(2,5,1,1),
(3,1,2,0),(3,2,2,0),(3,3,2,1),(3,4,2,1),(3,5,2,0),
(4,1,2,1),(4,2,2,1),(4,3,2,1),(4,4,2,0),(4,5,2,1),
(5,1,3,1),(5,2,3,1),(5,3,3,1),(5,4,3,1),(5,5,3,1);

-- CONSULTAS

-- Porcentaje de asistencia por alumno
SELECT
    a.nombre,
    SUM(ast.presente) AS dias_asistidos,
    COUNT(*) AS total_dias,
    ROUND(SUM(ast.presente)/COUNT(*)*100, 1) AS porcentaje_asistencia
FROM Asistencias ast
INNER JOIN Alumno a ON ast.id_alumno = a.id_alumno
GROUP BY a.nombre
ORDER BY porcentaje_asistencia ASC;

-- Ausentismo por grupo (para estrategias de mejora)
SELECT
    g.nombre AS grupo,
    SUM(CASE WHEN ast.presente = 0 THEN 1 ELSE 0 END) AS total_faltas,
    COUNT(*) AS registros_totales
FROM Asistencias ast
INNER JOIN Grupo g ON ast.id_grupo = g.id_grupo
GROUP BY g.nombre
ORDER BY total_faltas DESC;
Evidencia — Ejercicio 2uwu.

Ejercicio 3 — Uso de Transporte Público

¿Qué permite analizar?

  • Rutas y horarios más utilizados.
  • Tipo de usuario que más usa el transporte (estudiante, trabajador, adulto mayor).
  • Variación del uso por mes o día de la semana.
  • Toma de decisiones: optimizar rutas frecuentes y aumentar unidades en horarios pico.
sql · TransporteDW
CREATE DATABASE TransporteDW;
USE TransporteDW;

CREATE TABLE Ruta (
    id_ruta INT PRIMARY KEY AUTO_INCREMENT,
    nombre VARCHAR(80),
    origen VARCHAR(80),
    destino VARCHAR(80)
);

CREATE TABLE Tiempo (
    id_tiempo INT PRIMARY KEY AUTO_INCREMENT,
    dia INT, mes VARCHAR(20), hora INT
);

CREATE TABLE Usuario (
    id_usuario INT PRIMARY KEY AUTO_INCREMENT,
    tipo VARCHAR(30)  -- estudiante, trabajador, adulto mayor
);

-- Tabla de Hechos
CREATE TABLE Viajes (
    id_viaje INT PRIMARY KEY AUTO_INCREMENT,
    id_ruta INT, id_tiempo INT, id_usuario INT,
    num_viajes INT,
    FOREIGN KEY (id_ruta) REFERENCES Ruta(id_ruta),
    FOREIGN KEY (id_tiempo) REFERENCES Tiempo(id_tiempo),
    FOREIGN KEY (id_usuario) REFERENCES Usuario(id_usuario)
);

INSERT INTO Ruta (nombre, origen, destino) VALUES
('Ruta 1','Centro','Universidad'),
('Ruta 2','Norte','Hospital'),
('Ruta 3','Sur','Centro Comercial'),
('Ruta 4','Este','Estacion Central');

INSERT INTO Tiempo (dia, mes, hora) VALUES
(7,'Abril',7),(7,'Abril',8),(7,'Abril',14),
(8,'Abril',7),(8,'Abril',13),(8,'Mayo',8);

INSERT INTO Usuario (tipo) VALUES
('estudiante'),('trabajador'),('adulto mayor'),('estudiante'),('trabajador');

INSERT INTO Viajes (id_ruta,id_tiempo,id_usuario,num_viajes) VALUES
(1,1,1,120),(1,2,2,200),(2,1,3,80),(2,2,2,150),
(3,3,1,90),(4,4,2,180),(1,5,4,110),(3,6,5,130),
(2,4,1,95),(4,3,5,160);

-- CONSULTAS

-- Rutas mas utilizadas (para aumentar unidades)
SELECT
    r.nombre AS ruta,
    SUM(v.num_viajes) AS total_viajes
FROM Viajes v
INNER JOIN Ruta r ON v.id_ruta = r.id_ruta
GROUP BY r.nombre
ORDER BY total_viajes DESC;

-- Horarios pico (para optimizar frecuencias)
SELECT
    t.hora,
    SUM(v.num_viajes) AS total_viajes
FROM Viajes v
INNER JOIN Tiempo t ON v.id_tiempo = t.id_tiempo
GROUP BY t.hora
ORDER BY total_viajes DESC;
Evidencia — Ejercicio 3uwu.
galería adicional — secuencia 09
Evidencia extra 01
Evidencia extra 02
Evidencia extra 03
Secuencia 11

「Modelos Multidimensionales — Ejercicios 10, 11 y 12」

27 de abril — 1 de mayo de 2026

Ejercicio 10 — Cine

¿Qué permite analizar?

  • Películas más vistas y en qué horarios.
  • Salas con mayor afluencia.
  • Preferencias del público por género de película.
  • Toma de decisiones: programar más funciones de las películas exitosas y ajustar horarios según la demanda.
sql · CineDW
CREATE DATABASE CineDW;
USE CineDW;

CREATE TABLE Pelicula (
    id_pelicula INT PRIMARY KEY AUTO_INCREMENT,
    titulo VARCHAR(150),
    genero VARCHAR(50),
    duracion_min INT
);

CREATE TABLE Horario (
    id_horario INT PRIMARY KEY AUTO_INCREMENT,
    hora VARCHAR(10),
    dia_semana VARCHAR(20),
    mes VARCHAR(20)
);

CREATE TABLE Sala (
    id_sala INT PRIMARY KEY AUTO_INCREMENT,
    nombre VARCHAR(50),
    capacidad INT
);

-- Tabla de Hechos: Boletos vendidos
CREATE TABLE Boletos (
    id_registro INT PRIMARY KEY AUTO_INCREMENT,
    id_pelicula INT, id_horario INT, id_sala INT,
    boletos_vendidos INT,
    ingreso DECIMAL(10,2),
    FOREIGN KEY (id_pelicula) REFERENCES Pelicula(id_pelicula),
    FOREIGN KEY (id_horario) REFERENCES Horario(id_horario),
    FOREIGN KEY (id_sala) REFERENCES Sala(id_sala)
);

INSERT INTO Pelicula (titulo, genero, duracion_min) VALUES
('El Ultimo Heroe','Accion',130),
('Amor en Roma','Romance',110),
('La Sombra Oscura','Terror',100),
('Mundos Infinitos','Ciencia Ficcion',145),
('Risa Garantizada','Comedia',95);

INSERT INTO Horario (hora, dia_semana, mes) VALUES
('16:00','Lunes','Abril'),('19:00','Lunes','Abril'),
('21:00','Viernes','Abril'),('16:00','Sabado','Abril'),
('19:00','Sabado','Abril'),('21:00','Sabado','Mayo');

INSERT INTO Sala (nombre, capacidad) VALUES
('Sala 1',150),('Sala 2',200),('Sala 3',120);

INSERT INTO Boletos (id_pelicula,id_horario,id_sala,boletos_vendidos,ingreso) VALUES
(1,1,1,120,2400),(1,2,2,180,3600),(4,3,2,195,3900),
(2,4,3,90,1800),(3,5,1,130,2600),(5,5,3,100,2000),
(4,6,2,200,4000),(1,6,1,140,2800),(2,3,3,70,1400);

-- CONSULTAS

-- Peliculas mas vistas (para programar mas funciones)
SELECT
    p.titulo, p.genero,
    SUM(b.boletos_vendidos) AS total_boletos,
    SUM(b.ingreso) AS total_ingreso
FROM Boletos b
INNER JOIN Pelicula p ON b.id_pelicula = p.id_pelicula
GROUP BY p.titulo, p.genero
ORDER BY total_boletos DESC;

-- Horarios con mayor afluencia (para ajustar funciones)
SELECT
    h.hora, h.dia_semana,
    SUM(b.boletos_vendidos) AS total_boletos
FROM Boletos b
INNER JOIN Horario h ON b.id_horario = h.id_horario
GROUP BY h.hora, h.dia_semana
ORDER BY total_boletos DESC;
Evidencia — Ejercicio 10uwu.

Ejercicio 11 — Banco

¿Qué permite analizar?

  • Tipos de operaciones más frecuentes (depósito, retiro, transferencia, pago).
  • Clientes con mayor actividad bancaria.
  • Períodos con mayor volumen de transacciones.
  • Toma de decisiones: mejorar canales digitales y reforzar atención en fechas pico.
sql · BancoDW
CREATE DATABASE BancoDW;
USE BancoDW;

CREATE TABLE Cliente (
    id_cliente INT PRIMARY KEY AUTO_INCREMENT,
    tipo_cliente VARCHAR(30),  -- personal, empresarial
    edad INT
);

CREATE TABLE TipoOperacion (
    id_operacion INT PRIMARY KEY AUTO_INCREMENT,
    nombre VARCHAR(50)   -- deposito, retiro, transferencia, pago
);

CREATE TABLE Fecha (
    id_fecha INT PRIMARY KEY AUTO_INCREMENT,
    dia INT, mes VARCHAR(20), anio INT
);

-- Tabla de Hechos: Transacciones
CREATE TABLE Transacciones (
    id_transaccion INT PRIMARY KEY AUTO_INCREMENT,
    id_cliente INT, id_operacion INT, id_fecha INT,
    monto DECIMAL(12,2),
    num_operaciones INT,
    FOREIGN KEY (id_cliente) REFERENCES Cliente(id_cliente),
    FOREIGN KEY (id_operacion) REFERENCES TipoOperacion(id_operacion),
    FOREIGN KEY (id_fecha) REFERENCES Fecha(id_fecha)
);

INSERT INTO Cliente (tipo_cliente, edad) VALUES
('personal',35),('empresarial',0),('personal',28),
('personal',55),('empresarial',0);

INSERT INTO TipoOperacion (nombre) VALUES
('Deposito'),('Retiro'),('Transferencia'),('Pago de servicio');

INSERT INTO Fecha (dia, mes, anio) VALUES
(1,'Abril',2025),(15,'Abril',2025),(30,'Abril',2025),
(1,'Mayo',2025),(15,'Mayo',2025);

INSERT INTO Transacciones (id_cliente,id_operacion,id_fecha,monto,num_operaciones) VALUES
(1,1,1,5000,3),(1,2,1,2000,2),(2,3,2,50000,10),
(3,4,3,800,5),(4,2,4,3000,4),(5,3,4,120000,15),
(1,4,5,1200,8),(3,1,5,4000,6),(2,1,2,80000,12);

-- CONSULTAS

-- Operaciones mas frecuentes (para mejorar canales)
SELECT
    op.nombre AS tipo_operacion,
    SUM(t.num_operaciones) AS total_operaciones,
    SUM(t.monto) AS monto_total
FROM Transacciones t
INNER JOIN TipoOperacion op ON t.id_operacion = op.id_operacion
GROUP BY op.nombre
ORDER BY total_operaciones DESC;

-- Volumen por mes (para detectar fechas pico)
SELECT
    f.mes,
    SUM(t.num_operaciones) AS total_operaciones,
    SUM(t.monto) AS monto_movido
FROM Transacciones t
INNER JOIN Fecha f ON t.id_fecha = f.id_fecha
GROUP BY f.mes
ORDER BY total_operaciones DESC;
Evidencia — Ejercicio 11meow.

Ejercicio 12 — Plataforma de Streaming

¿Qué permite analizar?

  • Contenidos más vistos (series, películas, documentales).
  • Horarios de mayor consumo.
  • Perfil de usuarios que más consumen.
  • Toma de decisiones: recomendar contenido personalizado y mejorar el catálogo según preferencias.
sql · StreamingDW
CREATE DATABASE StreamingDW;
USE StreamingDW;

CREATE TABLE Usuario (
    id_usuario INT PRIMARY KEY AUTO_INCREMENT,
    edad INT,
    pais VARCHAR(50),
    plan VARCHAR(30)  -- basico, estandar, premium
);

CREATE TABLE Contenido (
    id_contenido INT PRIMARY KEY AUTO_INCREMENT,
    titulo VARCHAR(150),
    tipo VARCHAR(30),    -- serie, pelicula, documental
    genero VARCHAR(50)
);

CREATE TABLE Tiempo (
    id_tiempo INT PRIMARY KEY AUTO_INCREMENT,
    hora INT,
    dia_semana VARCHAR(20),
    mes VARCHAR(20)
);

-- Tabla de Hechos: Reproducciones
CREATE TABLE Reproducciones (
    id_rep INT PRIMARY KEY AUTO_INCREMENT,
    id_usuario INT, id_contenido INT, id_tiempo INT,
    num_reproducciones INT,
    minutos_vistos INT,
    FOREIGN KEY (id_usuario) REFERENCES Usuario(id_usuario),
    FOREIGN KEY (id_contenido) REFERENCES Contenido(id_contenido),
    FOREIGN KEY (id_tiempo) REFERENCES Tiempo(id_tiempo)
);

INSERT INTO Usuario (edad, pais, plan) VALUES
(22,'Mexico','estandar'),(35,'Mexico','premium'),
(17,'Colombia','basico'),(45,'Mexico','premium'),
(28,'Argentina','estandar');

INSERT INTO Contenido (titulo, tipo, genero) VALUES
('La Casa de Papel','serie','thriller'),
('Avengers Endgame','pelicula','accion'),
('Nuestro Planeta','documental','naturaleza'),
('Dark','serie','misterio'),
('Interstellar','pelicula','ciencia ficcion');

INSERT INTO Tiempo (hora, dia_semana, mes) VALUES
(20,'Lunes','Abril'),(22,'Viernes','Abril'),
(21,'Sabado','Abril'),(15,'Domingo','Abril'),
(20,'Miercoles','Mayo');

INSERT INTO Reproducciones (id_usuario,id_contenido,id_tiempo,num_reproducciones,minutos_vistos) VALUES
(1,1,1,15,600),(2,2,2,8,360),(3,1,3,20,800),
(4,4,4,12,550),(5,3,5,5,200),(1,5,2,10,430),
(2,1,3,18,720),(3,4,4,14,620),(4,2,1,9,400);

-- CONSULTAS

-- Contenidos mas vistos (para mejorar catalogo)
SELECT
    c.titulo, c.tipo, c.genero,
    SUM(r.num_reproducciones) AS total_reproducciones,
    SUM(r.minutos_vistos) AS total_minutos
FROM Reproducciones r
INNER JOIN Contenido c ON r.id_contenido = c.id_contenido
GROUP BY c.titulo, c.tipo, c.genero
ORDER BY total_reproducciones DESC;

-- Horarios de mayor consumo (para recomendar contenido)
SELECT
    t.hora,
    t.dia_semana,
    SUM(r.num_reproducciones) AS total_reproducciones
FROM Reproducciones r
INNER JOIN Tiempo t ON r.id_tiempo = t.id_tiempo
GROUP BY t.hora, t.dia_semana
ORDER BY total_reproducciones DESC;
Evidencia — Ejercicio 12meow.
galería adicional — secuencia 11
Evidencia extra 01
Evidencia extra 02
Evidencia extra 03
Evidencia extra 04
Apartado adicional — curiosidad sobre OLAP

El término OLAP (Online Analytical Processing) fue propuesto en 1993 por Edgar F. Codd, el mismo investigador que sentó las bases del modelo relacional dos décadas antes. La idea era separar el mundo de las transacciones diarias del mundo del análisis histórico, justo la distinción que se trabajó en estas secuencias entre CRUD y consultas multidimensionales.

moscas moscas

a.

Secuencia 12

「OLAP vs CRUD / ETL」

4 — 8 de mayo de 2026

Mapa conceptual sobre la transición entre dos mundos complementarios: el procesamiento transaccional y el análisis multidimensional.

Resumen del mapa conceptual

CaracterísticaOLTP / CRUDOLAP / Multidimensional
PropósitoOperaciones diarias (captura de datos)Análisis e inteligencia de negocios
OperacionesCREATE, READ, UPDATE, DELETESELECT con SUM, AVG, GROUP BY
EstructuraTablas normalizadas (3FN)Tabla de hechos + dimensiones (estrella)
RendimientoMuchas escrituras concurrentesLecturas masivas de datos históricos
Ejemplo de usoRegistrar una venta en caja¿Cuánto se vendió en todo el mes?
TecnologíaMySQL, PostgreSQL (transaccional)Data Warehouse, cubos OLAP

Concepto ETL (Extract, Transform, Load)

  • Extract (Extraer): se obtienen los datos del sistema CRUD/OLTP.
  • Transform (Transformar): se limpian, organizan y adaptan al modelo dimensional.
  • Load (Cargar): se insertan en el Data Warehouse para análisis.

Flujo completo de arquitectura

Sistema CRUD (OLTP) → Base de datos relacional normalizada → Proceso ETL → Data Warehouse (OLAP) → Reportes y Dashboards

Ejemplo de ETL en SQL

sql · proceso etl
-- Ejemplo de proceso ETL basico
-- (se ejecuta despues de tener datos en el sistema CRUD)

-- Paso 1: Sistema CRUD tiene tablas normalizadas:
-- Clientes(id, nombre)
-- Productos(id, nombre, precio)
-- Ventas(id, id_cliente, fecha)
-- DetalleVentas(id, id_venta, id_producto, cantidad)

-- Paso 2: ETL - Cargar datos al modelo multidimensional
INSERT INTO Hechos_Ventas (id_producto, id_cliente, id_tiempo, cantidad, total)
SELECT
    dv.id_producto,
    v.id_cliente,
    t.id_tiempo,
    dv.cantidad,
    dv.cantidad * p.precio AS total
FROM DetalleVentas dv
JOIN Ventas v       ON dv.id_venta = v.id
JOIN Productos p    ON dv.id_producto = p.id
JOIN Dim_Tiempo t   ON DATE(v.fecha) = t.fecha_completa;

-- Paso 3: Consulta analitica (OLAP)
SELECT
    p.nombre AS producto,
    SUM(h.total) AS total_ventas
FROM Hechos_Ventas h
JOIN Dim_Producto p ON h.id_producto = p.id_producto
GROUP BY p.nombre
ORDER BY total_ventas DESC;

Conclusión

  • No se convierte el modelo multidimensional en CRUD: son sistemas complementarios.
  • CRUD → captura y gestión de datos en tiempo real (OLTP).
  • Multidimensional → análisis histórico y toma de decisiones (OLAP).
  • La conexión entre ambos se realiza mediante el proceso ETL.
  • Error común a evitar: nunca hacer operaciones CRUD directamente sobre el Data Warehouse, ya que genera inconsistencias y bajo rendimiento.
meowowowow
Secuencia 12 · Actividad final

「CRUD en Python con MySQL vía XAMPP」

Ejercicio resuelto electrónicamente

Bitácora paso a paso, con configuraciones y código completo, más el ejercicio funcional terminado: un sistema CRUD de consola conectado a MySQL a través de XAMPP.

Paso 1 — Preparación del entorno (XAMPP)

CONFIGURACIÓN INICIAL
  • Abrir el Panel de Control de XAMPP e iniciar los módulos Apache y MySQL (botones "Start" de ambos servicios).
  • Confirmar que el módulo MySQL quede en verde y escuchando en el puerto 3306 (puerto por defecto).
  • Entrar a phpMyAdmin desde el navegador en http://localhost/phpmyadmin para crear la base de datos y la tabla de usuarios de forma visual.
  • Crear la base de datos crud_python y, dentro de ella, la tabla usuarios (también puede hacerse por código, ver Paso 3).

Paso 2 — Entorno virtual de Python y editor

CONFIGURACIÓN DEL PROYECTO
consola · creación del entorno
# Crear carpeta del proyecto y entrar en ella
mkdir crud_mysql_consola
cd crud_mysql_consola

# Crear entorno virtual
python -m venv venv

# Activar entorno virtual (Windows)
venv\Scripts\activate

# Activar entorno virtual (Mac / Linux)
source venv/bin/activate

# Abrir el proyecto en Visual Studio Code
code .

Con el entorno activo, el prompt de la consola muestra el prefijo (venv), lo que confirma que las librerías que se instalen a continuación quedarán aisladas de las demás instalaciones de Python en el equipo.

Paso 3 — Instalación de dependencias y conexión inicial

mysql-connector-python
consola · instalación
pip install mysql-connector-python

Parámetros de conexión utilizados, acordes a una instalación estándar de XAMPP (usuario root sin contraseña, host local):

python · conexion.py
import mysql.connector

def conectar():
    return mysql.connector.connect(
        host="localhost",
        user="root",
        password="",          # XAMPP por defecto no asigna contraseña a root
        database="crud_python"
    )

Paso 4 — Creación de la base de datos y tabla por código

SCRIPT DE INICIALIZACIÓN
sql · crud_python
CREATE DATABASE IF NOT EXISTS crud_python;
USE crud_python;

CREATE TABLE IF NOT EXISTS usuarios (
    id INT AUTO_INCREMENT PRIMARY KEY,
    nombre VARCHAR(100) NOT NULL,
    correo VARCHAR(100) NOT NULL,
    edad INT
);

Paso 5 — Desarrollo de las cuatro funciones CRUD

CREAR · LEER · ACTUALIZAR · ELIMINAR

Cada función abre su propia conexión, ejecuta la sentencia correspondiente y la cierra de forma ordenada para no dejar conexiones abiertas en el servidor MySQL.

python · funciones_crud.py
import mysql.connector

def conectar():
    return mysql.connector.connect(
        host="localhost",
        user="root",
        password="",
        database="crud_python"
    )

# ---------- CREAR ----------
def crear_usuario(nombre, correo, edad):
    conexion = conectar()
    cursor = conexion.cursor()
    sql = "INSERT INTO usuarios (nombre, correo, edad) VALUES (%s, %s, %s)"
    cursor.execute(sql, (nombre, correo, edad))
    conexion.commit()
    print(f"Usuario '{nombre}' agregado con id {cursor.lastrowid}.")
    cursor.close()
    conexion.close()

# ---------- LEER ----------
def leer_usuarios():
    conexion = conectar()
    cursor = conexion.cursor()
    cursor.execute("SELECT id, nombre, correo, edad FROM usuarios")
    filas = cursor.fetchall()
    print("\nID  NOMBRE               CORREO                    EDAD")
    print("-" * 60)
    for fila in filas:
        print(f"{fila[0]:<4}{fila[1]:<21}{fila[2]:<26}{fila[3]}")
    cursor.close()
    conexion.close()

# ---------- ACTUALIZAR ----------
def actualizar_usuario(id_usuario, nombre, correo, edad):
    conexion = conectar()
    cursor = conexion.cursor()
    sql = "UPDATE usuarios SET nombre=%s, correo=%s, edad=%s WHERE id=%s"
    cursor.execute(sql, (nombre, correo, edad, id_usuario))
    conexion.commit()
    if cursor.rowcount:
        print(f"Usuario con id {id_usuario} actualizado correctamente.")
    else:
        print("No se encontro ningun usuario con ese id.")
    cursor.close()
    conexion.close()

# ---------- ELIMINAR ----------
def eliminar_usuario(id_usuario):
    conexion = conectar()
    cursor = conexion.cursor()
    cursor.execute("DELETE FROM usuarios WHERE id=%s", (id_usuario,))
    conexion.commit()
    if cursor.rowcount:
        print(f"Usuario con id {id_usuario} eliminado.")
    else:
        print("No se encontro ningun usuario con ese id.")
    cursor.close()
    conexion.close()

Paso 6 — Menú interactivo de consola (ejercicio completo)

EJECUCIÓN FINAL · main.py

Bucle principal que despliega el menú, valida la opción elegida y llama a la función CRUD correspondiente. Este archivo, junto con funciones_crud.py del paso anterior en el mismo directorio, conforma el ejercicio resuelto en su totalidad.

python · main.py
from funciones_crud import (
    crear_usuario,
    leer_usuarios,
    actualizar_usuario,
    eliminar_usuario
)

def menu():
    while True:
        print("\n===== SISTEMA CRUD - USUARIOS (MySQL / XAMPP) =====")
        print("1. Crear usuario")
        print("2. Ver usuarios")
        print("3. Actualizar usuario")
        print("4. Eliminar usuario")
        print("5. Salir")
        opcion = input("Elige una opcion: ")

        if opcion == "1":
            nombre = input("Nombre: ")
            correo = input("Correo: ")
            edad = int(input("Edad: "))
            crear_usuario(nombre, correo, edad)

        elif opcion == "2":
            leer_usuarios()

        elif opcion == "3":
            id_usuario = int(input("ID del usuario a actualizar: "))
            nombre = input("Nuevo nombre: ")
            correo = input("Nuevo correo: ")
            edad = int(input("Nueva edad: "))
            actualizar_usuario(id_usuario, nombre, correo, edad)

        elif opcion == "4":
            id_usuario = int(input("ID del usuario a eliminar: "))
            eliminar_usuario(id_usuario)

        elif opcion == "5":
            print("Saliendo del programa...")
            break

        else:
            print("Opcion no valida, intenta de nuevo.")

if __name__ == "__main__":
    menu()
Validación: cada acción del menú (crear, leer, actualizar, eliminar) se reflejó correctamente tanto en la salida de consola como en la tabla usuarios revisada desde phpMyAdmin, confirmando la comunicación entre Python y MySQL a través de XAMPP.

Resumen de la bitácora del video

REFERENCIA POR TIEMPOS — CRUD en Python con MySQL (XAMPP) paso a paso — Consola.MP4
MomentoContenido
0:18 – 5:52Preparación del entorno: arranque del servidor MySQL en XAMPP, creación de base de datos y tabla de usuarios, configuración del entorno virtual de Python y apertura del proyecto en VS Code.
6:42 – 10:57Conexión y dependencias: instalación de mysql-connector-python y escritura del código de conexión inicial con usuario root y host local.
11:11 – 28:22Desarrollo de las cuatro funciones CRUD: crear (INSERT), leer (SELECT), actualizar (UPDATE) y eliminar (DELETE).
28:36 – 44:08Menú interactivo y ejecución: bucle principal que despliega el menú, permite elegir la acción y valida los cambios en tiempo real en consola y en phpMyAdmin.

El objetivo del video —y de este ejercicio— es manejar bases de datos de forma estructurada sin frameworks, entendiendo la lógica de comunicación entre el backend en Python y el gestor de datos en MySQL.

Evidencia — Ejercicio CRUD completo ñañañañaañ.
galería adicional — secuencia 12
Evidencia extra 01
Evidencia extra 02
Evidencia extra 03
Evidencia extra 04
Proyecto Final

「Proyecto Integrador — Cierre de Bitácora」

Entrega final del periodo — Febrero a Julio 2026

Descripción general del proyecto

Este apartado reúne el proyecto final de la materia, que integra los conocimientos abordados a lo largo de las secuencias 2 a 12: modelado entidad-relación, normalización, bases de datos relacionales, modelos multidimensionales para análisis (OLAP) y procesos ETL, además del ejercicio práctico de conexión entre Python y MySQL mediante XAMPP. Aquí se documenta el desarrollo, las decisiones de diseño y la evidencia correspondiente al cierre del curso.

nota miamasuaimuwi

Evidencias del desarrollo del proyecto

evidencess
Evidencia — Modelo / diagrama del proyecto aki cap.
Evidencia — Funcionamiento del sistema ejecucion fusilamiento omg ekisde.
galería adicional — proyecto final
Evidencia extra 01
Evidencia extra 02
Evidencia extra 03
Evidencia extra 04
Evidencia extra 05
Evidencia extra 06

Documentos PDF del proyecto

pdf god pro
documento — 01 --> proyecto1.pdf
documento — 02 --> proyecto2.pdf

M EEEEEEEMEWMMEOW MEOWMOWMEOWMEWOEWO

Apartados Extra

「Espacios Random / Bitácora Abierta」

wieieieis

Bitácora abierta

profe lo quiero mucho uwu

erwerewr
leidibeibimeiditrankienla.
23ertyukjhghj
suit
gambare gambare
este estilo yo lo lanzare
galería libre — sin asignar
Espacio libre
Espacio libre
Espacio libre
Espacio libre

Señal de prueba

Un pequeño coso raro, sin más función que la curiosidad.