Skip to main content

Modelado conceptual ER/UML y modelado lógico

Qué es el modelado conceptual

El modelo conceptual representa las entidades y relaciones de un dominio de forma gráfica y abstracta, sin entrar todavía en detalles técnicos de SQL, tipos de datos o índices.

El objetivo es:

  • Visualizar las entidades y sus relaciones,
  • Expresar cardinalidades y opcionalidades,
  • Alinear la visión de analistas, desarrolladores y responsables del proyecto,
  • Prevenir errores de diseño antes de que lleguen a la base de datos real.

En bases de datos relacionales, esto se suele hacer con:

  • Diagramas Entidad–Relación (ER) tradicionales (Chen / Crow’s Foot)
  • O diagramas de clases UML simplificados, si se prefiere un estilo orientado a objetos.

Qué es el modelado lógico

El Modelado Lógico es la fase del diseño de bases de datos que transforma el esquema conceptual de alto nivel (el qué y cómo se relaciona la información) en una estructura de datos detallada y bien definida, basada en el modelo de datos elegido (generalmente el modelo relacional).

Este modelo describe la estructura de los datos independientemente del software de base de datos específico (DBMS, como MySQL, PostgreSQL, Oracle), pero dependiente del tipo de modelo (relacional, orientado a documentos, etc.).

¿Para Qué Sirve?

El Modelo Lógico sirve como el plano intermedio que conecta los requisitos del negocio con la implementación física. Sus principales utilidades son:

  1. Estructura Formal: Convierte las entidades y relaciones abstractas en tablas, columnas y claves específicas, eliminando ambigüedades.
  2. Integridad de Datos: Define reglas estrictas para garantizar la calidad y consistencia de la información a través de las Claves Primarias (PK) y Claves Foráneas (FK).
  3. Normalización: Permite aplicar técnicas de normalización (como 1NF, 2NF, 3NF) para eliminar la redundancia de datos y mejorar la eficiencia de almacenamiento y actualización.
  4. Base para el Modelo Físico: Proporciona un esquema tan detallado (con tipos de datos lógicos y restricciones) que la transición a un motor de base de datos específico (Modelo Físico) se vuelve directa.

Elementos principales de un diagrama ER

  1. Entidad → Representa un conjunto de objetos reales o abstractos.
    • Se dibuja como un rectángulo.
    • Ejemplo: Alumno, Curso, Pedido.
  2. Atributo → Propiedad de la entidad.
    • Se puede representar dentro de la caja o con óvalos conectados.
    • Ejemplo: nombre, correo, precio.
  3. Clave primaria → Atributo que identifica de forma única cada instancia.
    • Suele subrayarse o marcarse de forma destacada.
  4. Relación → Asociación entre entidades.
    • Se representa con líneas o rombos.
    • Incluye cardinalidades (1:1, 1:N, N:N).
  5. Cardinalidades y opcionalidad → Indican cuántas instancias de una entidad se asocian con la otra.
    • 1 obligatorio
    • 0..1 opcional
    • 0..* muchos opcional
    • 1..* muchos obligatorio

Ejemplo: Sistema de gestión académica (continuación del Módulo 4)

Tomamos el diccionario de datos del centro de formación:

1. Entidades del diagrama ER

A partir de tu esquema, las entidades serían:

  • CURSO
    • PK: id_curso
  • PROFESOR
    • PK: id_profesor
  • GRUPO
    • PK: id_grupo
    • FK: id_profesor → PROFESOR
    • FK: id_curso → CURSO
  • HORARIO
    • PK: id_horario
    • FK: id_profesor → PROFESOR
    • FK: id_grupo → GRUPO
  • TIPO_TAREA
    • PK: id_tipotarea
  • TIPO_CANCELACION
    • PK: id_tipocancelacion
  • CLASE
    • PK: id_clase
    • FK: id_tipocancelacion → TIPO_CANCELACION
    • FK: id_horario → HORARIO
    • FK: id_tipotarea → TIPO_TAREA
    • FK: id_profesor → PROFESOR
  • ALUMNO
    • PK: id_alumno
  • MATRICULA
    • PK: id_matricula
    • FK: id_curso → CURSO
    • FK: id_alumno → ALUMNO
  • ALUMNO_EN_GRUPO
    • PK: id_alumnoengrupo
    • FK: id_matricula → MATRICULA
  • ASISTENCIA
    • PK: id_asistencia
    • FK: id_clase → CLASE
    • FK: id_alumnoengrupo → ALUMNO_EN_GRUPO

