teacher asking a question to the class
Photo by Max Fischer on Pexels.com

[Informe de Clase] Desarrollo de Sistemas (2º año) Semana 35

~ Diseño de Base de Datos (Diagramas ER) y Mapeo a Persistencia ~

En la Semana 35 hicimos un ejercicio práctico para derivar el diseño de base de datos (persistencia) a partir de los diagramas de clases creados la semana pasada. Es una sesión importante en la que el alumnado diseña qué clases se convierten en qué tablas y cómo se definen las relaciones, dando forma al esqueleto de un sistema en funcionamiento.


■ Introducción del profesor: “Diseñar cómo guardar las ‘cajas’ de memoria en el disco”

Profesor Tanaka: “Los datos definidos en las clases al final se convierten en tablas y registros. No basta con mapear los atributos UML directamente a tablas; lo que importa es diseñar pensando en la operación: normalización, índices, transacciones, etc.”


■ Puntos clave de hoy (resumen)

  • Definir entidades (tablas) y relaciones usando un diagrama ER.
  • Reducir redundancia teniendo en cuenta la normalización (1FN–3FN).
  • Diseñar claves primarias / foráneas y la integridad referencial (restricciones FK).
  • Diseñar índices (colocarlos adecuadamente según la frecuencia de las consultas).
  • Probar migraciones simples (CREATE TABLE / ALTER) y verificar el comportamiento con datos de ejemplo.
  • Considerar operaciones como transacciones, copias de seguridad y seguridad (contramedidas contra inyección SQL).

■ Ejercicio ①: Mapeo UML → Diagramas ER

En grupos, el alumnado debatió cómo mapear los atributos de las clases a tablas. Puntos clave:

  • Decidir qué se convierte en entidad: Si una clase tiene su propio ciclo de vida o es referenciada por múltiples objetos, debería convertirse en una tabla separada (p. ej., Book, Member, Loan).
  • Tratamiento de muchos-a-muchos: Las relaciones de muchos a muchos (por ejemplo, préstamos entre Member y Book) se representan con una tabla de unión (Loan).
  • Normalizar atributos: Considerar dividir direcciones y múltiples números de teléfono en tablas separadas para eliminar atributos repetidos.

Ejemplo: Esquema ER sencillo para un sistema de biblioteca

  • members (id PK, name, member_id, created_at)
  • books (id PK, title, author, is_reference, is_available)
  • loans (id PK, member_id FK → members.id, book_id FK → books.id, borrowed_at, due_date, returned_at)

Comentario de un estudiante: “¡Al introducir una tabla Loan, se vuelve natural gestionar el historial de préstamos y las comprobaciones de retrasos!”


■ Ejercicio ②: Comprobando la normalización (1FN → 3FN)

Cada grupo comprobó si su diseño de tablas estaba correctamente normalizado.

  • 1FN: Las columnas contienen valores atómicos y no columnas repetidas (evitar patrones tipo phone1, phone2).
  • 2FN: Eliminar la dependencia funcional parcial (tener cuidado al usar claves primarias compuestas).
  • 3FN: Los atributos no clave deben depender solo de la clave (los datos derivados deben moverse a otra tabla o a una vista).

Ejemplo: Si books contiene una columna library_branch_name, el alumnado señaló que es más apropiado moverla a una tabla separada branches.


■ Ejercicio ③: Construir y ejecutar con SQL (Migración y datos de muestra)

En clase escribimos sentencias SQL sencillas, las aplicamos a un entorno de BD de aprendizaje y comprobamos cómo se comportaban (suponiendo un entorno de práctica con SQLite / PostgreSQL). Ejemplo usado en clase:

