Módulo 07: Relaciones binarias

Objetivos del módulo

  • Definir con rigor qué es una relación binaria (binary relationship) y qué es una ocurrencia de relación
  • Distinguir las tres correspondencias posibles entre dos entidades: 1:1, 1:N y N:M
  • Dominar las diez combinaciones de cardinalidades mínimas y máximas que pueden aparecer en una relación binaria, con un ejemplo real de cada una
  • Dibujar cada relación en la notación del curso y su diagrama de ocurrencias, y leerla en lenguaje natural en los dos sentidos
  • Usar y anotar cardinalidades concretas distintas de n, como (0,3), (2,5) o (3,3)
  • Decidir dónde se colocan los atributos de relación según la correspondencia y detectar los atributos que dependen de la ocurrencia de relación
  • Resolver el problema de las relaciones N:M que deben registrar repeticiones en el tiempo
  • Modelar varias relaciones distintas entre las mismas dos entidades
  • Evitar el error de representar una relación como un atributo que “apunta” a otra entidad
  • Aplicar criterios para decidir entre una relación 1:1 y fusionar las dos entidades, y entre entidad y relación
  • Anticipar cómo se transforma cada tipo de relación binaria al modelo relacional
  • Reconocer y corregir los errores más frecuentes al modelar relaciones binarias

1. Qué es una relación binaria

1.1. Definición

En el módulo anterior viste el concepto general de relación, su grado y la convención de cardinalidades del curso. Ahora nos centramos en el caso más frecuente con diferencia: las relaciones entre dos entidades. En un diseño real, más del 90 % de las relaciones son binarias, así que dominarlas a fondo es imprescindible.

📘 Concepto: Una relación binaria (binary relationship) es una relación de grado 2: asocia ocurrencias de dos tipos de entidad. Formalmente, si E₁ y E₂ son dos tipos de entidad, un tipo de relación binaria R entre ellos es un subconjunto del producto cartesiano E₁ × E₂. Cada elemento de R, un par (e₁, e₂) con e₁ ∈ E₁ y e₂ ∈ E₂, es una ocurrencia de la relación (relationship instance).

Dos consecuencias de esta definición que usarás durante todo el módulo:

  1. R es un conjunto: el mismo par (e₁, e₂) no puede aparecer dos veces. Si Ana imparte Bases de Datos, esa ocurrencia existe o no existe, pero no “existe tres veces”. Esta propiedad tan inocente es el origen del problema de las repeticiones en el tiempo (sección 7).
  2. Una ocurrencia de relación se identifica por las ocurrencias de entidad que asocia: el par (Ana, Bases de Datos) identifica por sí solo esa ocurrencia. La relación no necesita un identificador propio.

💡 Consejo: Cuando hables de relaciones distingue siempre el tipo de relación (“imparte”, lo que dibujas en el diagrama) de sus ocurrencias (“Ana imparte Bases de Datos”, “Luis imparte Redes”). Es la misma distinción que entre la entidad PROFESOR y el profesor concreto Ana.

1.2. La convención de cardinalidades del curso (recordatorio)

En todo el curso se usa la misma convención, que estudiaste en detalle en el módulo 06 (sección «La convención del curso: la pareja (mín, máx)», donde también se comparan las notaciones de participación, pata de gallo y UML). Solo la recordamos:

⚠️ Importante: La pareja (mín, máx) escrita junto a la entidad A indica con cuántas ocurrencias de A se relaciona una ocurrencia de la otra entidad. Para leer una relación desde la entidad X, sitúate en X, cruza el rombo y lee la pareja que hay en el otro extremo.

flowchart LR
    PROFESOR[PROFESOR] ---|"(1,1)"| imparte{"imparte<br/>1:N"}
    imparte ---|"(0,n)"| ASIGNATURA[ASIGNATURA]
    PROFESOR --- p_dni([<u>dni</u>])
    PROFESOR --- p_nombre([nombre])
    ASIGNATURA --- a_cod([<u>codigo</u>])
    ASIGNATURA --- a_nombre([nombre])
  • Desde PROFESOR: cruzo el rombo y leo (0,n) → “un profesor imparte como mínimo 0 y como máximo n asignaturas”.
  • Desde ASIGNATURA: cruzo el rombo y leo (1,1) → “una asignatura es impartida como mínimo por 1 y como máximo por 1 profesor”.

La cardinalidad mínima expresa si la participación es opcional (0) u obligatoria (1 o más). La cardinalidad máxima expresa si una ocurrencia se relaciona como mucho con una (1) o con varias (n, o un número concreto mayor que 1).

📘 Concepto: Observa una sutileza de esta convención: la mínima escrita junto a ASIGNATURA, (0,n), habla de la participación de PROFESOR (puede haber profesores que no imparten nada: participación parcial de PROFESOR). La mínima escrita junto a PROFESOR, (1,1), habla de la participación de ASIGNATURA (toda asignatura tiene profesor: participación total de ASIGNATURA). Lo verás cientos de veces: la mínima del extremo contrario describe tu obligación de participar.

1.3. El tipo de correspondencia

El tipo de correspondencia (también llamado razón de cardinalidad, cardinality ratio) se obtiene solo de las dos cardinalidades máximas:

Máximo junto a A Máximo junto a B Correspondencia entre A y B Se lee
1 1 1:1 uno a uno
1 n (o cualquier número > 1) 1:N uno a muchos (A es el “lado 1”, B el “lado N”)
n (o > 1) 1 N:1 muchos a uno (es una 1:N vista al revés)
n (o > 1) n (o > 1) N:M muchos a muchos

En el diagrama del profesor, el máximo junto a PROFESOR es 1 y junto a ASIGNATURA es n: la correspondencia es 1:N con PROFESOR en el lado 1. En el curso la escribimos dentro del rombo (debajo del verbo) o en el texto.

⚠️ Importante: Las cardinalidades mínimas no intervienen en el tipo de correspondencia. Una relación (0,1)-(0,n) y otra (1,1)-(1,n) son las dos 1:N. Las mínimas determinan otra cosa: la obligatoriedad de participar, que en el modelo relacional se traducirá en columnas NOT NULL o en restricciones adicionales.

1.4. Diagramas de ocurrencias

Un diagrama de ocurrencias (también diagrama de ejemplares o de instancias) dibuja un pequeño conjunto de ocurrencias concretas de cada entidad y las ocurrencias de la relación que las unen. No forma parte del esquema (el esquema es el diagrama E/R), pero es la herramienta más eficaz para comprobar que las cardinalidades que has puesto son las correctas: si puedes dibujar un ejemplo real que las incumple, están mal.

La forma completa muestra el conjunto de ocurrencias de cada entidad, el conjunto de ocurrencias de la relación en el centro, y líneas que unen cada ocurrencia de relación con las dos ocurrencias de entidad que asocia:

flowchart LR
    subgraph S_PROF["PROFESOR"]
        p1("Ana")
        p2("Luis")
        p3("Eva")
    end
    subgraph S_IMP["imparte"]
        r1(("r1"))
        r2(("r2"))
        r3(("r3"))
    end
    subgraph S_ASIG["ASIGNATURA"]
        a1("Bases de Datos")
        a2("Redes")
        a3("Sistemas Operativos")
    end
    p1 --- r1 --- a1
    p1 --- r2 --- a2
    p2 --- r3 --- a3

Comprobación de las cardinalidades con este ejemplo:

  • Cada asignatura está unida a exactamente un profesor → (1,1) junto a PROFESOR. ✔
  • Ana imparte 2 asignaturas, Luis 1 y Eva ninguna → mínimo 0 y máximo “varias” → (0,n) junto a ASIGNATURA. ✔

Como cada ocurrencia de relación binaria es un par, a partir de ahora usaremos la forma simplificada: cada línea que une dos ejemplares es una ocurrencia de la relación.

flowchart LR
    subgraph S_PROF["PROFESOR"]
        p1("Ana")
        p2("Luis")
        p3("Eva")
    end
    subgraph S_ASIG["ASIGNATURA"]
        a1("Bases de Datos")
        a2("Redes")
        a3("Sistemas Operativos")
    end
    p1 --- a1
    p1 --- a2
    p2 --- a3

💡 Consejo: Para validar una cardinalidad mínima de 0 dibuja siempre al menos un ejemplar sin líneas (como Eva). Para validar un máximo de n, dibuja un ejemplar con dos o más líneas (como Ana). Si el enunciado no permite dibujar ese caso, la cardinalidad no es la que creías.

1.5. Cómo leer una relación en lenguaje natural

Toda relación binaria se lee con dos frases, una desde cada entidad, siguiendo siempre la misma plantilla:

“Cada ⟨entidad origen⟩ ⟨verbo⟩ como mínimo ⟨mín⟩ y como máximo ⟨máx⟩ ⟨entidad destino⟩”, donde (mín, máx) es la pareja escrita junto a la entidad destino.

Para el segundo sentido suele hacer falta la voz pasiva o un verbo recíproco (“imparte” / “es impartida por”, “realiza” / “es realizado por”, “contiene” / “está contenido en”). Si la frase en uno de los sentidos suena forzada, prueba otro verbo para el rombo; un buen nombre de relación se lee bien en los dos sentidos.

Valor de la pareja Fórmula en lenguaje natural
(0,1) “ninguno o uno”, “como mucho uno”, “puede tener un…”
(1,1) “exactamente uno”, “uno y solo uno”, “siempre un…”
(0,n) “ninguno, uno o varios”, “puede tener varios…”
(1,n) “al menos uno”, “uno o varios”, “siempre tiene algún…”
(2,5) “entre dos y cinco”
(3,3) “exactamente tres”

1.6. Método para obtener las cardinalidades de una relación binaria

El módulo 06 presentó el método de las cuatro preguntas y las palabras clave de los enunciados. Lo recordamos en forma de lista de comprobación, porque lo aplicarás en cada una de las diez combinaciones de este módulo: piensa siempre en una ocurrencia concreta y en cualquier momento de la vida de la base de datos:

  1. Dado un A concreto, ¿con cuántos B puede estar relacionado como mínimo? (¿puede existir un A sin ningún B, por ejemplo justo después de darlo de alta?)
  2. Dado un A concreto, ¿con cuántos B como máximo? → las dos respuestas se escriben junto a B.
  3. Dado un B concreto, ¿con cuántos A como mínimo?
  4. Dado un B concreto, ¿con cuántos A como máximo? → las dos respuestas se escriben junto a A.

⚠️ Importante: Pregúntate si hablas de un instante o de toda la historia. “Un empleado pertenece a un departamento” es cierto en un instante dado; a lo largo de su carrera puede haber pasado por cinco. El enunciado (o el cliente) decide qué hay que registrar, y la cardinalidad cambia según la respuesta. Volveremos a esto en la sección 7.


2. Correspondencia 1:1

2.1. Concepto

📘 Concepto: En una relación 1:1 (uno a uno), cada ocurrencia de A se relaciona como mucho con una ocurrencia de B y cada ocurrencia de B se relaciona como mucho con una de A. Las dos cardinalidades máximas valen 1.

Hay tres combinaciones posibles de mínimas: las dos opcionales, una opcional y otra obligatoria, o las dos obligatorias. En los diagramas de ocurrencias de una 1:1, ningún ejemplar tiene más de una línea.

2.2. Combinación (0,1) – (0,1): opcional en ambos sentidos

💻 Ejemplo: En una empresa, algunos empleados tienen asignada una plaza de garaje. Cada plaza se asigna como mucho a un empleado y cada empleado tiene como mucho una plaza. Hay empleados sin plaza y plazas libres.

flowchart LR
    EMPLEADO[EMPLEADO] ---|"(0,1)"| asignada{"tiene asignada<br/>1:1"}
    asignada ---|"(0,1)"| PLAZA[PLAZA_GARAJE]
    EMPLEADO --- e_id([<u>emp_id</u>])
    EMPLEADO --- e_nombre([nombre])
    PLAZA --- p_num([<u>numero</u>])
    PLAZA --- p_planta([planta])

Diagrama de ocurrencias:

flowchart LR
    subgraph S_EMP["EMPLEADO"]
        e1("100 Ana")
        e2("101 Luis")
        e3("102 Marta")
    end
    subgraph S_PLA["PLAZA_GARAJE"]
        g1("P-01")
        g2("P-02")
        g3("P-03")
    end
    e1 --- g2
    e3 --- g1
    e1 ~~~ g3

Lectura en los dos sentidos:

  • “Cada empleado tiene asignada como mínimo ninguna y como máximo una plaza de garaje” (pareja junto a PLAZA_GARAJE). Luis no tiene plaza.
  • “Cada plaza de garaje está asignada como mínimo a ningún y como máximo a un empleado” (pareja junto a EMPLEADO). La P-03 está libre.

Es la combinación más “débil”: ninguna de las dos entidades está obligada a participar. Otros ejemplos: HABITACIÓN de hotel está ocupada por HUÉSPED principal (en un instante), ALUMNO tiene asignada TAQUILLA, EMPLEADO usa PORTÁTIL de empresa.