En un diagrama ER estas “cajas” serían entidades (rectángulos) y las FKs se representarían a través de relaciones.

2. Relaciones ER (interpretación habitual)

A partir de las FKs, las relaciones típicas serían:

  • CURSO – GRUPO

    • Un CURSO tiene muchos GRUPOS.
    • Cada GRUPO pertenece a un único CURSO.
    • Cardinalidad: CURSO 1 ──── N GRUPO.
  • CURSO – MATRICULA – ALUMNO

    • Un ALUMNO puede tener muchas MATRÍCULAS (en distintos cursos).
    • Un CURSO tiene muchas MATRÍCULAS.
    • MATRICULA es la entidad débil que relaciona ALUMNO y CURSO (relación N:M resuelta con MATRICULA).
  • PROFESOR – GRUPO

    • Un PROFESOR puede impartir varios GRUPOS.
    • Cada GRUPO tiene un PROFESOR responsable.
    • Cardinalidad: PROFESOR 1 ──── N GRUPO.
  • PROFESOR – HORARIO – GRUPO

    • HORARIO actúa como tabla intermedia que relaciona PROFESOR y GRUPO:
      • Un GRUPO puede tener varios HORARIOS.
      • Un PROFESOR puede tener varios HORARIOS.
      • Según cómo lo interpretes, HORARIO puede representar un tramo (día/hora) asociado a un profesor y un grupo.
  • HORARIO – CLASE

    • Un HORARIO puede tener muchas CLASES (por ejemplo, diferentes días de ese tramo).
    • Cada CLASE se imparte en un único HORARIO.
  • CLASE – TIPO_TAREA

    • Cada CLASE tiene un TIPO_TAREA (teoría, práctica, examen, etc.).
    • Un TIPO_TAREA puede aparecer en muchas CLASES.
    • Cardinalidad: TIPO_TAREA 1 ──── N CLASE.
  • CLASE – TIPO_CANCELACION

    • Opcionalmente, una CLASE puede tener un TIPO_CANCELACION (solo cuando se cancela).
    • Un TIPO_CANCELACION puede usarse en muchas CLASES.
  • MATRICULA – ALUMNO_EN_GRUPO – GRUPO

    (en tu modelo solo aparece FK a MATRICULA; conceptualmente esta entidad suele ser la tabla que asigna alumnos matriculados a grupos)

    • Un ALUMNO (a través de su MATRICULA) puede estar en varios grupos o grupos de prácticas.
    • Un GRUPO puede tener muchos alumnos.
    • ALUMNO_EN_GRUPO es la intermedia de una relación N:M entre MATRICULA y GRUPO.
  • CLASE – ALUMNO_EN_GRUPO – ASISTENCIA

    • Una CLASE tiene muchos registros de ASISTENCIA.
    • Cada ALUMNO_EN_GRUPO tiene muchos registros de ASISTENCIA.
    • ASISTENCIA es la entidad intermedia de una relación N:M entre CLASE y ALUMNO_EN_GRUPO, que guarda si ese alumno asistió o no a esa clase.

Si quisieras dibujarlo como ER “clásico”:

  • Cada tabla de tu diagrama sería una entidad.
  • Las PK serían atributos identificadores.
  • Las FKs se convierten en relaciones con cardinalidades 1:N o N:M (cuando hay tablas intermedias como MATRICULA, ALUMNO_EN_GRUPO, ASISTENCIA, HORARIO).

Con estos datos, podemos exportarlo en formato DBML a la herramienta de drawdb o a dbdiagram.io en formato CSV para generar el diagrama gráfico.

///////////////////////////////////////////////////////////
// SISTEMA DE GESTIÓN ACADÉMICA - MODELO DBML COMPLETO //
///////////////////////////////////////////////////////////