-- members table
CREATE TABLE members (
  id SERIAL PRIMARY KEY,
  member_id VARCHAR(20) UNIQUE NOT NULL,
  name VARCHAR(100) NOT NULL,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- books table
CREATE TABLE books (
  id SERIAL PRIMARY KEY,
  title VARCHAR(200) NOT NULL,
  author VARCHAR(100),
  is_reference BOOLEAN DEFAULT FALSE,
  is_available BOOLEAN DEFAULT TRUE
);

-- loans table (junction table)
CREATE TABLE loans (
  id SERIAL PRIMARY KEY,
  member_id INTEGER NOT NULL REFERENCES members(id),
  book_id INTEGER NOT NULL REFERENCES books(id),
  borrowed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  due_date DATE,
  returned_at TIMESTAMP NULL
);

Después insertamos datos de ejemplo y utilizamos consultas JOIN para verificar el comportamiento.

INSERT INTO members (member_id, name) VALUES ('M001', 'Tanaka');
INSERT INTO books (title, author) VALUES ('Harry Potter', 'J.K. Rowling');

-- Proceso de préstamo (dentro de una transacción)
BEGIN;
INSERT INTO loans (member_id, book_id, due_date) VALUES (1, 1, '2025-12-01');
UPDATE books SET is_available = FALSE WHERE id = 1;
COMMIT;

-- Obtener libros actualmente prestados
SELECT b.title, m.name, l.borrowed_at, l.due_date
FROM loans l
JOIN books b ON l.book_id = b.id
JOIN members m ON l.member_id = m.id
WHERE l.returned_at IS NULL;

Reacción del alumnado: “Si gestionamos el préstamo y la actualización de stock dentro de una transacción, ¡aunque algo falle a medias, la consistencia de los datos se mantiene!”


■ Ejercicio ④: Conceptos básicos de índices y rendimiento

Suponiendo mayores volúmenes de datos tras crear las tablas, hablamos de qué columnas deberían tener índices.

  • Considerar índices en columnas que se busquen con frecuencia, como books.title y members.member_id.
  • Columnas usadas en JOIN, como loans.book_id y loans.member_id, suelen beneficiarse mucho de los índices.
  • Por otro lado, evitar índices innecesarios sobre columnas muy actualizadas o con baja selectividad (p. ej., flags booleanos).

Ejemplos simples de SQL:

CREATE INDEX idx_books_title ON books(title);
CREATE INDEX idx_loans_member_id ON loans(member_id);

Realización del alumnado: “Los índices hacen más rápidas las lecturas, pero introducen un compromiso al ralentizar las escrituras.”


■ Ejercicio ⑤: Consideraciones operativas (copias de seguridad, migraciones, seguridad)

  • Copias de seguridad: Conceptos como volcados regulares (pg_dump, etc.) y recuperación a un punto en el tiempo (PITR).
  • Migraciones: Los cambios de esquema deben hacerse por fases (tener cuidado con ALTER y preparar planes de rollback).
  • Seguridad: Usar consultas parametrizadas con placeholders para prevenir inyección SQL (por ejemplo, cursor.execute("SELECT ... WHERE id=%s", (id,))).
  • Control de acceso: Aplicar el principio de mínimo privilegio a los usuarios de BD (por ejemplo, usuarios solo lectura).

Profesor Tanaka: “Incluso un gran diseño no sirve de nada si se pierden o filtran datos durante la operación. Persistencia también significa asumir la ‘responsabilidad última’ sobre los datos.”


■ Comentario de cierre del profesor

“El diseño de datos tiene un impacto enorme en la fiabilidad y el rendimiento de la aplicación. Si diseñas teniendo en mente todo el flujo —de diagramas de clases a diagramas ER, de diagramas ER a DDL y de ahí a la operación— tanto la implementación como las pruebas se vuelven mucho más fluidas. La próxima semana finalizaremos los diagramas ER y cada grupo creará scripts de migración reales.”


■ Tarea (para la próxima clase)

  1. Entregar el diagrama ER final (PNG/PDF) de tu grupo y los scripts CREATE TABLE (DDL) creados esta semana.
  2. Proponer al menos tres índices en vuestras tablas y explicar el motivo de cada uno (20–60 caracteres por explicación).
  3. Redactar un documento de una página que describa el procedimiento de rollback en caso de pérdida de datos (flujo desde la copia de seguridad hasta la restauración).

La Semana 35 se centró en llevar el diseño hasta el nivel de la persistencia y adquirir experiencia práctica con SQL y consideraciones operativas. El alumnado profundizó en la idea de que “diseño = conjunto de promesas” y de que “la base de datos es un activo que debe tratarse con cuidado”, preparándose para la siguiente fase de implementación.

por greeden

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)