2.3. Combinación (1,1) – (0,1): obligatoria en un sentido

💻 Ejemplo: Cada país tiene exactamente una capital, que es una ciudad. Una ciudad es capital de un país o de ninguno (la mayoría de las ciudades no son capitales).

flowchart LR
    CIUDAD[CIUDAD] ---|"(1,1)"| capital{"es capital de<br/>1:1"}
    capital ---|"(0,1)"| PAIS[PAÍS]
    CIUDAD --- c_cod([<u>cod_ciudad</u>])
    CIUDAD --- c_nombre([nombre])
    PAIS --- p_iso([<u>codigo_iso</u>])
    PAIS --- p_nombre([nombre])
flowchart LR
    subgraph S_CIU["CIUDAD"]
        c1("Madrid")
        c2("Lisboa")
        c3("Valencia")
        c4("Oporto")
    end
    subgraph S_PAI["PAÍS"]
        p1("España")
        p2("Portugal")
    end
    c1 --- p1
    c2 --- p2
  • “Cada ciudad es capital de como mínimo ningún y como máximo un país” (0,1) junto a PAÍS. Valencia y Oporto no son capitales.
  • “Cada país tiene como capital exactamente una ciudad” (1,1) junto a CIUDAD. No puede haber un país sin capital ni con dos.

💡 Consejo: Observa que el universo del discurso manda: si tu sistema tuviera que representar países con varias capitales (Bolivia tiene capital constitucional y sede de gobierno), el máximo junto a CIUDAD ya no sería 1, o tendrías dos relaciones distintas (“es capital constitucional de”, “es sede de gobierno de”). Las cardinalidades no son verdades universales, son reglas del negocio que modelas.

Otros ejemplos de (1,1)-(0,1): DEPARTAMENTO es dirigido por EMPLEADO (todo departamento tiene director; la mayoría de empleados no dirigen nada), VEHÍCULO tiene instalado DISPOSITIVO_GPS cuando todos los dispositivos dados de alta están instalados, pero no todos los vehículos llevan uno (aquí la pareja (1,1) estaría junto a VEHÍCULO).

2.4. Combinación (1,1) – (1,1): obligatoria en ambos sentidos

💻 Ejemplo: En una red social, al registrarse un usuario se crea automáticamente su perfil público. No existe perfil sin usuario ni usuario sin perfil, y cada uno tiene exactamente uno del otro.

flowchart LR
    USUARIO[USUARIO] ---|"(1,1)"| tiene{"tiene<br/>1:1"}
    tiene ---|"(1,1)"| PERFIL[PERFIL]
    USUARIO --- u_login([<u>login</u>])
    USUARIO --- u_email(["email (AK)"])
    USUARIO --- u_hash([hash_clave])
    PERFIL --- f_url([<u>url_publica</u>])
    PERFIL --- f_bio([biografia])
    PERFIL --- f_foto([foto])
flowchart LR
    subgraph S_USU["USUARIO"]
        u1("anagarcia")
        u2("luismr")
        u3("marta_sg")
    end
    subgraph S_PER["PERFIL"]
        f1("/ana-garcia")
        f2("/luis-martinez")
        f3("/marta-sanchez")
    end
    u1 --- f1
    u2 --- f2
    u3 --- f3
  • “Cada usuario tiene exactamente un perfil”.
  • “Cada perfil pertenece a exactamente un usuario”.

El diagrama de ocurrencias es una biyección: cada ejemplar de un lado tiene exactamente una línea. Esta combinación es la candidata natural a fusionar las dos entidades en una sola; lo estudiarás con criterios en la sección 10.

2.5. Resumen de las relaciones 1:1

Combinación Significado Ejemplo ¿Candidata a fusión?
(0,1) – (0,1) Ninguna entidad obligada EMPLEADO – PLAZA_GARAJE No: existen ocurrencias sueltas en ambos lados
(1,1) – (0,1) Una entidad obligada, la otra no CIUDAD – PAÍS (capital) A veces: se podría llevar la información a la entidad obligada
(1,1) – (1,1) Ambas obligadas USUARIO – PERFIL Sí, casi siempre (salvo razones de la sección 10)

3. Correspondencia 1:N

3.1. Concepto

📘 Concepto: En una relación 1:N (uno a muchos) entre A y B, cada ocurrencia de A puede relacionarse con varias de B, pero cada ocurrencia de B se relaciona como mucho con una de A. A es el lado 1 (el “padre”) y B el lado N (el “hijo”). La máxima junto a A es 1 y la máxima junto a B es n (o un número mayor que 1).

En el diagrama de ocurrencias de una 1:N, los ejemplares del lado N tienen como mucho una línea, mientras que los del lado 1 pueden tener varias: el dibujo recuerda a un abanico o a un peine.

Para nombrar las combinaciones escribiremos “pareja junto al lado 1 – pareja junto al lado N”. Hay cuatro posibles, porque la mínima de cada lado puede ser 0 o 1.

3.2. Combinación (0,1) – (0,n)

💻 Ejemplo (esquema EMPRESA): Cada empleado pertenece como mucho a un departamento y un departamento tiene cualquier número de empleados. En los datos de ../recursos/empresa_datos.sql el empleado 160 (Tomás, becario) no tiene departamento y el departamento 70 (INVESTIGACIÓN) no tiene empleados.

flowchart LR
    DEPARTAMENTO[DEPARTAMENTO] ---|"(0,1)"| pertenece{"tiene adscrito<br/>1:N"}
    pertenece ---|"(0,n)"| EMPLEADO[EMPLEADO]
    DEPARTAMENTO --- d_id([<u>dept_id</u>])
    DEPARTAMENTO --- d_nombre([nombre])
    EMPLEADO --- e_id([<u>emp_id</u>])
    EMPLEADO --- e_nombre([nombre])
flowchart LR
    subgraph S_DEP["DEPARTAMENTO"]
        d20("20 VENTAS")
        d40("40 CONTABILIDAD")
        d70("70 INVESTIGACIÓN")
    end
    subgraph S_EMP["EMPLEADO"]
        e110("110 Carmen")
        e111("111 David")
        e130("130 Isabel")
        e131("131 Jorge")
        e160("160 Tomás")
    end
    d20 --- e110
    d20 --- e111
    d40 --- e130
    d40 --- e131
    d70 ~~~ e160
  • Desde DEPARTAMENTO: “Cada departamento tiene adscritos ninguno, uno o varios empleados” (0,n). El 70 no tiene ninguno.
  • Desde EMPLEADO: “Cada empleado está adscrito como mucho a un departamento” (0,1). Tomás no está en ninguno.

⚠️ Importante: La mínima 0 junto a DEPARTAMENTO (que permite empleados sin departamento) no es un descuido: es una decisión de diseño que el script de EMPRESA implementa dejando la columna dept_id de EMPLEADOS sin NOT NULL. Toda mínima 0 debe estar justificada por un caso real (becarios, empleados en tránsito…). Si el enunciado dice “todo empleado pertenece a un departamento”, la pareja sería (1,1).

3.3. Combinación (1,1) – (0,n)

Es, con diferencia, la combinación más frecuente en los diseños reales.

💻 Ejemplo (esquema EMPRESA): Cada pedido lo realiza exactamente un cliente; un cliente puede haber realizado cualquier número de pedidos, incluido ninguno (los clientes 1013 y 1014 están dados de alta pero aún no han comprado).

flowchart LR
    CLIENTE[CLIENTE] ---|"(1,1)"| realiza{"realiza<br/>1:N"}
    realiza ---|"(0,n)"| PEDIDO[PEDIDO]
    CLIENTE --- c_id([<u>cliente_id</u>])
    CLIENTE --- c_nif(["nif (AK)"])
    CLIENTE --- c_nombre([nombre])
    PEDIDO --- p_id([<u>pedido_id</u>])
    PEDIDO --- p_estado([estado])
flowchart LR
    subgraph S_CLI["CLIENTE"]
        c1001("1001 Talleres Martín")
        c1002("1002 Construcciones Levante")
        c1013("1013 Carlos Ibáñez")
    end
    subgraph S_PED["PEDIDO"]
        p5001("5001")
        p5006("5006")
        p5021("5021")
        p5002("5002")
    end
    c1001 --- p5001
    c1001 --- p5006
    c1001 --- p5021
    c1002 --- p5002
  • “Cada cliente realiza ninguno, uno o varios pedidos” (0,n) junto a PEDIDO.
  • “Cada pedido es realizado por exactamente un cliente” (1,1) junto a CLIENTE. Un pedido sin cliente no tiene sentido en este negocio.

Otros ejemplos típicos: PROFESOR (1,1) – ASIGNATURA (0,n), CATEGORÍA (1,1) – PRODUCTO (0,n) (en EMPRESA categoria_id de PRODUCTOS es NOT NULL), CLIENTE (1,1) – CUENTA_BANCARIA (0,n), AUTOR (1,1) – COMENTARIO (0,n).

3.4. Combinación (1,1) – (1,n)

💻 Ejemplo: Cada municipio pertenece exactamente a una provincia, y cada provincia tiene al menos un municipio (en realidad, muchos).

flowchart LR
    PROVINCIA[PROVINCIA] ---|"(1,1)"| comprende{"comprende<br/>1:N"}
    comprende ---|"(1,n)"| MUNICIPIO[MUNICIPIO]
    PROVINCIA --- pr_cod([<u>cod_provincia</u>])
    PROVINCIA --- pr_nombre([nombre])
    MUNICIPIO --- m_cod([<u>cod_ine</u>])
    MUNICIPIO --- m_nombre([nombre])
    MUNICIPIO --- m_hab([habitantes])
flowchart LR
    subgraph S_PRO["PROVINCIA"]
        v46("46 Valencia")
        v03("03 Alicante")
    end
    subgraph S_MUN["MUNICIPIO"]
        m1("Gandia")
        m2("Sagunto")
        m3("Xàtiva")
        m4("Elche")
        m5("Alcoy")
    end
    v46 --- m1
    v46 --- m2
    v46 --- m3
    v03 --- m4
    v03 --- m5
  • “Cada provincia comprende uno o varios municipios” (1,n) junto a MUNICIPIO. No existe una provincia vacía.
  • “Cada municipio está comprendido en exactamente una provincia” (1,1) junto a PROVINCIA.

⚠️ Importante: Una mínima de 1 en el lado N obliga a algo que el diseño debe resolver: no se puede dar de alta una provincia sin dar de alta a la vez al menos un municipio, y no se puede borrar el último municipio de una provincia. En el modelo relacional esa obligación no se puede expresar con una simple clave ajena; se anotará como restricción semántica y se garantizará con transacciones o con la lógica de la aplicación. Piensa siempre si de verdad la necesitas o si basta con (0,n).

3.5. Combinación (0,1) – (1,n)

💻 Ejemplo (liga deportiva): La federación registra a todos los jugadores con licencia. Un jugador está fichado como mucho por un equipo (puede estar sin equipo, como “agente libre”), y la federación solo da de alta equipos que tengan al menos un jugador.

flowchart LR
    EQUIPO[EQUIPO] ---|"(0,1)"| ficha{"tiene fichado<br/>1:N"}
    ficha ---|"(1,n)"| JUGADOR[JUGADOR]
    EQUIPO --- q_cod([<u>cod_equipo</u>])
    EQUIPO --- q_nombre([nombre])
    JUGADOR --- j_lic([<u>licencia</u>])
    JUGADOR --- j_nombre([nombre])
flowchart LR
    subgraph S_EQU["EQUIPO"]
        q1("CD Huracán")
        q2("UD Ribera")
    end
    subgraph S_JUG["JUGADOR"]
        j1("Pérez")
        j2("Gómez")
        j3("Ruiz")
        j4("Sanz")
    end
    q1 --- j1
    q1 --- j2
    q2 --- j3
    q1 ~~~ j4
  • “Cada equipo tiene fichados uno o varios jugadores” (1,n) junto a JUGADOR.
  • “Cada jugador está fichado como mucho por un equipo” (0,1) junto a EQUIPO. Sanz es agente libre.

3.6. Resumen de las relaciones 1:N

Combinación (lado 1 – lado N) Hijo sin padre Padre sin hijos Ejemplo
(0,1) – (0,n) Permitido Permitido DEPARTAMENTO – EMPLEADO (EMPRESA)
(1,1) – (0,n) Prohibido Permitido CLIENTE – PEDIDO (EMPRESA)
(1,1) – (1,n) Prohibido Prohibido PROVINCIA – MUNICIPIO
(0,1) – (1,n) Permitido Prohibido EQUIPO – JUGADOR (agentes libres)

💡 Consejo: Para no liarte, recuerda: en una 1:N la pareja junto al padre responde a “¿cuántos padres tiene un hijo?” (siempre máximo 1) y la pareja junto al hijo responde a “¿cuántos hijos tiene un padre?” (máximo n).