Table CURSO {
id_curso int [pk]
}

Table PROFESOR {
id_profesor int [pk]
}

Table GRUPO {
id_grupo int [pk]
id_profesor int [not null, ref: > PROFESOR.id_profesor]
id_curso int [not null, ref: > CURSO.id_curso]
}

Table HORARIO {
id_horario int [pk]
id_profesor int [not null, ref: > PROFESOR.id_profesor]
id_grupo int [not null, ref: > GRUPO.id_grupo]
}

Table TIPO_TAREA {
id_tipotarea int [pk]
}

Table TIPO_CANCELACION {
id_tipocancelacion int [pk]
}

Table CLASE {
id_clase int [pk]
id_tipocancelacion int [ref: > TIPO_CANCELACION.id_tipocancelacion]
id_horario int [not null, ref: > HORARIO.id_horario]
id_tipotarea int [not null, ref: > TIPO_TAREA.id_tipotarea]
id_profesor int [not null, ref: > PROFESOR.id_profesor]
}

Table ALUMNO {
id_alumno int [pk]
}

Table MATRICULA {
id_matricula int [pk]
id_curso int [not null, ref: > CURSO.id_curso]
id_alumno int [not null, ref: > ALUMNO.id_alumno]
}

Table ALUMNO_EN_GRUPO {
id_alumnoengrupo int [pk]
id_matricula int [not null, ref: > MATRICULA.id_matricula]
}

Table ASISTENCIA {
id_asistencia int [pk]
id_clase int [not null, ref: > CLASE.id_clase]
id_alumnoengrupo int [not null, ref: > ALUMNO_EN_GRUPO.id_alumnoengrupo]
}

Formato CSV

CSV

Puedes copiarlos y pegarlos en tus archivos:

curso.csv
profesor.csv
grupo.csv
horario.csv
tipo_tarea.csv
tipo_cancelacion.csv
clase.csv
alumno.csv
matricula.csv
alumno_en_grupo.csv
asistencia.csv

1. curso.csv

id_curso
1
2

2. profesor.csv

id_profesor
10
11

3. grupo.csv

id_grupo,id_profesor,id_curso
100,10,1
101,11,2

4. horario.csv

id_horario,id_profesor,id_grupo
200,10,100
201,11,101

5. tipo_tarea.csv

id_tipotarea
1
2
3

6. tipo_cancelacion.csv

id_tipocancelacion
1
2

7. clase.csv

id_clase,id_tipocancelacion,id_horario,id_tipotarea,id_profesor
300,,200,1,10
301,2,201,3,11

Nota: en la clase 300 no hay cancelación, por eso el campo está vacío.

8. alumno.csv

id_alumno
500
501

9. matricula.csv

id_matricula,id_curso,id_alumno
600,1,500
601,2,501

10. alumno_en_grupo.csv

id_alumnoengrupo,id_matricula
700,600
701,601

11. asistencia.csv

id_asistencia,id_clase,id_alumnoengrupo
800,300,700
801,301,701

Ejercicio práctico guiado — Prestamos de libros

Enunciado

Diseño de un sistema de préstamos de libros para una biblioteca pública. Una biblioteca pública quiere informatizar su sistema de gestión de préstamos de libros. Hasta ahora, todo se gestiona en papel: fichas de socios, listados de libros, anotaciones a mano de los préstamos y devoluciones, y sanciones cuando un usuario se retrasa.

El objetivo de la práctica es diseñar la base de datos a nivel conceptual y lógico antes de crear físicamente las tablas. Para ello deberás:

  1. Identificar las principales entidades del sistema (libros, socios, préstamos, ejemplares, etc.).
  2. Definir sus atributos principales y sus claves.
  3. Establecer las relaciones entre entidades y sus cardinalidades.
  4. Elaborar un diagrama ER conceptual en texto.
  5. Transformar ese modelo en un esquema DBML.
  6. Generar archivos CSV con datos de ejemplo que respeten el modelo.

Al final, deberías poder importar el DBML en una herramienta como dbdiagram.io o drawDB, y visualizar el diagrama relacional que has diseñado.

Planteamiento general del problema

Escenarios que el sistema debe cubrir:

  1. La biblioteca posee muchos libros.
    • Cada libro tiene título, ISBN, año de publicación y una categoría (novela, ensayo, infantil, etc.).
    • Un libro puede tener uno o varios autores.
  2. De cada libro existen uno o varios ejemplares físicos.
    • Cada ejemplar tiene un código de inventario interno y una ubicación en la biblioteca (por ejemplo, estantería A3).
    • Cada ejemplar tiene un estado: disponible, prestado, deteriorado, perdido.
  3. Hay socios de la biblioteca.
    • Cada socio se registra con sus datos personales (nombre, apellidos, DNI, email, teléfono, fecha de alta).
    • Un socio puede estar activo, bloqueado o dado de baja.
  4. Los préstamos se realizan por socio.
    • Un socio puede pedir varios ejemplares en un mismo préstamo (una “operación” de préstamo con varias líneas).
    • Cada préstamo tiene fecha de inicio y fecha prevista de devolución.
    • Cuando se devuelven todos los ejemplares, se registra la fecha real y se marca el estado del préstamo: devuelto, retrasado, cancelado, etc.
  5. Si un préstamo se devuelve tarde, se puede generar una multa asociada a ese préstamo.
    • La multa tiene importe, motivo, fecha de generación y si está pagada o no.

Queremos un modelo que permita responder preguntas típicas:

  • ¿Qué ejemplares tiene prestados actualmente un socio?
  • ¿Qué ejemplares están disponibles en la biblioteca?
  • ¿Qué préstamos están retrasados?
  • ¿Qué multas tiene pendientes un socio?

Diccionario de datos

3.1. Entidad CATEGORIA

AtributoTipo conceptualDescripciónObligatorioClave
id_categoriaIdentificadorIdentificador único de la categoríaPK
nombreTextoNombre de la categoría (novela, infantil, etc.)AK
descripcionTextoDescripción opcional de la categoríaNo

3.2. Entidad LIBRO

AtributoTipo conceptualDescripciónObligatorioClave
id_libroIdentificadorIdentificador único del libroPK
tituloTextoTítulo del libro
isbnTexto (único)Código ISBN del libroAK
anio_publicacionNúmeroAño de publicaciónNo
id_categoriaFK → CATEGORIACategoría principal del libroFK

3.3. Entidad AUTOR

AtributoTipo conceptualDescripciónObligatorioClave
id_autorIdentificadorIdentificador único del autorPK
nombreTextoNombre del autor
apellidosTextoApellidos del autor

3.4. Entidad LIBRO_AUTOR (relación N:M)

AtributoTipo conceptualDescripciónObligatorioClave
id_libro_autorIdentificadorIdentificador de la relación libro–autorPK
id_libroFK → LIBROLibro asociadoFK
id_autorFK → AUTORAutor asociadoFK

3.5. Entidad EJEMPLAR

AtributoTipo conceptualDescripciónObligatorioClave
id_ejemplarIdentificadorIdentificador único del ejemplar físicoPK
id_libroFK → LIBROLibro al que pertenece el ejemplarFK
codigo_inventarioTexto (único)Código interno de inventarioAK
ubicacionTextoUbicación física (estantería, sala, etc.)No
estado_ejemplarTexto (enum)disponible / prestado / deteriorado / perdido

3.6. Entidad SOCIO

AtributoTipo conceptualDescripciónObligatorioClave
id_socioIdentificadorIdentificador único del socioPK
nombreTextoNombre del socio
apellidosTextoApellidos del socio
dniTexto (único)Documento de identidadAK
emailTexto (email)Correo de contacto
telefonoTextoTeléfonoNo
fecha_altaFechaFecha de alta en la biblioteca
estado_socioTexto (enum)activo / bloqueado / baja

3.7. Entidad PRESTAMO

AtributoTipo conceptualDescripciónObligatorioClave
id_prestamoIdentificadorIdentificador único del préstamoPK
id_socioFK → SOCIOSocio que realiza el préstamoFK
fecha_prestamoFechaFecha de inicio del préstamo
fecha_prevista_devolucionFechaFecha prevista para devolver todos los ejemplares
fecha_devolucion_realFechaFecha en la que se completó la devoluciónNo
estado_prestamoTexto (enum)activo / devuelto / retrasado / cancelado