4. Correspondencia N:M

4.1. Concepto

📘 Concepto: En una relación N:M (muchos a muchos), cada ocurrencia de A puede relacionarse con varias de B y cada ocurrencia de B con varias de A. Las dos cardinalidades máximas son mayores que 1.

En el diagrama de ocurrencias de una N:M las líneas forman una red: hay ejemplares de ambos lados con varias líneas. Se usa N:M (y no N:N) para subrayar que el número de ocurrencias relacionadas en un sentido no tiene por qué coincidir con el del otro.

Hay tres combinaciones de mínimas: (0,n)-(0,n), (1,n)-(0,n) y (1,n)-(1,n).

4.2. Combinación (0,n) – (0,n)

💻 Ejemplo (esquema EMPRESA): Un empleado puede estar asignado a varios proyectos y en un proyecto trabajan varios empleados. Hay empleados que no participan en ningún proyecto (por ejemplo, la directora general, 100) y proyectos todavía sin nadie asignado (el proyecto 5, “Plan estratégico 2027”).

flowchart LR
    EMPLEADO[EMPLEADO] ---|"(0,n)"| asignado{"está asignado a<br/>N:M"}
    asignado ---|"(0,n)"| PROYECTO[PROYECTO]
    EMPLEADO --- e_id([<u>emp_id</u>])
    EMPLEADO --- e_nombre([nombre])
    PROYECTO --- y_id([<u>proyecto_id</u>])
    PROYECTO --- y_nombre([nombre])
flowchart LR
    subgraph S_EMP["EMPLEADO"]
        e120("120 Pablo")
        e140("140 Nuria")
        e122("122 Iván")
        e100("100 Ana")
    end
    subgraph S_PRY["PROYECTO"]
        y1("1 Migración a la nube")
        y2("2 Nueva tienda online")
        y3("3 Campaña Navidad")
        y5("5 Plan estratégico")
    end
    e120 --- y1
    e120 --- y2
    e140 --- y2
    e140 --- y3
    e122 --- y2
    e100 ~~~ y5
  • “Cada empleado está asignado a ninguno, uno o varios proyectos” (0,n) junto a PROYECTO.
  • “En cada proyecto están asignados ninguno, uno o varios empleados” (0,n) junto a EMPLEADO.

Pablo (120) está en los proyectos 1 y 2; el proyecto 2 tiene a Pablo, Nuria e Iván. En EMPRESA esta relación es la tabla ASIGNACIONES, que además guarda atributos de la relación (sección 6).

4.3. Combinación (1,n) – (0,n)

💻 Ejemplo (biblioteca): Todo libro del catálogo tiene al menos un autor (puede tener varios). La biblioteca registra autores que todavía no tienen ningún libro en su fondo (porque se han pedido sus obras o figuran en un índice de autoridades), y un autor puede haber escrito muchos libros.

flowchart LR
    AUTOR[AUTOR] ---|"(1,n)"| escribe{"escribe<br/>N:M"}
    escribe ---|"(0,n)"| LIBRO[LIBRO]
    AUTOR --- au_id([<u>cod_autor</u>])
    AUTOR --- au_nombre([nombre])
    LIBRO --- l_isbn([<u>isbn</u>])
    LIBRO --- l_titulo([titulo])
flowchart LR
    subgraph S_AUT["AUTOR"]
        a1("Elmasri")
        a2("Navathe")
        a3("Date")
        a4("Codd")
    end
    subgraph S_LIB["LIBRO"]
        l1("Fundamentos de Sistemas de BD")
        l2("Introducción a los Sistemas de BD")
        l3("Database Systems: Models")
    end
    a1 --- l1
    a2 --- l1
    a3 --- l2
    a1 --- l3
    a4 ~~~ l3
  • “Cada autor escribe ninguno, uno o varios libros” (0,n) junto a LIBRO. Codd figura como autor pero no hay libros suyos en el fondo.
  • “Cada libro es escrito por uno o varios autores” (1,n) junto a AUTOR. No hay libros anónimos en este catálogo (si los hubiera, sería (0,n)).

💻 Ejemplo (esquema EMPRESA): Otro caso (1,n)-(0,n) es PEDIDO contiene PRODUCTO: todo pedido contiene al menos un producto (1,n junto a PRODUCTO) y un producto aparece en ninguno o en muchos pedidos (0,n junto a PEDIDO; el producto 14 está descatalogado y nunca se ha vendido). En EMPRESA se ha modelado con la entidad débil LINEAS_PEDIDO, que estudiarás en el módulo de entidades débiles.

4.4. Combinación (1,n) – (1,n)

💻 Ejemplo (transporte): Cada línea de metro tiene parada en varias estaciones y por cada estación pasa al menos una línea (en las estaciones de correspondencia, varias). No se registran estaciones cerradas ni líneas sin paradas.

flowchart LR
    LINEA[LINEA_METRO] ---|"(1,n)"| para{"para en<br/>N:M"}
    para ---|"(1,n)"| ESTACION[ESTACIÓN]
    LINEA --- li_num([<u>numero</u>])
    LINEA --- li_color([color])
    ESTACION --- es_cod([<u>cod_estacion</u>])
    ESTACION --- es_nombre([nombre])
flowchart LR
    subgraph S_LIN["LINEA_METRO"]
        l1("L1")
        l3("L3")
        l5("L5")
    end
    subgraph S_EST["ESTACIÓN"]
        s1("Sol")
        s2("Callao")
        s3("Gran Vía")
        s4("Ópera")
        s5("Lavapiés")
    end
    l1 --- s1
    l1 --- s3
    l3 --- s1
    l3 --- s2
    l3 --- s5
    l5 --- s2
    l5 --- s4
  • “Cada línea para en una o varias estaciones” (1,n) junto a ESTACIÓN.
  • “En cada estación paran una o varias líneas” (1,n) junto a LINEA_METRO. Sol y Callao son estaciones de correspondencia.

💡 Consejo: Mira el enunciado con lupa: una línea con una sola parada no es una línea. Lo realista sería (2,n) junto a ESTACIÓN. Es el primer ejemplo de cardinalidad concreta distinta de 0, 1 y n (sección 5).

4.5. Resumen de las relaciones N:M

Combinación Ejemplo Comentario
(0,n) – (0,n) EMPLEADO – PROYECTO (EMPRESA) La más frecuente en N:M; nadie está obligado
(1,n) – (0,n) AUTOR – LIBRO; PRODUCTO – PEDIDO Una de las dos entidades no puede existir sin la otra
(1,n) – (1,n) LINEA_METRO – ESTACIÓN Ambas obligadas: dar de alta exige crear ocurrencias de las dos a la vez

4.6. Catálogo completo de las diez combinaciones

Cada extremo de una relación binaria puede llevar una de cuatro parejas básicas: (0,1), (1,1), (0,n) o (1,n). Las combinaciones distintas (sin contar el orden, porque (0,1)-(1,1) es la misma que (1,1)-(0,1) leída al revés) son diez:

# Pareja junto a A Pareja junto a B Correspondencia Ejemplo del módulo
1 (0,1) (0,1) 1:1 EMPLEADO – PLAZA_GARAJE
2 (1,1) (0,1) 1:1 CIUDAD – PAÍS (capital)
3 (1,1) (1,1) 1:1 USUARIO – PERFIL
4 (0,1) (0,n) 1:N DEPARTAMENTO – EMPLEADO
5 (1,1) (0,n) 1:N CLIENTE – PEDIDO
6 (1,1) (1,n) 1:N PROVINCIA – MUNICIPIO
7 (0,1) (1,n) 1:N EQUIPO – JUGADOR
8 (0,n) (0,n) N:M EMPLEADO – PROYECTO
9 (1,n) (0,n) N:M AUTOR – LIBRO
10 (1,n) (1,n) N:M LINEA_METRO – ESTACIÓN

✏️ Ejercicio: Para cada fila de la tabla, escribe en una hoja las dos frases de lectura (una desde cada entidad) sin mirar las secciones anteriores. Después compruébalas. Si en alguna te has equivocado de extremo, repasa la sección 1.2.


5. Cardinalidades concretas distintas de 0, 1 y n

5.1. Cuándo aparecen

La notación (mín, máx) admite cualquier número natural en ambas posiciones, siempre que mín ≤ máx y máx ≥ 1. Se usan cuando el universo del discurso impone límites numéricos fijos:

Regla del negocio Pareja Dónde se escribe
Un socio puede tener a la vez como máximo 3 libros prestados (0,3) Junto a EJEMPLAR
Un grupo de prácticas tiene entre 2 y 5 alumnos (2,5) Junto a ALUMNO
Un tribunal de TFG lo forman exactamente 3 profesores (3,3) Junto a PROFESOR
Un partido lo disputan exactamente 2 equipos (2,2) Junto a EQUIPO
Una línea de metro tiene al menos 2 estaciones (2,n) Junto a ESTACIÓN
Un coche tiene como máximo 2 conductores habituales asegurados (1,2) Junto a CONDUCTOR

⚠️ Importante: A efectos del tipo de correspondencia, cualquier máximo mayor que 1 cuenta como “N”. Una relación (1,1)-(0,3) es 1:N, y una (3,3)-(0,n) es N:M. Lo que cambia es que la base de datos deberá controlar el límite concreto.

5.2. Ejemplo: préstamos con límite (0,3)

💻 Ejemplo (biblioteca): “Cada socio puede tener en préstamo, en un momento dado, un máximo de tres ejemplares. Un ejemplar está prestado a un socio o está en la estantería.”

flowchart LR
    SOCIO[SOCIO] ---|"(0,1)"| prestado{"tiene en préstamo<br/>1:N"}
    prestado ---|"(0,3)"| EJEMPLAR[EJEMPLAR]
    SOCIO --- s_num([<u>num_socio</u>])
    SOCIO --- s_nombre([nombre])
    EJEMPLAR --- x_cod([<u>cod_ejemplar</u>])
    EJEMPLAR --- x_estado([estado])
flowchart LR
    subgraph S_SOC["SOCIO"]
        s1("S-01 Ana")
        s2("S-02 Luis")
    end
    subgraph S_EJE["EJEMPLAR"]
        x1("E-100")
        x2("E-101")
        x3("E-102")
        x4("E-103")
        x5("E-104")
    end
    s1 --- x1
    s1 --- x2
    s1 --- x3
    s2 --- x4
    s2 ~~~ x5
  • “Cada socio tiene en préstamo entre 0 y 3 ejemplares” (0,3) junto a EJEMPLAR. Ana ha llegado al límite: un cuarto préstamo violaría la restricción.
  • “Cada ejemplar está prestado como mucho a un socio” (0,1) junto a SOCIO. El E-104 está en la estantería.

Fíjate en que el enunciado dice “a la vez”: esta relación representa los préstamos vigentes, no el historial. Si hubiera que guardar todos los préstamos pasados, el mismo socio podría llevarse el mismo ejemplar varias veces y el modelo cambia por completo (sección 7).

5.3. Ejemplo: grupos de prácticas (2,5) y tribunales (3,3)

flowchart LR
    ALUMNO[ALUMNO] ---|"(2,5)"| forma{"forma parte de<br/>N:1"}
    forma ---|"(1,1)"| GRUPO[GRUPO_PRACTICAS]
    ALUMNO --- al_exp([<u>expediente</u>])
    GRUPO --- gr_cod([<u>cod_grupo</u>])
  • “Cada grupo de prácticas está formado por entre 2 y 5 alumnos” (2,5) junto a ALUMNO.
  • “Cada alumno forma parte de exactamente un grupo de prácticas” (1,1) junto a GRUPO_PRACTICAS.
flowchart LR
    PROFESOR[PROFESOR] ---|"(3,3)"| evalua{"evalúa<br/>N:M"}
    evalua ---|"(0,n)"| TFG[TFG]
    PROFESOR --- pf_dni([<u>dni</u>])
    TFG --- t_cod([<u>cod_tfg</u>])
    TFG --- t_titulo([titulo])
  • “Cada TFG es evaluado por exactamente 3 profesores” (3,3) junto a PROFESOR.
  • “Cada profesor evalúa ninguno, uno o varios TFG” (0,n) junto a TFG.

💡 Consejo: Cuando un número fijo de participantes tiene papeles distintos (presidente, secretario y vocal del tribunal; equipo local y visitante de un partido), suele ser mejor modelar varias relaciones con (1,1) cada una que una sola relación (3,3) o (2,2). Lo ves en la sección 8.

5.4. Cómo anotar límites que no son constantes

A veces el límite depende de un dato: “un socio normal puede tener 3 préstamos y un socio premium, 6”; “un aula admite tantos alumnos como su aforo”. Una pareja fija no puede expresarlo. En estos casos:

  1. Pon en el diagrama la pareja más general que sea cierta, normalmente (0,n).
  2. Añade una restricción semántica numerada y escrita en lenguaje natural debajo del diagrama (o en una nota unida al rombo con línea discontinua).