3.8. Entidad LINEA_PRESTAMO

AtributoTipo conceptualDescripciónObligatorioClave
id_lineaIdentificadorIdentificador de la línea de préstamoPK
id_prestamoFK → PRESTAMOPréstamo al que pertenece la líneaFK
id_ejemplarFK → EJEMPLAREjemplar prestado en esta líneaFK

3.9. Entidad MULTA

AtributoTipo conceptualDescripciónObligatorioClave
id_multaIdentificadorIdentificador único de la multaPK
id_prestamoFK → PRESTAMOPréstamo al que se asocia la multaFK
importeNúmero decimalImporte de la multa
motivoTextoMotivo de la multa
pagadaBooleanoIndica si la multa ha sido pagada
fecha_generacionFechaFecha en la que se generó la multa
fecha_pagoFechaFecha en la que se pagó la multaNo

Diagrama ER en texto (entidades y cardinalidades)

Relaciones principales:

  • CATEGORIA 1 ──── N LIBRO

    Un libro pertenece a una categoría. Una categoría agrupa muchos libros.

  • LIBRO 1 ──── N EJEMPLAR

    Un libro tiene varios ejemplares físicos. Cada ejemplar pertenece a un único libro.

  • LIBRO N ──── N AUTOR (mediante LIBRO_AUTOR)

    Un libro puede tener varios autores. Un autor puede participar en varios libros.

    LIBRO_AUTOR resuelve la relación N:M.

  • SOCIO 1 ──── N PRESTAMO

    Un socio puede realizar muchos préstamos. Cada préstamo pertenece a un único socio.

  • PRESTAMO 1 ──── N LINEA_PRESTAMO

    Un préstamo puede incluir varios ejemplares (múltiples líneas).

    Cada línea pertenece a un único préstamo.

  • EJEMPLAR 1 ──── N LINEA_PRESTAMO

    Un mismo ejemplar puede aparecer en distintas líneas de préstamo a lo largo del tiempo.

    Cada línea de préstamo hace referencia a un ejemplar concreto.

  • PRESTAMO 1 ──── 0..1 MULTA

    Un préstamo puede no tener multa, o tener una multa asociada.

    Cada multa pertenece a un único préstamo.

Este modelo permite:

  • Registrar qué socio tiene qué ejemplares.
  • Controlar el estado de cada ejemplar.
  • Gestionar multas por retrasos.

Esquema en DBML (para dbdiagram / drawDB)

Copia y pega esto en un archivo biblioteca.dbml o directamente en dbdiagram/drawDB:

///////////////////////////////////////////////////////////
// SISTEMA DE PRÉSTAMOS DE BIBLIOTECA - DBML //
///////////////////////////////////////////////////////////

Table CATEGORIA {
id_categoria int [pk]
nombre varchar [not null, note: 'Nombre de la categoría']
descripcion varchar
}

Table LIBRO {
id_libro int [pk]
titulo varchar [not null]
isbn varchar [not null, unique]
anio_publicacion int
id_categoria int [not null, ref: > CATEGORIA.id_categoria]
}

Table AUTOR {
id_autor int [pk]
nombre varchar [not null]
apellidos varchar [not null]
}

Table LIBRO_AUTOR {
id_libro_autor int [pk]
id_libro int [not null, ref: > LIBRO.id_libro]
id_autor int [not null, ref: > AUTOR.id_autor]
}

Table EJEMPLAR {
id_ejemplar int [pk]
id_libro int [not null, ref: > LIBRO.id_libro]
codigo_inventario varchar [not null, unique]
ubicacion varchar
estado_ejemplar varchar [not null, note: 'disponible / prestado / deteriorado / perdido']
}

Table SOCIO {
id_socio int [pk]
nombre varchar [not null]
apellidos varchar [not null]
dni varchar [not null, unique]
email varchar [not null]
telefono varchar
fecha_alta date [not null]
estado_socio varchar [not null, note: 'activo / bloqueado / baja']
}