flowchart LR
    SOCIO[SOCIO] ---|"(0,1)"| prestado{"tiene en préstamo<br/>1:N"}
    prestado ---|"(0,n)"| EJEMPLAR[EJEMPLAR]
    SOCIO --- s_num([<u>num_socio</u>])
    SOCIO --- s_tipo([tipo])
    EJEMPLAR --- x_cod([<u>cod_ejemplar</u>])
    nota1["RS1: máximo 3 préstamos si tipo = NORMAL<br/>y 6 si tipo = PREMIUM"] -.- prestado

Restricciones semánticas:

  • RS1: Un socio de tipo NORMAL no puede tener más de 3 ejemplares en préstamo a la vez; uno de tipo PREMIUM, no más de 6.

⚠️ Importante: Las cardinalidades concretas (como (0,3)) y las restricciones semánticas no se pueden imponer con una clave ajena en el modelo relacional. En Oracle requieren una aserción (disponible desde Oracle 26ai), un disparador (PL/SQL, ver el Curso de Oracle PL/SQL) o control en la aplicación. Aun así, deben figurar en el esquema conceptual: el diseño documenta las reglas, aunque luego cueste implementarlas.


6. Atributos de relación

6.1. Concepto y prueba de dependencia

📘 Concepto: Un atributo de relación es una propiedad que no describe a ninguna de las dos entidades por separado, sino a la asociación entre ellas: su valor depende de la pareja (a, b) y no de a ni de b individualmente.

El módulo 06 ya presentó la idea y la tabla de dónde colocarlos según la cardinalidad; aquí la desarrollamos con más casos. La prueba para saber de quién es un atributo es preguntarse “¿de qué depende su valor?”:

Atributo ¿Depende solo del alumno? ¿Solo de la asignatura? ¿Del par (alumno, asignatura)? Conclusión
fecha_nacimiento Sí No — Atributo de ALUMNO
creditos No Sí — Atributo de ASIGNATURA
nota_final No No Sí Atributo de la relación cursa

Los atributos de relación se dibujan unidos al rombo:

flowchart LR
    ALUMNO[ALUMNO] ---|"(0,n)"| cursa{"cursa<br/>N:M"}
    cursa ---|"(0,n)"| ASIGNATURA[ASIGNATURA]
    ALUMNO --- al_exp([<u>expediente</u>])
    ALUMNO --- al_fnac([fecha_nacimiento])
    ASIGNATURA --- as_cod([<u>codigo</u>])
    ASIGNATURA --- as_cred([creditos])
    cursa --- cu_nota(["nota_final (0,1)"])

La nota es opcional (0,1) porque, mientras el curso está en marcha, el alumno cursa la asignatura pero aún no tiene nota.

6.2. Atributos en relaciones N:M: deben quedarse en la relación

En una N:M el atributo no puede migrar a ninguna de las entidades. Compruébalo con ASIGNACIONES de EMPRESA, que tiene los atributos fecha_asignacion, horas y funcion:

flowchart LR
    EMPLEADO[EMPLEADO] ---|"(0,n)"| asignado{"está asignado a<br/>N:M"}
    asignado ---|"(0,n)"| PROYECTO[PROYECTO]
    EMPLEADO --- e_id([<u>emp_id</u>])
    PROYECTO --- y_id([<u>proyecto_id</u>])
    asignado --- as_fecha([fecha_asignacion])
    asignado --- as_horas([horas])
    asignado --- as_func(["funcion (0,1)"])

Si intentas mover horas a EMPLEADO, Pablo (120), que trabaja 450 horas en el proyecto 1 y 300 en el 2, necesitaría dos valores en el mismo atributo: el atributo se volvería multivaluado y, además, perdería la información de a qué proyecto corresponde cada número. Si lo mueves a PROYECTO, el proyecto 2 tendría cuatro valores de horas (uno por empleado). Por eso:

⚠️ Importante: En una relación N:M, los atributos que dependen del par deben quedarse en la relación. Moverlos a una entidad es un error de diseño grave.

6.3. Atributos en relaciones 1:N: pueden migrar al lado N

En una 1:N cada ocurrencia del lado N participa como mucho una vez en la relación. Por tanto, dado un ejemplar del lado N, existe a lo sumo un par en el que interviene, y un atributo del par se puede guardar en ese ejemplar sin ambigüedad.

💻 Ejemplo: “Se quiere saber desde qué fecha está adscrito cada empleado a su departamento.”

flowchart LR
    DEPARTAMENTO[DEPARTAMENTO] ---|"(0,1)"| adscrito{"tiene adscrito<br/>1:N"}
    adscrito ---|"(0,n)"| EMPLEADO[EMPLEADO]
    DEPARTAMENTO --- d_id([<u>dept_id</u>])
    EMPLEADO --- e_id([<u>emp_id</u>])
    adscrito --- ad_fecha([fecha_incorporacion])

Como cada empleado está en un solo departamento (máximo 1 junto a DEPARTAMENTO), la fecha de incorporación tiene un único valor por empleado. Son igual de correctas dos versiones:

  • Versión A: fecha_incorporacion como atributo de la relación (como en el diagrama). Expresa con más precisión su significado: describe la adscripción, no al empleado.
  • Versión B: fecha_incorporacion como atributo de EMPLEADO, con cardinalidad (0,1) porque los empleados sin departamento no la tienen.

Nunca puede migrar al lado 1 (DEPARTAMENTO): el departamento 20 tiene seis empleados, cada uno con su fecha.

💡 Consejo: En el diseño conceptual se recomienda dejar el atributo en la relación (versión A), porque documenta mejor la semántica y facilita cambiar la cardinalidad en el futuro: si mañana un empleado puede estar en varios departamentos, la relación pasa a N:M y el atributo ya está donde debe. En el paso a relacional, de todos modos, acabará en la tabla del lado N junto a la clave ajena.

6.4. Atributos en relaciones 1:1: pueden migrar a cualquiera de los dos lados

En una 1:1 cada ocurrencia de ambos lados participa como mucho una vez, así que el atributo podría ir a cualquiera de las dos entidades. El criterio para elegir:

  1. Preferiblemente, al lado con participación obligatoria (mínima 1 en el otro extremo), para no generar valores nulos.
  2. Si ambos son opcionales, al lado donde tenga más sentido o donde se consulte más.

💻 Ejemplo: EMPLEADO (0,1) – tiene asignada – (0,1) PLAZA_GARAJE con el atributo fecha_asignacion. Si va en EMPLEADO, será nulo para todos los que no tienen plaza; si va en PLAZA_GARAJE, será nulo para las plazas libres. Como ninguna opción evita los nulos, en el diseño conceptual se deja en la relación.

6.5. Atributos que dependen de la ocurrencia de relación (y no de la entidad)

Hay atributos que parecen de una entidad y, sin embargo, su valor puede ser distinto en cada ocurrencia de la relación. El ejemplo clásico es el precio:

💻 Ejemplo (esquema EMPRESA): PRODUCTOS tiene la columna precio (el precio actual de catálogo) y LINEAS_PEDIDO tiene precio_unitario (el precio al que se vendió en ese pedido concreto). En los datos de ejemplo coinciden (el “Monitor 27 4K” cuesta 329 € y a ese precio se vendió en el pedido 5004), pero si mañana se rebaja a 299 €, el pedido 5004 debe seguir diciendo 329 €. Ambos datos son necesarios: el primero describe al producto; el segundo, a la ocurrencia “el pedido 5004 contiene el Monitor 27 4K”.

flowchart LR
    PEDIDO[PEDIDO] ---|"(0,n)"| contiene{"contiene<br/>N:M"}
    contiene ---|"(1,n)"| PRODUCTO[PRODUCTO]
    PEDIDO --- p_id([<u>pedido_id</u>])
    PEDIDO --- p_fecha([fecha_pedido])
    PRODUCTO --- r_id([<u>producto_id</u>])
    PRODUCTO --- r_precio([precio])
    contiene --- c_cant([cantidad])
    contiene --- c_precio([precio_unitario])
    contiene --- c_desc([descuento])

Otros casos del mismo tipo:

Atributo de la entidad Atributo de la relación Por qué son distintos
PRODUCTO.precio contiene.precio_unitario El precio cambia con el tiempo; el pedido guarda el de la venta
EMPLEADO.salario asignado.coste_hora Un proyecto puede facturar a otra tarifa
HABITACIÓN.precio_noche reserva.precio_pactado Ofertas, temporada, descuentos
JUGADOR.dorsal_habitual convocado.dorsal En cada partido puede llevar otro dorsal
ACTOR.nombre interpreta.personaje El personaje depende de la película

⚠️ Importante: Pregúntate siempre: “Si este valor cambia mañana, ¿deben cambiar también los datos del pasado?” Si la respuesta es no (las facturas antiguas no deben cambiar su importe), el valor tiene que copiarse en la ocurrencia de relación en el momento en que se produce.

6.6. Atributos derivados en relaciones

Igual que en las entidades, un atributo de relación puede ser derivado. En contiene, el importe_linea = cantidad × precio_unitario × (1 − descuento/100) se puede calcular: se dibuja con borde discontinuo o, mejor, se omite y se documenta la regla de cálculo.

flowchart LR
    classDef derivado stroke-dasharray: 5 5
    PEDIDO[PEDIDO] ---|"(0,n)"| contiene{"contiene<br/>N:M"}
    contiene ---|"(1,n)"| PRODUCTO[PRODUCTO]
    contiene --- c_cant([cantidad])
    contiene --- c_precio([precio_unitario])
    contiene --- c_imp([importe_linea]):::derivado

7. Relaciones N:M que deben registrar repeticiones en el tiempo

7.1. El problema

El módulo 06 te avisó de esta trampa; ahora vamos a resolverla a fondo. Recuerda de la sección 1.1 que una relación es un conjunto de pares: el par (a, b) aparece como mucho una vez. Esto se convierte en un problema cuando el mismo par puede asociarse varias veces a lo largo del tiempo.

💻 Ejemplo (centro de salud): “Un paciente puede acudir a consulta con varios médicos y un médico atiende a muchos pacientes. De cada consulta se guarda la fecha, la hora y el diagnóstico.” Un primer diseño, aparentemente razonable:

flowchart LR
    PACIENTE[PACIENTE] ---|"(0,n)"| consulta{"consulta con<br/>N:M"}
    consulta ---|"(0,n)"| MEDICO[MÉDICO]
    PACIENTE --- pa_nss([<u>nss</u>])
    MEDICO --- me_col([<u>num_colegiado</u>])
    consulta --- co_fecha([fecha])
    consulta --- co_diag([diagnostico])

¿Qué ocurre si Ana va al Dr. Pérez el 3 de marzo y vuelve el 10 de abril? El par (Ana, Dr. Pérez) ya existe; no puede haber una segunda ocurrencia. El diseño solo permite guardar una consulta por pareja paciente-médico: la segunda machacaría a la primera o sería rechazada. El diseño es incorrecto para este enunciado, aunque las cardinalidades parezcan bien.

⚠️ Importante: Siempre que modeles una N:M con un atributo de tipo fecha, pregúntate: “¿puede repetirse el mismo par en otra fecha?” Si la respuesta es sí, la relación N:M simple no sirve.

7.2. Solución 1 (recomendada): convertir la relación en una entidad

La ocurrencia que se repite (la consulta) es en realidad un objeto del mundo real: tiene identidad propia, se puede numerar, tiene atributos y quizá se relacione con otras cosas (recetas, pruebas, facturas). Se modela como entidad unida a las dos entidades originales por dos relaciones 1:N:

flowchart LR
    PACIENTE[PACIENTE] ---|"(1,1)"| solicita{"acude a<br/>1:N"}
    solicita ---|"(0,n)"| CONSULTA[CONSULTA]
    CONSULTA ---|"(0,n)"| atiende{"atiende<br/>N:1"}
    atiende ---|"(1,1)"| MEDICO[MÉDICO]
    PACIENTE --- pa_nss([<u>nss</u>])
    MEDICO --- me_col([<u>num_colegiado</u>])
    CONSULTA --- co_id([<u>num_consulta</u>])
    CONSULTA --- co_fh([fecha_hora])
    CONSULTA --- co_diag(["diagnostico (0,1)"])
  • “Cada paciente acude a ninguna o varias consultas” (0,n) junto a CONSULTA; “cada consulta es de exactamente un paciente” (1,1) junto a PACIENTE.
  • “Cada médico atiende ninguna o varias consultas” (0,n) junto a CONSULTA; “cada consulta la atiende exactamente un médico” (1,1) junto a MÉDICO.

Ahora Ana puede tener tantas consultas con el Dr. Pérez como quiera: cada una es una ocurrencia distinta de CONSULTA con su propio número.

💡 Consejo: La entidad CONSULTA también podría no tener un identificador propio e identificarse por (paciente, médico, fecha_hora). En ese caso sería una entidad débil que depende en identificación de PACIENTE y de MÉDICO. Lo estudiarás en el módulo de entidades débiles; por ahora basta con un identificador propio.

7.3. Solución 2: llevar el tiempo al identificador

Otra forma de verlo es que la consulta asocia tres cosas: un paciente, un médico y un instante. Si se modela el tiempo como entidad (FECHA o, mejor, un periodo), la relación pasa a ser ternaria, y la terna (Ana, Dr. Pérez, 03/03) es distinta de (Ana, Dr. Pérez, 10/04). Es una solución que verás en el módulo de relaciones ternarias y n-arias; en la práctica se prefiere la solución 1 salvo que el tiempo tenga entidad propia en el problema (turnos, temporadas, cursos académicos…).

Algunos autores y herramientas permiten también marcar un atributo de la relación como parte de su identificador (por ejemplo, subrayar fecha en la relación). No es notación de Chen estándar, por lo que en este curso no la usaremos en el E/R, pero conviene que sepas que la idea de fondo es la misma: el identificador de cada ocurrencia debe incluir el tiempo.

7.4. Solución 3 (limitada): atributo multivaluado en la relación

Si solo se necesitara guardar las fechas de las visitas (sin más datos por visita), se podría usar un atributo multivaluado fechas en la relación. En cuanto cada visita tiene otros datos (hora, diagnóstico…), habría que convertirlo en un atributo compuesto multivaluado, y el diseño se vuelve confuso. Es una solución válida solo para casos muy simples.

7.5. Avance: cómo se refleja el problema en el modelo relacional

En el modelo relacional una N:M se convierte en una tabla cuya clave primaria es la combinación de las claves de las dos entidades. Mira la de EMPRESA:

ASIGNACIONES (emp_id, proyecto_id, fecha_asignacion, horas, funcion)

  • emp_id → EMPLEADOS(emp_id)
  • proyecto_id → PROYECTOS(proyecto_id)

Con esa clave primaria, un empleado no puede ser asignado dos veces al mismo proyecto: si el negocio necesitara registrar que Pablo salió del proyecto 1 en marzo y volvió en junio, INSERT de la segunda asignación fallaría por clave duplicada. Habría que cambiar la clave (añadir fecha_asignacion a la clave primaria) o crear una entidad ASIGNACIÓN con identificador propio. La decisión se toma en el diseño conceptual, no al escribir el CREATE TABLE.

7.6. Instantánea frente a historia

El mismo par de entidades puede dar relaciones con cardinalidades distintas según se modele el estado actual o la historia:

Enunciado Correspondencia Pareja junto a DEPARTAMENTO
“Cada empleado está en un departamento” 1:N (1,1)
“Se quiere saber en qué departamentos ha estado cada empleado” N:M (1,n) o (0,n)
“Se quiere saber en qué departamentos ha estado y cuándo, pudiendo volver a uno anterior” Entidad ADSCRIPCION —

💡 Consejo: Un diseño muy habitual combina ambas cosas: una relación 1:N “está adscrito” con el estado actual (rápida de consultar) y una entidad HISTORICO_ADSCRIPCION con todos los periodos. El módulo de restricciones avanzadas trata en detalle el modelado de datos históricos.


8. Varias relaciones binarias entre las mismas dos entidades

8.1. Cada significado, una relación

Dos entidades pueden estar unidas por tantas relaciones como significados distintos tenga su asociación. Cada relación tiene su propio nombre, sus propias cardinalidades y sus propios atributos, y sus ocurrencias son independientes.

💻 Ejemplo: “De cada persona se guarda el municipio donde nació, el municipio donde reside y, si trabaja, el municipio donde trabaja.”

flowchart LR
    PERSONA[PERSONA] ---|"(0,n)"| nace{"nació en<br/>N:1"}
    nace ---|"(1,1)"| MUNICIPIO[MUNICIPIO]
    PERSONA ---|"(0,n)"| vive{"reside en<br/>N:1"}
    vive ---|"(1,1)"| MUNICIPIO
    PERSONA ---|"(0,n)"| trabaja{"trabaja en<br/>N:1"}
    trabaja ---|"(0,1)"| MUNICIPIO
    PERSONA --- pe_dni([<u>dni</u>])
    MUNICIPIO --- mu_cod([<u>cod_ine</u>])
Relación Pareja junto a MUNICIPIO Lectura desde PERSONA Pareja junto a PERSONA Lectura desde MUNICIPIO
nació en (1,1) Toda persona nació en exactamente un municipio (0,n) En un municipio han nacido 0 o más personas
reside en (1,1) Toda persona reside en exactamente un municipio (0,n) En un municipio residen 0 o más personas
trabaja en (0,1) Una persona trabaja en un municipio o en ninguno (0,n) En un municipio trabajan 0 o más personas

En el diagrama de ocurrencias, cada línea se etiqueta con la relación a la que pertenece:

flowchart LR
    subgraph S_PER["PERSONA"]
        p1("Ana")
        p2("Luis")
    end
    subgraph S_MUN["MUNICIPIO"]
        m1("Valencia")
        m2("Paterna")
        m3("Teruel")
    end
    p1 ---|"nació en"| m3
    p1 ---|"reside en"| m1
    p1 ---|"trabaja en"| m2
    p2 ---|"nació en"| m1
    p2 ---|"reside en"| m1

Luis nació y reside en Valencia: el mismo par (Luis, Valencia) aparece en dos relaciones distintas, lo cual es perfectamente válido (lo que no puede ocurrir es que aparezca dos veces en la misma relación).

⚠️ Importante: Es un error fusionar las tres en una sola relación “está relacionada con” y añadir un atributo tipo (‘NACIMIENTO’, ‘RESIDENCIA’, ‘TRABAJO’). Se pierden las cardinalidades propias de cada una (con una sola relación no se puede decir que la residencia es obligatoria y el trabajo no) y el diagrama deja de comunicar el significado.

8.2. Ejemplo clásico: pertenece y dirige

💻 Ejemplo: “Cada empleado pertenece a un departamento. Cada departamento está dirigido por uno de sus empleados; un empleado dirige como mucho un departamento.”

flowchart LR
    EMPLEADO[EMPLEADO] ---|"(1,n)"| pertenece{"pertenece a<br/>N:1"}
    pertenece ---|"(1,1)"| DEPARTAMENTO[DEPARTAMENTO]
    EMPLEADO ---|"(1,1)"| dirige{"dirige<br/>1:1"}
    dirige ---|"(0,1)"| DEPARTAMENTO
    EMPLEADO --- e_id([<u>emp_id</u>])
    DEPARTAMENTO --- d_id([<u>dept_id</u>])
    dirige --- di_fecha([fecha_inicio])
  • pertenece a (N:1): cada empleado pertenece exactamente a 1 departamento (1,1); cada departamento tiene al menos un empleado (1,n), porque tiene al menos a su director.
  • dirige (1:1): cada departamento está dirigido por exactamente 1 empleado (1,1) junto a EMPLEADO; cada empleado dirige como mucho 1 departamento (0,1) junto a DEPARTAMENTO.

Las dos relaciones no son independientes del todo: el enunciado dice “uno de sus empleados”. Esa regla no la expresa ninguna cardinalidad y se anota como restricción semántica:

  • RS1: El empleado que dirige un departamento debe pertenecer a ese mismo departamento (restricción de inclusión entre dirige y pertenece a).

Las restricciones entre relaciones (inclusión, exclusión, exclusividad) se estudian a fondo en el módulo de restricciones avanzadas.

8.3. Número fijo de participantes con papeles distintos: una relación o varias

💻 Ejemplo (liga deportiva): “Cada partido lo disputan dos equipos, uno como local y otro como visitante.”

Opción A: una sola relación (2,2).

flowchart LR
    EQUIPO[EQUIPO] ---|"(2,2)"| disputa{"disputa<br/>N:M"}
    disputa ---|"(0,n)"| PARTIDO[PARTIDO]
    EQUIPO --- q_cod([<u>cod_equipo</u>])
    PARTIDO --- pa_cod([<u>cod_partido</u>])
    disputa --- di_cond([condicion])

El atributo condicion (‘LOCAL’/’VISITANTE’) distingue el papel. Pero el diagrama no garantiza que haya exactamente un local y un visitante (podrían ser los dos locales), y obtener “el local del partido 7” exige filtrar por un valor.

Opción B (recomendada): dos relaciones (1,1).

flowchart LR
    EQUIPO[EQUIPO] ---|"(1,1)"| local{"juega como local<br/>1:N"}
    local ---|"(0,n)"| PARTIDO[PARTIDO]
    EQUIPO ---|"(1,1)"| visitante{"juega como visitante<br/>1:N"}
    visitante ---|"(0,n)"| PARTIDO
    EQUIPO --- q_cod([<u>cod_equipo</u>])
    PARTIDO --- pa_cod([<u>cod_partido</u>])
    PARTIDO --- pa_fecha([fecha_hora])
  • RS1: El equipo local y el visitante de un partido deben ser distintos.
Criterio Opción A: una relación (2,2) Opción B: dos relaciones (1,1)
Expresa los papeles Con un atributo Con el nombre de cada relación
Garantiza un local y un visitante No (restricción semántica) Sí, por las cardinalidades
Impide que un equipo juegue contra sí mismo No No (RS1), pero es fácil de comprobar
Correspondencia N:M Dos 1:N
Paso a relacional Tabla intermedia Dos claves ajenas en PARTIDO

💡 Consejo: Usa una sola relación con máximo fijo cuando los participantes son intercambiables (los tres miembros de un tribunal de TFG si no tienen cargos, los dos conductores asegurados). Usa varias relaciones cuando cada participante tiene un papel distinto (local/visitante, presidente/secretario/vocal, origen/destino).


9. Relación frente a atributo que “apunta” a otra entidad

9.1. El error típico

Quien ya ha trabajado con tablas tiende a pensar en claves ajenas y dibuja algo así:

flowchart LR
    CLIENTE[CLIENTE] --- c_nif([<u>nif</u>])
    CLIENTE --- c_nombre([nombre])
    PEDIDO[PEDIDO] --- p_id([<u>pedido_id</u>])
    PEDIDO --- p_fecha([fecha_pedido])
    PEDIDO --- p_nif([nif_cliente])

Incorrecto. Las dos entidades aparecen desconectadas, y la asociación entre ellas está escondida en el atributo nif_cliente. Problemas:

  1. En el modelo E/R no existen las claves ajenas. Las asociaciones entre entidades se representan siempre con relaciones. Las claves ajenas aparecerán al transformar el diagrama al modelo relacional.
  2. Se pierden las cardinalidades: el diagrama no dice si un pedido puede no tener cliente o si un cliente puede tener varios pedidos.
  3. El diagrama no comunica el significado: quien lo lee no ve que los pedidos son de los clientes.
  4. Al transformar el diagrama, la regla de las relaciones 1:N añadirá otra clave ajena en PEDIDO, y acabarás con el dato duplicado.

Correcto:

flowchart LR
    CLIENTE[CLIENTE] ---|"(1,1)"| realiza{"realiza<br/>1:N"}
    realiza ---|"(0,n)"| PEDIDO[PEDIDO]
    CLIENTE --- c_nif([<u>nif</u>])
    CLIENTE --- c_nombre([nombre])
    PEDIDO --- p_id([<u>pedido_id</u>])
    PEDIDO --- p_fecha([fecha_pedido])

⚠️ Importante: Regla práctica: si un atributo de una entidad contiene el identificador (o el nombre) de otra entidad del diagrama, casi seguro que falta una relación. Bórralo y dibuja el rombo.

9.2. Cuándo sí es correcto un atributo

No todo lo que tiene “nombre de cosa” debe ser una entidad. nombre_banco en CUENTA, pais_nacimiento en PERSONA o marca en VEHÍCULO pueden ser simples atributos si en el universo del discurso no interesan como objetos. La decisión es la de “entidad o atributo” que viste en el módulo de entidades y atributos:

Pregunta Si la respuesta es sí…
¿Tiene atributos propios que hay que guardar (dirección del banco, código ISO del país)? Entidad + relación
¿Tiene que existir aunque no esté relacionado con nada (un país sin personas nacidas allí registradas)? Entidad + relación
¿Participa en otras relaciones? Entidad + relación
¿Hay que controlar que sus valores pertenezcan a una lista válida y gestionarla (alta, baja, modificación)? Entidad + relación (catálogo)
¿Es solo un texto descriptivo que nadie consulta por separado? Atributo

💡 Consejo: Lo que nunca es correcto es tener a la vez la entidad, la relación y un atributo con el identificador de la otra entidad. Es redundancia pura: el mismo hecho se guarda dos veces y antes o después las dos copias discreparán.


10. Relación 1:1 frente a fusionar las entidades

10.1. El dilema

Cuando dos entidades están unidas por una 1:1, cada ocurrencia de una “va emparejada” con una de la otra, así que es legítimo preguntarse si no son la misma cosa descrita en dos sitios. Fusionarlas (llevar todos los atributos a una sola entidad) simplifica el esquema; separarlas lo hace más fiel a la realidad. ¿Cómo decidir?