Table PRESTAMO {
id_prestamo int [pk]
id_socio int [not null, ref: > SOCIO.id_socio]
fecha_prestamo date [not null]
fecha_prevista_devolucion date [not null]
fecha_devolucion_real date
estado_prestamo varchar [not null, note: 'activo / devuelto / retrasado / cancelado']
}

Table LINEA_PRESTAMO {
id_linea int [pk]
id_prestamo int [not null, ref: > PRESTAMO.id_prestamo]
id_ejemplar int [not null, ref: > EJEMPLAR.id_ejemplar]
}

Table MULTA {
id_multa int [pk]
id_prestamo int [not null, ref: > PRESTAMO.id_prestamo]
importe decimal [not null]
motivo varchar [not null]
pagada boolean [not null]
fecha_generacion date [not null]
fecha_pago date
}

CSV por tabla, con cabecera y datos de ejemplo

Te los dejo listos para crear archivos individuales .csv (uno por tabla).

Puedes guardarlos en una carpeta datos/ si quieres usarlos con Node.js.

6.1. categoria.csv

id_categoria,nombre,descripcion
1,Ficción,Libros de narrativa y novela
2,Ensayo,Libros de no ficción y ensayo
3,Infantil,Libros para público infantil

6.2. libro.csv

id_libro,titulo,isbn,anio_publicacion,id_categoria
1,El nombre del viento,9788401337208,2007,1
2,Sapiens: De animales a dioses,9788499924211,2011,2
3,Cuentos para dormir,9788499321232,2015,3

6.3. autor.csv

id_autor,nombre,apellidos
1,Patrick,Rothfuss
2,Yuval Noah,Harari
3,Ana,López

6.4. libro_autor.csv

id_libro_autor,id_libro,id_autor
1,1,1
2,2,2
3,3,3

6.5. ejemplar.csv

id_ejemplar,id_libro,codigo_inventario,ubicacion,estado_ejemplar
1,1,EXP-0001,Sala A - Estante 1,disponible
2,1,EXP-0002,Sala A - Estante 1,prestado
3,2,EXP-0003,Sala B - Estante 3,disponible
4,3,EXP-0004,Sala Infantil - Estante 2,disponible

6.6. socio.csv

id_socio,nombre,apellidos,dni,email,telefono,fecha_alta,estado_socio
1,Carlos,Pérez,12345678A,carlos@example.com,600111222,2023-01-10,activo
2,María,García,87654321B,maria@example.com,600333444,2023-03-05,activo
3,Lucía,Ramírez,11223344C,lucia@example.com,600555666,2022-11-20,bloqueado

6.7. prestamo.csv

id_prestamo,id_socio,fecha_prestamo,fecha_prevista_devolucion,fecha_devolucion_real,estado_prestamo
1,1,2024-10-01,2024-10-15,2024-10-14,devuelto
2,2,2024-10-05,2024-10-19,,activo
3,1,2024-09-10,2024-09-24,2024-10-01,retrasado

6.8. linea_prestamo.csv

id_linea,id_prestamo,id_ejemplar
1,1,1
2,2,2
3,2,3
4,3,2

6.9. multa.csv

id_multa,id_prestamo,importe,motivo,pagada,fecha_generacion,fecha_pago
1,3,5.00,Retraso en devolución,false,2024-10-02,

Buenas prácticas en modelado conceptual

  • Cada relación debe tener una justificación funcional, no se crean “por si acaso”.
  • Define cardinalidades con precisión (evita dejar “N:N” si no sabes si es opcional u obligatorio).
  • Usa nombres coherentes y consistentes con el diccionario de datos.
  • El modelo conceptual no incluye aún índices, triggers ni optimizaciones físicas.
  • No intentes resolver reglas de negocio complejas aquí: documenta la lógica y sigue.

Errores comunes de principiantes

  • Crear relaciones circulares sin motivo.
  • No diferenciar entre cardinalidad obligatoria y opcional.
  • Confundir entidades con atributos (por ejemplo: poner “teléfono” como entidad separada sin necesidad).
  • No usar una tabla intermedia para N:N.
  • Cambiar nombres entre modelo conceptual y físico sin documentar.