10.2. Criterios

Criterio Favorece fusionar Favorece mantener separadas
Cardinalidades mínimas (1,1)-(1,1): siempre van juntas Alguna mínima 0: hay ocurrencias sueltas
Ciclo de vida Se crean y se destruyen a la vez Se crean o se borran en momentos distintos
Naturaleza Son dos vistas del mismo objeto real Son objetos reales distintos (una persona y su coche)
Otras relaciones Ninguna de las dos se relaciona con terceras entidades por separado Cada una tiene sus propias relaciones
Estabilidad de la pareja El emparejamiento no cambia nunca El emparejamiento cambia con el tiempo (reasignar plaza, cambiar de director)
Evolución previsible La 1:1 es permanente Es probable que pase a 1:N (un usuario con varios perfiles)
Número de atributos Pocos atributos en una de ellas Ambas tienen identidad y muchos atributos propios

📘 Concepto: El criterio más fuerte es el de la identidad: si existe un objeto del mundo real que existe sin el otro (una plaza de garaje sin asignar, un empleado sin plaza), son entidades distintas. Si uno “es parte” o “es una faceta” del otro y no tiene sentido por separado, fusiónalas.

10.3. Casos

Relación 1:1 Cardinalidades Decisión Razón
USUARIO – PERFIL (1,1)-(1,1) Fusionar en USUARIO Mismo ciclo de vida; el perfil es una faceta del usuario
EMPLEADO – PLAZA_GARAJE (0,1)-(0,1) Separadas Plazas libres y empleados sin plaza; la asignación cambia
EMPLEADO – DEPARTAMENTO (dirige) (1,1)-(0,1) Separadas Son objetos distintos con muchas otras relaciones
PEDIDO – FACTURA (1,1)-(0,1) Separadas La factura se emite después; además, es previsible facturar varios pedidos juntos
PERSONA – DNI (documento) (1,1)-(1,1) Fusionar: el número y la caducidad del DNI son atributos de PERSONA No se gestiona el documento como objeto propio
COCHE – MOTOR (0,1)-(0,1) en un taller que almacena motores Separadas Los motores se desmontan y se cambian de coche

El resultado de fusionar USUARIO y PERFIL:

flowchart LR
    USUARIO[USUARIO] --- u_login([<u>login</u>])
    USUARIO --- u_email(["email (AK)"])
    USUARIO --- u_hash([hash_clave])
    USUARIO --- u_url(["url_publica (AK)"])
    USUARIO --- u_bio(["biografia (0,1)"])
    USUARIO --- u_foto(["foto (0,1)"])

El antiguo identificador de PERFIL (url_publica) pasa a ser un identificador alternativo (clave candidata) de USUARIO, y por eso se marca con (AK), como el email. Si una de las entidades fusionadas era opcional, sus atributos pasan a ser opcionales (0,1).

💡 Consejo: Separar datos por motivos de seguridad o rendimiento (los datos médicos de un empleado en otra tabla con permisos distintos, una foto grande que se consulta poco) es una decisión de diseño físico, no conceptual. En el E/R modela la realidad; esas particiones se deciden más adelante.


11. Entidad frente a relación

11.1. Cuándo una relación debe convertirse en entidad

Convertir una relación en entidad se llama reificación (reification): “cosificar” la asociación. Hazlo cuando se cumpla alguno de estos criterios:

Criterio Ejemplo
El mismo par puede repetirse en el tiempo Un paciente vuelve al mismo médico (sección 7)
La asociación tiene un identificador propio usado en el mundo real Número de matrícula, número de préstamo, número de contrato
La asociación tiene muchos atributos y su propio ciclo de vida (estados, fechas de alta, baja, modificación) Matrícula: solicitada → admitida → pagada → anulada
La asociación debe relacionarse con otras entidades Cada matrícula genera pagos; cada préstamo puede generar una multa
Hay que tratar la asociación como un “documento” Contrato, reserva, factura, póliza

📘 Concepto: En el E/R básico una relación no puede participar en otra relación. Si necesitas relacionar una asociación con una tercera entidad, tienes dos caminos: convertirla en entidad (este apartado) o usar una agregación (lo verás en el módulo de agregación).

11.2. Ejemplo: la matrícula

💻 Ejemplo (universidad): “Un alumno se matricula de asignaturas cada curso académico. De cada matrícula se guarda el número de matrícula, la fecha, el curso académico, la convocatoria y la nota. Una matrícula puede pagarse en varios plazos.” Con una relación N:M no se puede registrar que un alumno se matricula de la misma asignatura en dos cursos distintos (repetición), ni relacionar la matrícula con sus pagos.

flowchart LR
    ALUMNO[ALUMNO] ---|"(1,1)"| hace{"formaliza<br/>1:N"}
    hace ---|"(0,n)"| MATRICULA[MATRÍCULA]
    MATRICULA ---|"(0,n)"| de{"es de<br/>N:1"}
    de ---|"(1,1)"| ASIGNATURA[ASIGNATURA]
    MATRICULA ---|"(1,1)"| genera{"se paga en<br/>1:N"}
    genera ---|"(1,n)"| PLAZO[PLAZO_PAGO]
    ALUMNO --- al_exp([<u>expediente</u>])
    ASIGNATURA --- as_cod([<u>codigo</u>])
    MATRICULA --- ma_num([<u>num_matricula</u>])
    MATRICULA --- ma_curso([curso_academico])
    MATRICULA --- ma_conv([convocatoria])
    MATRICULA --- ma_nota(["nota (0,1)"])
    PLAZO --- pl_num([<u>num_recibo</u>])
    PLAZO --- pl_imp([importe])

11.3. Regla para trasladar las cardinalidades

Al reificar una relación R entre A y B en una entidad E, se obtienen dos relaciones 1:N (A–E y E–B). Las cardinalidades se trasladan así:

Relación nueva Pareja junto a A (o B) Pareja junto a E
A – E (1,1): cada ocurrencia de E es de exactamente un A La pareja que había junto a B en R (cuántos B tenía cada A), con máximo n si puede repetirse
E – B (1,1): cada ocurrencia de E es de exactamente un B La pareja que había junto a A en R (cuántos A tenía cada B), con máximo n si puede repetirse

Ejemplo: si en ALUMNO (0,n) – cursa – (1,n) ASIGNATURA (todo alumno cursa al menos una asignatura; una asignatura puede no tener alumnos), al reificar: ALUMNO (1,1) – formaliza – (1,n) MATRÍCULA y MATRÍCULA (0,n) – es de – (1,1) ASIGNATURA.

11.4. El error contrario: entidades que son relaciones

Si una “entidad” no tiene identificador propio, sus únicos atributos son los identificadores de otras dos entidades y no participa en nada más, es una relación disfrazada:

  • Incorrecto: entidad ASIGNACION con atributos emp_id y proyecto_id, sin relaciones dibujadas.
  • Correcto: relación N:M está asignado a entre EMPLEADO y PROYECTO (como en la sección 6.2).

12. Avance: transformación al modelo relacional

En el módulo de transformación E/R → relacional (módulo 17) verás las reglas completas. Como anticipo, cada correspondencia binaria se transforma así:

Correspondencia Transformación habitual Ejemplo en EMPRESA
1:N Clave ajena en la tabla del lado N que referencia al lado 1. Si la pareja junto al lado 1 es (1,1), la columna es NOT NULL PEDIDOS.cliente_id (NOT NULL), EMPLEADOS.dept_id (admite nulos)
N:M Tabla nueva cuya clave primaria combina las claves de ambas entidades, más los atributos de la relación ASIGNACIONES (emp_id, proyecto_id, ...)
1:1 Clave ajena con UNIQUE en una de las dos tablas (preferiblemente la de participación obligatoria) o fusión en una sola tabla —

PEDIDOS (pedido_id, cliente_id, empleado_id (N), fecha_pedido, fecha_envio (N), estado)

  • cliente_id → CLIENTES(cliente_id)
  • empleado_id → EMPLEADOS(emp_id)

ASIGNACIONES (*emp_id*, *proyecto_id*, fecha_asignacion, horas (N), funcion (N))

  • emp_id → EMPLEADOS(emp_id)
  • proyecto_id → PROYECTOS(proyecto_id)

⚠️ Importante: Las cardinalidades mínimas de 1 en el lado N ((1,n): “toda provincia tiene algún municipio”) y los máximos concretos ((0,3), (2,5)) no se traducen a ninguna restricción estándar de tabla. Se pierden en la transformación y hay que documentarlas como restricciones semánticas. Por eso es tan importante anotarlas bien en el E/R.


13. Errores frecuentes

13.1. Escribir la cardinalidad en el extremo equivocado

Incorrecto (se ha escrito junto a cada entidad “cuántos tiene ella”):

flowchart LR
    CLIENTE[CLIENTE] ---|"(0,n)"| realiza{realiza}
    realiza ---|"(1,1)"| PEDIDO[PEDIDO]

Leído con la convención del curso dice que “un pedido es realizado por varios clientes” y “un cliente realiza exactamente un pedido”: lo contrario de lo que se quería. Correcto: CLIENTE (1,1) – realiza – (0,n) PEDIDO (sección 3.3). Comprueba siempre leyendo la frase en voz alta desde cada entidad.

13.2. Deducir la correspondencia de las mínimas

“Como la pareja es (1,1)-(1,n), la relación es 1:1 porque hay unos”. Incorrecto: la correspondencia sale de los máximos (1 y n), así que es 1:N.

13.3. Mínima 1 cuando hay momentos en que no se cumple

“Todo departamento tiene empleados” suena bien, pero ¿qué pasa el día en que se crea el departamento 70, antes de contratar a nadie? Si el sistema debe permitirlo, la pareja junto a EMPLEADO es (0,n), no (1,n). La mínima debe cumplirse siempre, también en el momento del alta y después de las bajas.

13.4. Atributo de una N:M colocado en una entidad

Incorrecto: horas como atributo de EMPLEADO en EMPLEADO – PROYECTO. Correcto: horas en la relación (sección 6.2).

13.5. N:M con fecha para hechos que se repiten

Incorrecto: PACIENTE – consulta – MÉDICO con atributo fecha. Correcto: entidad CONSULTA (sección 7.2).

13.6. Atributo que referencia otra entidad

Incorrecto: nif_cliente en PEDIDO. Correcto: relación realiza (sección 9).

13.7. Nombres de relación vacíos de significado

Rombos llamados tiene, relación, asociado, R1 o pedido_cliente. Correcto: verbos concretos que se lean en ambos sentidos: realiza, contiene, imparte, está asignado a. Si dos relaciones entre las mismas entidades se llaman tiene1 y tiene2, es la señal de que no has entendido qué significa cada una.

13.8. Relaciones redundantes

Incorrecto: añadir CLIENTE – compra – PRODUCTO cuando ya existen CLIENTE – realiza – PEDIDO y PEDIDO – contiene – PRODUCTO. Los productos que ha comprado un cliente se deducen recorriendo el camino: la nueva relación duplica información.

⚠️ Importante: No todo ciclo es redundante. En EMPRESA, CLIENTE se relaciona con EMPLEADO por dos caminos: el comercial asignado al cliente (CLIENTES.comercial_id) y el empleado que tramitó cada pedido (PEDIDOS.empleado_id). No son el mismo dato (un pedido lo puede tramitar otro empleado), así que ambas relaciones son necesarias. Una relación es redundante solo si su contenido se puede deducir siempre del resto.

13.9. Una relación genérica con un atributo “tipo”

Incorrecto: PERSONA – relacionada con – MUNICIPIO con atributo tipo. Correcto: una relación por significado (sección 8.1).

13.10. Fusionar entidades 1:1 que son objetos distintos

Incorrecto: meter los datos de la plaza de garaje (numero_plaza, planta) como atributos opcionales de EMPLEADO. Se pierden las plazas libres (no se pueden registrar si no hay empleado) y cada reasignación obliga a “mover” atributos de un empleado a otro. Correcto: dos entidades y relación (0,1)-(0,1).


14. Ejercicios resueltos

Ejercicio 1: Leer un diagrama

Lee el siguiente diagrama de un hospital. Escribe las cuatro frases (dos por relación), indica la correspondencia de cada relación y qué participaciones son totales.

flowchart LR
    MEDICO[MÉDICO] ---|"(1,n)"| pertenece{pertenece a}
    pertenece ---|"(1,1)"| SERVICIO[SERVICIO]
    MEDICO ---|"(1,1)"| jefe{es jefe de}
    jefe ---|"(0,1)"| SERVICIO
Ver solución

pertenece a:

  • Desde MÉDICO (leo junto a SERVICIO): “Cada médico pertenece a exactamente un servicio”.
  • Desde SERVICIO (leo junto a MÉDICO): “A cada servicio pertenecen uno o varios médicos”.
  • Máximos 1 (junto a SERVICIO) y n (junto a MÉDICO): 1:N, con SERVICIO en el lado 1.

es jefe de:

  • Desde MÉDICO: “Cada médico es jefe de como mucho un servicio” (0,1).
  • Desde SERVICIO: “Cada servicio tiene como jefe a exactamente un médico” (1,1).
  • Máximos 1 y 1: 1:1.

Participaciones: en pertenece a ambas son totales (todo médico pertenece a un servicio, mínima 1 junto a SERVICIO; todo servicio tiene médicos, mínima 1 junto a MÉDICO). En es jefe de, la de SERVICIO es total (mínima 1 junto a MÉDICO) y la de MÉDICO es parcial (mínima 0 junto a SERVICIO).

Restricción que el diagrama no expresa y convendría anotar: el jefe de un servicio debería pertenecer a ese servicio.

Ejercicio 2: Del enunciado al diagrama (taller mecánico)

“El taller registra los vehículos que repara. Todo vehículo tiene un único propietario, que debe estar registrado como cliente. Un cliente puede tener varios vehículos; no se registran clientes que no tengan al menos un vehículo.” Dibuja el diagrama y justifica cada cardinalidad.

Ver solución
flowchart LR
    CLIENTE[CLIENTE] ---|"(1,1)"| propietario{"es propietario de<br/>1:N"}
    propietario ---|"(1,n)"| VEHICULO[VEHÍCULO]
    CLIENTE --- c_dni([<u>dni</u>])
    CLIENTE --- c_nombre([nombre])
    VEHICULO --- v_mat([<u>matricula</u>])
    VEHICULO --- v_marca([marca])
Pareja Pregunta Respuesta del enunciado
(1,1) junto a CLIENTE ¿Cuántos propietarios tiene un vehículo? “Un único propietario” → mínimo 1, máximo 1
(1,n) junto a VEHÍCULO ¿Cuántos vehículos tiene un cliente? “Puede tener varios” → máximo n; “no se registran clientes sin vehículo” → mínimo 1

Correspondencia 1:N (CLIENTE en el lado 1). Observa que la mínima 1 junto a VEHÍCULO obliga a dar de alta el cliente y su primer vehículo en la misma operación.

Ejercicio 3: Clasificar frases

Para cada frase, da la pareja junto a cada entidad y la correspondencia:

  1. “Cada aula se asigna a un grupo como máximo, y cada grupo tiene asignada exactamente un aula.”
  2. “Un actor puede participar en muchas películas; toda película tiene al menos un actor.”
  3. “Cada factura pertenece a un cliente; un cliente puede no tener facturas.”
  4. “Un médico puede tener asignada una consulta (despacho) o ninguna; una consulta puede estar vacía o asignada a un médico.”
  5. “Un socio puede pertenecer a varios clubes de lectura y un club tiene entre 5 y 20 socios.”
Ver solución
# Entidades Pareja junto a la 1.ª Pareja junto a la 2.ª Correspondencia
1 AULA – GRUPO (1,1) junto a AULA (aulas por grupo) (0,1) junto a GRUPO (grupos por aula) 1:1
2 ACTOR – PELÍCULA (1,n) junto a ACTOR (actores por película) (0,n) junto a PELÍCULA (películas por actor; el enunciado no exige que todo actor tenga película) N:M
3 CLIENTE – FACTURA (1,1) junto a CLIENTE (0,n) junto a FACTURA 1:N
4 MÉDICO – CONSULTA (0,1) junto a MÉDICO (0,1) junto a CONSULTA 1:1
5 SOCIO – CLUB (5,20) junto a SOCIO (socios por club) (0,n) junto a CLUB (clubes por socio; “puede pertenecer” indica mínimo 0) N:M

En la frase 2 la mínima junto a PELÍCULA no la fija el enunciado; (0,n) es la interpretación más prudente y conviene confirmarla con el cliente.

Ejercicio 4: De las ocurrencias a las cardinalidades

Se conocen estas ocurrencias de la relación ALUMNO pertenece a CLUB_DEPORTIVO de un instituto (alumnos: A1…A5; clubes: C1…C4):

Alumno Club
A1 C1
A1 C2
A2 C1
A3 C3
A5 C3

a) ¿Qué cardinalidades son compatibles con estos datos? b) ¿Puede deducirse de los datos que el máximo junto a ALUMNO es n?

Ver solución

Clubes por alumno: A1 → 2, A2 → 1, A3 → 1, A4 → 0, A5 → 1. Alumnos por club: C1 → 2, C2 → 1, C3 → 2, C4 → 0.

a) Junto a CLUB_DEPORTIVO: mínimo 0 (A4 no está en ninguno) y máximo al menos 2 (A1 está en dos) → (0,n). Junto a ALUMNO: mínimo 0 (C4 no tiene alumnos) y máximo al menos 2 → (0,n). Correspondencia N:M.

b) Los datos solo pueden refutar cardinalidades, nunca demostrarlas. Muestran que el máximo no es 1 (hay clubes con 2 alumnos), pero no si es 30 o ilimitado. Las cardinalidades se obtienen del significado (del enunciado o del cliente); los diagramas de ocurrencias sirven para comprobarlas y para encontrar contraejemplos.

Ejercicio 5: Límites concretos

“Una autoescuela tiene profesores y alumnos. Cada alumno tiene asignado un único profesor de prácticas, que puede cambiar. Cada profesor tiene asignados entre 0 y 12 alumnos. Los profesores en formación no pueden tener más de 4.” Dibuja el diagrama con las cardinalidades y las restricciones semánticas necesarias.

Ver solución
flowchart LR
    PROFESOR[PROFESOR] ---|"(1,1)"| tutela{"tiene asignado<br/>1:N"}
    tutela ---|"(0,12)"| ALUMNO[ALUMNO]
    PROFESOR --- pr_dni([<u>dni</u>])
    PROFESOR --- pr_form([en_formacion])
    ALUMNO --- al_dni([<u>dni</u>])
    ALUMNO --- al_nombre([nombre])
  • (1,1) junto a PROFESOR: cada alumno tiene exactamente un profesor de prácticas.
  • (0,12) junto a ALUMNO: cada profesor tiene entre 0 y 12 alumnos. Es una 1:N con máximo concreto.
  • RS1: Un profesor con en_formacion = sí no puede tener más de 4 alumnos asignados.

Que el profesor “pueda cambiar” no altera las cardinalidades: en cada instante es uno. Si hubiera que guardar el historial de profesores de cada alumno, se necesitaría una entidad ASIGNACIÓN con fechas.

Ejercicio 6: ¿Dónde va cada atributo?

En una plataforma de streaming, USUARIO (0,n) – ve – (0,n) SERIE. Decide dónde va cada atributo: fecha_alta, idioma_preferido, num_temporadas, anyo_estreno, ultimo_episodio_visto, valoracion (de 1 a 5 estrellas), idioma_audio_elegido, fecha_ultima_visualizacion.

Ver solución
Atributo Depende de Ubicación
fecha_alta El usuario USUARIO
idioma_preferido El usuario (su configuración general) USUARIO
num_temporadas La serie SERIE (o derivado si se registran temporadas)
anyo_estreno La serie SERIE
ultimo_episodio_visto El par usuario-serie Relación ve
valoracion El par usuario-serie Relación ve, opcional (0,1)
idioma_audio_elegido El par (cada usuario puede elegir un idioma distinto para cada serie) Relación ve
fecha_ultima_visualizacion El par usuario-serie Relación ve
flowchart LR
    USUARIO[USUARIO] ---|"(0,n)"| ve{"ve<br/>N:M"}
    ve ---|"(0,n)"| SERIE[SERIE]
    USUARIO --- u_id([<u>id_usuario</u>])
    USUARIO --- u_alta([fecha_alta])
    USUARIO --- u_idioma([idioma_preferido])
    SERIE --- s_id([<u>id_serie</u>])
    SERIE --- s_anyo([anyo_estreno])
    ve --- v_ult([ultimo_episodio_visto])
    ve --- v_val(["valoracion (0,1)"])
    ve --- v_aud([idioma_audio_elegido])
    ve --- v_fecha([fecha_ultima_visualizacion])

Como la relación es N:M, ninguno de los atributos del par puede migrar a una entidad. Aquí no hay problema de repetición: se guarda el estado actual de cada par, no cada sesión de visionado.

Ejercicio 7: Varias relaciones (vuelos)

“De cada vuelo se conoce el aeropuerto de origen y el de destino. Un aeropuerto puede ser origen y destino de muchos vuelos. Se registran aeropuertos que aún no tienen vuelos.” Modélalo y justifica la elección frente a una única relación.

Ver solución
flowchart LR
    VUELO[VUELO] ---|"(0,n)"| sale{"sale de<br/>N:1"}
    sale ---|"(1,1)"| AEROPUERTO[AEROPUERTO]
    VUELO ---|"(0,n)"| llega{"llega a<br/>N:1"}
    llega ---|"(1,1)"| AEROPUERTO
    VUELO --- vu_cod([<u>cod_vuelo</u>])
    VUELO --- vu_hora([hora_salida])
    AEROPUERTO --- ae_iata([<u>codigo_iata</u>])
    AEROPUERTO --- ae_ciudad([ciudad])
  • sale de: cada vuelo sale de exactamente 1 aeropuerto (1,1); de cada aeropuerto salen 0 o más vuelos (0,n).
  • llega a: igual, con el destino.
  • RS1: El aeropuerto de origen y el de destino de un vuelo deben ser distintos.

Son dos papeles distintos con un participante cada uno, así que dos relaciones 1:N son mejores que una relación (2,2) con un atributo papel: las cardinalidades garantizan que hay exactamente un origen y un destino, y cada relación se lee con naturalidad.

Ejercicio 8: Corregir un diseño

Un compañero ha entregado este diagrama para “Los empleados trabajan en proyectos, dedicando un número de horas a cada uno. Cada proyecto lo dirige un empleado.” Encuentra y corrige los errores.

flowchart LR
    EMPLEADO[EMPLEADO] ---|"(0,n)"| tiene{tiene}
    tiene ---|"(0,n)"| PROYECTO[PROYECTO]
    EMPLEADO --- e_id([<u>emp_id</u>])
    EMPLEADO --- e_horas([horas])
    PROYECTO --- y_id([<u>proyecto_id</u>])
    PROYECTO --- y_dir([emp_id_director])
Ver solución

Errores:

  1. Nombre vacío: tiene no dice nada. Se cambia por trabaja en.
  2. Atributo de N:M en una entidad: horas depende del par empleado-proyecto; debe estar en la relación.
  3. Atributo que referencia otra entidad: emp_id_director esconde la relación dirige. Se sustituye por una relación propia.
  4. Falta la relación dirige, con sus cardinalidades: cada proyecto lo dirige exactamente un empleado (1,1); un empleado dirige 0 o más proyectos (0,n).
flowchart LR
    EMPLEADO[EMPLEADO] ---|"(0,n)"| trabaja{"trabaja en<br/>N:M"}
    trabaja ---|"(0,n)"| PROYECTO[PROYECTO]
    EMPLEADO ---|"(1,1)"| dirige{"dirige<br/>1:N"}
    dirige ---|"(0,n)"| PROYECTO
    EMPLEADO --- e_id([<u>emp_id</u>])
    PROYECTO --- y_id([<u>proyecto_id</u>])
    trabaja --- t_horas([horas])

Restricción opcional a confirmar con el cliente: ¿el director debe trabajar también en el proyecto? Si es así, se anota como RS de inclusión.

Ejercicio 9: ¿Fusionar o no?

Decide para cada relación 1:1 si fusionarías las entidades: a) EMPLEADO (1,1) – tiene – (1,1) CUENTA_ACCESO (usuario y contraseña del sistema, creados con el contrato y borrados con la baja); b) SOCIO (0,1) – tiene alquilada – (0,1) TAQUILLA de un gimnasio; c) PAÍS (1,1) – tiene – (1,1) BANDERA (solo se guarda una imagen de la bandera).

Ver solución

a) Fusionar es razonable: mínimas 1 en ambos lados, mismo ciclo de vida, y la cuenta no tiene relaciones propias. Los atributos login y hash_clave pasan a EMPLEADO; login es identificador alternativo. Si la cuenta tuviera relaciones propias (roles, registros de acceso) o pudiera haber empleados sin cuenta, se mantendría separada.

b) Separadas: hay taquillas libres y socios sin taquilla (mínimas 0), y la asignación cambia con el tiempo. La taquilla es un objeto físico con identidad propia (número, vestuario).

c) Fusionar: la “bandera” se reduce a un atributo imagen_bandera de PAÍS. No tiene identidad ni atributos propios que gestionar en este universo del discurso.

Ejercicio 10: Repeticiones en el tiempo (taller)

“Un mecánico repara vehículos. De cada reparación se guarda la fecha de entrada, la fecha de salida, las horas de mano de obra y la descripción. Un vehículo puede ser reparado varias veces por el mismo mecánico.” Un alumno propone MECÁNICO (0,n) – repara – (0,n) VEHÍCULO con los cuatro atributos en la relación. ¿Es correcto? Si no lo es, corrígelo.

Ver solución

No es correcto. La relación es un conjunto de pares: el par (mecánico Juan, vehículo 1234-ABC) solo puede aparecer una vez, así que no se podría registrar una segunda reparación del mismo vehículo por el mismo mecánico. La reparación es un hecho que se repite y tiene identidad propia: se reifica.

flowchart LR
    MECANICO[MECÁNICO] ---|"(1,1)"| realiza{"realiza<br/>1:N"}
    realiza ---|"(0,n)"| REPARACION[REPARACIÓN]
    REPARACION ---|"(0,n)"| sobre{"se hace sobre<br/>N:1"}
    sobre ---|"(1,1)"| VEHICULO[VEHÍCULO]
    MECANICO --- me_dni([<u>dni</u>])
    VEHICULO --- ve_mat([<u>matricula</u>])
    REPARACION --- re_num([<u>num_orden</u>])
    REPARACION --- re_ent([fecha_entrada])
    REPARACION --- re_sal(["fecha_salida (0,1)"])
    REPARACION --- re_horas([horas])
    REPARACION --- re_desc([descripcion])
  • Cada reparación la realiza exactamente un mecánico (1,1); un mecánico realiza 0 o más reparaciones (0,n).
  • Cada reparación se hace sobre exactamente un vehículo (1,1); un vehículo tiene 0 o más reparaciones (0,n).
  • fecha_salida es opcional porque mientras el vehículo está en el taller aún no se conoce.

Si en una reparación pudieran intervenir varios mecánicos, la relación MECÁNICO – REPARACIÓN pasaría a N:M con el atributo horas en ella.

Ejercicio 11: Entidad o relación (gimnasio)

“Los socios se inscriben en actividades (pilates, spinning…). De cada inscripción se guarda la fecha y la cuota mensual pactada. Cada mes se genera un recibo de cada inscripción activa.” Modela la inscripción y justifica si es relación o entidad.

Ver solución

La inscripción debe relacionarse con los recibos, y en el E/R básico una relación no puede participar en otra relación. Además, un socio podría darse de baja y volver a inscribirse en la misma actividad. Ambas razones llevan a reificarla:

flowchart LR
    SOCIO[SOCIO] ---|"(1,1)"| solicita{"solicita<br/>1:N"}
    solicita ---|"(0,n)"| INSCRIPCION[INSCRIPCIÓN]
    INSCRIPCION ---|"(0,n)"| en{"en<br/>N:1"}
    en ---|"(1,1)"| ACTIVIDAD[ACTIVIDAD]
    INSCRIPCION ---|"(1,1)"| genera{"genera<br/>1:N"}
    genera ---|"(0,n)"| RECIBO[RECIBO]
    SOCIO --- so_num([<u>num_socio</u>])
    ACTIVIDAD --- ac_cod([<u>cod_actividad</u>])
    INSCRIPCION --- in_id([<u>id_inscripcion</u>])
    INSCRIPCION --- in_fecha([fecha_alta])
    INSCRIPCION --- in_baja(["fecha_baja (0,1)"])
    INSCRIPCION --- in_cuota([cuota_mensual])
    RECIBO --- rc_num([<u>num_recibo</u>])
    RECIBO --- rc_mes([mes])
    RECIBO --- rc_imp([importe])

Cada recibo es de exactamente una inscripción (1,1); una inscripción genera 0 o más recibos (0,n): 0 justo después del alta, antes del primer cargo. La cuota_mensual va en INSCRIPCIÓN y no en ACTIVIDAD porque es la pactada con ese socio (sección 6.5).

Ejercicio 12: Caso integrador (liga deportiva)

“Una federación organiza una liga. Cada equipo tiene un estadio propio (un estadio puede ser compartido por dos equipos de la misma ciudad como máximo) y una plantilla de entre 16 y 25 jugadores. Un jugador juega en un solo equipo; los jugadores sin equipo no se registran. Cada partido lo disputan un equipo local y uno visitante, se juega en un estadio (normalmente el del local, pero no siempre) y lo dirige un árbitro principal. Un árbitro dirige muchos partidos a lo largo de la liga. De cada jugador se registra en qué partidos ha sido convocado y los minutos que jugó.” Dibuja el diagrama solo con relaciones binarias y justifica cada cardinalidad.

Ver solución

Por claridad se divide en dos diagramas.

Equipos, estadios y jugadores:

flowchart LR
    ESTADIO[ESTADIO] ---|"(1,1)"| juega_en{"tiene como estadio<br/>1:N"}
    juega_en ---|"(1,2)"| EQUIPO[EQUIPO]
    EQUIPO ---|"(1,1)"| plantilla{"tiene en plantilla<br/>1:N"}
    plantilla ---|"(16,25)"| JUGADOR[JUGADOR]
    ESTADIO --- es_cod([<u>cod_estadio</u>])
    ESTADIO --- es_aforo([aforo])
    EQUIPO --- eq_cod([<u>cod_equipo</u>])
    JUGADOR --- ju_lic([<u>licencia</u>])
Pareja Justificación
(1,1) junto a ESTADIO Cada equipo tiene exactamente un estadio propio
(1,2) junto a EQUIPO Un estadio registrado es de al menos un equipo y como máximo de dos
(1,1) junto a EQUIPO (en plantilla) Un jugador juega en un solo equipo y no se registran jugadores sin equipo
(16,25) junto a JUGADOR Tamaño de la plantilla

Partidos:

flowchart LR
    EQUIPO[EQUIPO] ---|"(1,1)"| local{"juega como local<br/>1:N"}
    local ---|"(0,n)"| PARTIDO[PARTIDO]
    EQUIPO ---|"(1,1)"| visit{"juega como visitante<br/>1:N"}
    visit ---|"(0,n)"| PARTIDO
    ESTADIO[ESTADIO] ---|"(1,1)"| sede{"acoge<br/>1:N"}
    sede ---|"(0,n)"| PARTIDO
    ARBITRO[ÁRBITRO] ---|"(1,1)"| arbitra{"dirige<br/>1:N"}
    arbitra ---|"(0,n)"| PARTIDO
    JUGADOR[JUGADOR] ---|"(0,n)"| convocado{"es convocado para<br/>N:M"}
    convocado ---|"(0,n)"| PARTIDO
    convocado --- cv_min([minutos_jugados])
    PARTIDO --- pa_cod([<u>cod_partido</u>])
    PARTIDO --- pa_fecha([fecha_hora])
Relación Justificación
juega como local / visitante Dos papeles distintos: dos 1:N. Cada partido tiene exactamente un local y un visitante; un equipo juega 0 o más partidos en cada papel (0 antes de empezar la liga)
acoge Cada partido se juega en exactamente un estadio. Es una relación propia y no se deduce del local, porque “no siempre” es el del local: no es redundante
dirige Cada partido tiene exactamente un árbitro principal; un árbitro dirige 0 o más
es convocado para N:M: un jugador es convocado a muchos partidos y un partido tiene muchos convocados. minutos_jugados depende del par. No hay repetición en el tiempo: un jugador no puede ser convocado dos veces al mismo partido

Restricciones semánticas:

  • RS1: El equipo local y el visitante de un partido son distintos.
  • RS2: Un jugador solo puede ser convocado para partidos que dispute su equipo (como local o como visitante).
  • RS3: Un partido tiene como máximo un número de convocados por equipo fijado por el reglamento (por ejemplo, 18).

15. Ejercicios propuestos

Ejercicio propuesto 1: Lectura

Escribe las dos frases de lectura y la correspondencia de: OFICINA (1,1) – trabaja en – (1,n) COMERCIAL; CURSO (0,n) – imparte – (1,3) FORMADOR; PERSONA (0,1) – es titular de – (0,1) ABONO_TRANSPORTE.

Ejercicio propuesto 2: Agencia de viajes

“Cada reserva de viaje la hace un cliente y corresponde a un único paquete turístico. Un cliente puede hacer muchas reservas y un paquete puede reservarse muchas veces (o ninguna).” Modela RESERVA como entidad y justifica por qué no basta con una relación N:M entre CLIENTE y PAQUETE.

Ejercicio propuesto 3: Biblioteca con historial

Amplía el ejemplo de la sección 5.2 para guardar todos los préstamos (también los ya devueltos), con fecha de préstamo, fecha prevista y fecha real de devolución, manteniendo el límite de 3 préstamos vigentes por socio. ¿Qué restricción semántica necesitas ahora?

Ejercicio propuesto 4: Hotel

“Un cliente reserva habitaciones para unas fechas. Al llegar, ocupa una habitación (que puede ser distinta de la reservada). Una habitación aloja como máximo a 4 huéspedes a la vez.” Identifica cuántas relaciones (o entidades) hay entre CLIENTE y HABITACIÓN y dibuja el diagrama.

Ejercicio propuesto 5: Clasificación de las diez combinaciones

Inventa un ejemplo distinto de los del módulo para cada una de las diez combinaciones de la tabla de la sección 4.6 y dibuja su diagrama de ocurrencias con al menos cuatro ejemplares por entidad.

Ejercicio propuesto 6: Atributos de relación

En la relación ACTOR (1,n) – actúa en – (0,n) PELÍCULA, decide la ubicación de: nacionalidad, personaje, duracion, orden_en_creditos, cache, fecha_nacimiento, es_protagonista, anyo.

Ejercicio propuesto 7: Errores

Busca al menos cinco errores en este enunciado-diagrama y corrígelo: CLIENTE con atributos nif, nombre, cod_comercial; EMPLEADO con atributos emp_id, nombre, num_clientes; relación tiene entre CLIENTE (1,n) y EMPLEADO (1,1) para expresar que “cada cliente tiene asignado un comercial y un comercial puede tener muchos clientes”.

Ejercicio propuesto 8: Fusión

Decide razonadamente si fusionarías: ALUMNO – EXPEDIENTE_ACADEMICO (1,1)-(1,1); VEHÍCULO – TARJETA_ITV (1,1)-(1,1) donde la tarjeta se renueva con cada inspección; TRABAJADOR – PUESTO (0,1)-(0,1) en una fábrica con puestos vacantes.

Ejercicio propuesto 9: Instantánea e historia

Para PROFESOR – DEPARTAMENTO, dibuja tres versiones: a) solo el departamento actual; b) todos los departamentos en los que ha estado; c) todos los periodos con fechas, pudiendo volver a uno anterior. Explica cómo cambian las cardinalidades.

Ejercicio propuesto 10: Caso completo (red de bibliotecas municipales)

“Una ciudad tiene varias bibliotecas. Cada ejemplar pertenece a una biblioteca, pero puede estar temporalmente cedido a otra. Los socios se registran en una biblioteca, aunque pueden sacar libros de cualquiera. Cada biblioteca tiene un director, que es un empleado de esa biblioteca. Un libro (obra) tiene uno o varios autores y varios ejemplares.” Construye el diagrama E/R solo con relaciones binarias, justifica todas las cardinalidades y enumera las restricciones semánticas.


Resumen

Concepto Idea clave
Relación binaria Subconjunto de E₁ × E₂; cada ocurrencia es un par que no se repite
Convención del curso La pareja junto a A dice con cuántos A se relaciona una ocurrencia de la otra entidad
Lectura Desde X, cruza el rombo y lee la pareja del otro extremo; una frase en cada sentido
Tipo de correspondencia Lo deciden solo los máximos: 1:1, 1:N, N:M
Mínimas Deciden la obligatoriedad (participación total o parcial); deben cumplirse siempre
Diez combinaciones 3 de 1:1, 4 de 1:N y 3 de N:M
Diagrama de ocurrencias Ejemplares unidos por líneas; sirve para validar y buscar contraejemplos
Cardinalidades concretas (0,3), (2,5), (3,3)…; cuentan como “N” si máx > 1; se controlan con restricciones
Límites variables Pareja general + restricción semántica (RS) anotada
Atributo de relación Depende del par; en N:M se queda en la relación; en 1:N puede migrar al lado N; en 1:1 a cualquier lado
Atributos de la ocurrencia Precio de venta frente a precio actual: se copia en la relación
Repeticiones en el tiempo Una N:M no puede repetir un par: reificar en entidad (o tiempo en el identificador)
Varias relaciones Una por significado, con sus propias cardinalidades; papeles distintos → relaciones distintas
Atributo que referencia Error: en el E/R no hay claves ajenas; se dibuja la relación
1:1 o fusión Fusionar si (1,1)-(1,1), mismo ciclo de vida y misma identidad
Reificación Convertir una relación en entidad si se repite, tiene identificador, muchos atributos o se relaciona con otras
Paso a relacional 1:N → FK en el lado N; N:M → tabla nueva; 1:1 → FK UNIQUE o fusión