Módulo 14: Entidades débiles

Objetivos del módulo

  • Definir con precisión qué es una entidad débil y qué es su entidad propietaria
  • Distinguir la dependencia en existencia de la dependencia en identificación, con ejemplos y contraejemplos
  • Diferenciar ambas de la simple participación obligatoria (cardinalidad mínima 1)
  • Usar correctamente el identificador parcial (discriminador) y la relación de identificación
  • Representar las entidades débiles en la notación del curso y reconocerlas en otras notaciones
  • Modelar cadenas de entidades débiles y entidades débiles con varias propietarias
  • Decidir con criterio cuándo modelar algo como débil y cuándo como fuerte con identificador propio
  • Relacionar las entidades débiles con los atributos multivaluados y con las claves primarias compuestas del modelo relacional
  • Analizar a fondo el caso LINEAS_PEDIDO del esquema EMPRESA

1. El problema: objetos que no se identifican solos

Piensa en una cadena hotelera con varios hoteles. Cada hotel numera sus habitaciones a su manera: 101, 102, 201… Si alguien te dice “la habitación 101”, no sabes de qué habitación habla: hay una habitación 101 en el hotel de Valencia, otra en el de Sevilla y otra en el de Bilbao. Para identificar una habitación necesitas dos datos: el hotel y el número.

flowchart LR
    subgraph SH["HOTEL"]
        h1["VLC Hotel Turia"]
        h2["SVQ Hotel Giralda"]
    end
    subgraph SHAB["HABITACION"]
        hab1["101"]
        hab2["102"]
        hab3["201"]
        hab4["101 "]
        hab5["102 "]
    end
    h1 --- hab1
    h1 --- hab2
    h1 --- hab3
    h2 --- hab4
    h2 --- hab5

Hay dos ocurrencias de HABITACION con número 101 y dos con número 102: el número no identifica por sí solo. Además, una habitación no tiene sentido sin su hotel: si el hotel de Sevilla se vende y sale del sistema, sus habitaciones desaparecen con él. Este tipo de entidades, que dependen de otra para existir y, a menudo, para identificarse, son las entidades débiles.


2. Definición de entidad débil

2.1 Definición

📘 Concepto: Una entidad débil (weak entity) es una entidad cuyas ocurrencias dependen de la existencia de ocurrencias de otra entidad, llamada entidad propietaria (owner, también fuerte, dominante o identificadora). En su forma más habitual, la entidad débil no tiene atributos suficientes para formar un identificador propio: sus ocurrencias solo se pueden identificar combinando el identificador de la propietaria con uno o varios atributos propios, llamados identificador parcial o discriminador.

La definición recoge las dos formas de “debilidad” que distinguen los autores:

  • En la tradición anglosajona (Chen, Elmasri y Navathe, Silberschatz), una entidad débil es, por definición, la que no tiene clave propia y se identifica a través de su propietaria. Es la dependencia en identificación.
  • En la tradición española (de Miguel, Piattini), se distingue además una forma más suave, la dependencia en existencia: la entidad tiene identificador propio, pero sus ocurrencias no pueden existir sin la propietaria.

En este curso usaremos los dos conceptos, porque ayudan a razonar, pero verás que el caso importante (y el que se transforma de forma especial en el modelo relacional) es la dependencia en identificación.

2.2 Terminología

Término Sinónimos Significado En el ejemplo
Entidad débil Dependiente, subordinada La que depende HABITACION
Entidad propietaria Fuerte, dominante, identificadora, owner De la que depende la débil HOTEL
Relación de identificación Relación débil, identifying relationship La relación que une la débil con su propietaria tiene
Identificador parcial Discriminador, clave parcial, partial key Atributo(s) de la débil que distinguen las ocurrencias de una misma propietaria numero
Identificador completo — Identificador de la propietaria + identificador parcial (codigo_hotel, numero)

3. Dependencia en existencia y dependencia en identificación

3.1 Dependencia en existencia

📘 Concepto: Una entidad A tiene dependencia en existencia (E) respecto de una entidad B cuando las ocurrencias de A no pueden existir si no existe la ocurrencia de B con la que están relacionadas, y desaparecen cuando esta desaparece. Sin embargo, A tiene identificador propio: sus ocurrencias se distinguen sin necesidad de conocer B.

Ejemplo: una biblioteca registra los ejemplares de cada libro, y cada ejemplar lleva una etiqueta con un código de barras único en toda la biblioteca (por ejemplo, B0004521). Un ejemplar no tiene sentido sin su libro (si se da de baja la obra del catálogo, se dan de baja sus ejemplares), pero el ejemplar B0004521 se identifica perfectamente sin saber de qué libro es.

flowchart LR
    classDef debil stroke-width:4px
    LIBRO[LIBRO] ---|"(1,1)"| tiene{"tiene<br/>E"}:::debil
    tiene ---|"(1,n)"| EJEMPLAR[EJEMPLAR]:::debil
    LIBRO --- l_isbn([<u>signatura</u>])
    LIBRO --- l_tit([titulo])
    EJEMPLAR --- e_cod([<u>codigo_barras</u>])
    EJEMPLAR --- e_est([estado])
    EJEMPLAR --- e_fa([fecha_adquisicion])

Observa que codigo_barras está subrayado como identificador completo (no parcial), y que en el rombo hemos indicado E (existencia).

3.2 Dependencia en identificación

📘 Concepto: Una entidad A tiene dependencia en identificación (ID) respecto de una entidad B cuando, además de depender en existencia, las ocurrencias de A no pueden identificarse por sus propios atributos: se necesita el identificador de la ocurrencia de B a la que pertenecen.

Ejemplo: otra biblioteca no etiqueta los ejemplares con un código global, sino que los numera dentro de cada libro: ejemplar 1, ejemplar 2, ejemplar 3 de “La Regenta”; ejemplar 1, ejemplar 2 de “Fortunata y Jacinta”. El “ejemplar 2” no identifica nada si no se dice de qué libro.

flowchart LR
    classDef debil stroke-width:4px
    LIBRO[LIBRO] ---|"(1,1)"| tiene{"tiene<br/>ID"}:::debil
    tiene ---|"(1,n)"| EJEMPLAR[EJEMPLAR]:::debil
    LIBRO --- l_sig([<u>signatura</u>])
    LIBRO --- l_tit([titulo])
    EJEMPLAR --- e_num(["<u>num_ejemplar</u> parcial"])
    EJEMPLAR --- e_est([estado])
    EJEMPLAR --- e_fa([fecha_adquisicion])

Ahora num_ejemplar es un identificador parcial: el identificador completo de un ejemplar es (signatura, num_ejemplar).

⚠️ Importante: Toda dependencia en identificación implica dependencia en existencia (si no puedo identificar un ejemplar sin su libro, el ejemplar no puede existir sin el libro). Lo contrario no es cierto: el ejemplar con código de barras global depende en existencia, pero no en identificación. Como acabas de ver, la misma realidad (los ejemplares de una biblioteca) puede dar lugar a uno u otro caso según cómo se identifiquen las cosas en el negocio.

3.3 Participación obligatoria no es lo mismo que debilidad

Este es el punto que más confusión genera. Fíjate en estos tres niveles, de más débil a más fuerte:

flowchart TB
    subgraph N1["Participación obligatoria: mínima 1 (módulo 06)"]
        pe1["PEDIDO respecto de CLIENTE"]
        pe2["EMPLEADO respecto de DEPARTAMENTO<br/>(si fuera obligatorio)"]
        subgraph N2["Dependencia en existencia (E)"]
            ex1["EJEMPLAR con código de barras global"]
            subgraph N3["Dependencia en identificación (ID)"]
                id1["HABITACION de HOTEL"]
                id2["LINEA_PEDIDO de PEDIDO"]
                id3["PLAZO de PRESTAMO"]
            end
        end
    end
  1. Participación obligatoria (mínima 1 junto a B): toda ocurrencia de A está relacionada con alguna de B. Es una restricción de cardinalidad. En EMPRESA, todo pedido tiene un cliente.
  2. Dependencia en existencia: además, la ocurrencia de A no tiene sentido sin su B concreta: forma parte de ella, desaparece con ella y no puede cambiar de propietaria.
  3. Dependencia en identificación: además, A necesita el identificador de B para identificarse.

¿Por qué un PEDIDO, que siempre tiene cliente, no es una entidad débil de CLIENTE?

  • Tiene identidad propia: el pedido 5001 es el pedido 5001, se sepa o no de qué cliente es.
  • Tiene sentido por sí mismo: es un documento comercial y contable que la empresa debe conservar aunque el cliente se dé de baja.
  • Al borrar un cliente, lo razonable no es borrar sus pedidos, sino impedir el borrado (o anonimizar el cliente). De hecho, en EMPRESA la clave ajena de pedidos a clientes no tiene ON DELETE CASCADE.
  • Un pedido podría, en algún caso (por un error de grabación), reasignarse a otro cliente. Una habitación no puede “cambiarse” de hotel: sería otra habitación.

💡 Consejo: Tres preguntas para detectar una dependencia en existencia: (1) si borro la propietaria, ¿tiene sentido conservar la ocurrencia dependiente? (2) ¿puede la dependiente “cambiar” de propietaria sin dejar de ser ella misma? (3) ¿la dependiente es una parte o un detalle de la propietaria, más que un objeto con vida propia? Si las respuestas son “no”, “no” y “sí”, hay dependencia en existencia.

3.4 Ejemplos y contraejemplos

Entidad Propietaria ¿Débil? Tipo Razonamiento
LINEA_PEDIDO PEDIDO Sí ID La línea 2 solo existe dentro de su pedido; se numera dentro de él; se borra con él
HABITACION HOTEL Sí ID La 101 se repite en cada hotel; no tiene sentido sin el hotel
PLAZO PRESTAMO (bancario) Sí ID El plazo 7 de un préstamo hipotecario: los plazos se numeran 1, 2, 3… dentro de cada préstamo
FAMILIAR EMPLEADO Sí ID Los familiares (a efectos de seguro médico o ayudas) se registran por su nombre dentro de cada empleado; si el empleado se va, sus familiares salen del sistema
EJEMPLAR (numerado por libro) LIBRO Sí ID Ejemplar 1, 2, 3 de cada libro
EJEMPLAR (código de barras global) LIBRO Sí E Depende del libro pero se identifica solo
TEMPORADA / EPISODIO SERIE / TEMPORADA Sí ID Temporada 2 de una serie; episodio 5 de una temporada
PEDIDO CLIENTE No — Participación obligatoria, pero identidad y sentido propios
EMPLEADO DEPARTAMENTO No — Puede cambiar de departamento, existe sin él (empleado 160 de EMPRESA)
FACTURA REPARACION No (normalmente) — Tiene número propio y valor legal; nunca se borra al borrar la reparación
ASIGNATURA TITULACION No (normalmente) — Tiene código propio y puede compartirse entre titulaciones
PROYECTO DEPARTAMENTO No — En EMPRESA tiene identificador y nombre únicos propios, y su departamento es opcional

⚠️ Importante: Que en la tabla aparezcan dos versiones de EJEMPLAR no es una contradicción: la debilidad depende de los requisitos, no del nombre de la entidad. El mismo concepto puede ser débil en un sistema y fuerte en otro.

3.5 Cómo decidirlo: árbol de decisión

flowchart TB
    q1{"¿La ocurrencia tiene sentido<br/>sin la otra entidad?"}
    q1 -->|"Sí"| f1["Entidad FUERTE<br/>(quizá con participación obligatoria)"]
    q1 -->|"No"| q2{"¿Puede cambiar de<br/>propietaria sin dejar<br/>de ser la misma?"}
    q2 -->|"Sí"| f1
    q2 -->|"No"| q3{"¿Se identifica con<br/>sus propios atributos?"}
    q3 -->|"Sí"| e1["Débil por EXISTENCIA (E)"]
    q3 -->|"No"| i1["Débil por IDENTIFICACIÓN (ID)"]

4. El identificador parcial (discriminador)

📘 Concepto: El identificador parcial o discriminador de una entidad débil por identificación es el atributo (o conjunto de atributos) que distingue entre sí las ocurrencias de la débil que pertenecen a la misma ocurrencia de la propietaria. El identificador completo de la entidad débil es la combinación del identificador de la propietaria y el identificador parcial.

Entidad débil Identificador parcial Identificador completo Ejemplo
HABITACION numero (codigo_hotel, numero) (VLC, 101)
LINEA_PEDIDO num_linea (pedido_id, num_linea) (5001, 2)
PLAZO num_plazo (num_prestamo, num_plazo) (H-2024-0087, 7)
FAMILIAR nombre (codigo_empleado, nombre) (120, “Lucía”)
TEMPORADA num_temporada (codigo_serie, num_temporada) (S0042, 2)

El identificador parcial suele ser de uno de estos dos tipos:

  • Un número secuencial dentro de la propietaria: línea 1, 2, 3…; plazo 1, 2, 3…; temporada 1, 2… Es lo más habitual y lo más robusto.
  • Un atributo natural que es único dentro de la propietaria, pero no en general: el nombre de un familiar (dos empleados distintos pueden tener un hijo llamado “Pablo”, pero un mismo empleado no tendrá dos hijos con el mismo nombre… ¿seguro? Ver ejercicio 5).

Veamos un ejemplar (un estado) de LINEA_PEDIDO con datos reales del esquema EMPRESA:

pedido_id (de la propietaria) num_linea (parcial) producto cantidad precio_unitario descuento
5001 1 2 (Portátil Gaming 16) 1 1499.00 0
5001 2 6 (Ratón inalámbrico) 2 19.90 0
5001 3 9 (Monitor 24 FHD) 2 139.00 5
5002 1 4 (Torre Oficina i5) 10 649.00 10
5002 2 9 (Monitor 24 FHD) 10 139.00 10
5002 3 8 (Pack teclado y ratón) 10 34.50 10

El valor 1 de num_linea aparece en los dos pedidos: por sí solo no identifica. La pareja (pedido_id, num_linea) sí.

⚠️ Importante: En el diagrama E/R, el identificador de la propietaria no se dibuja como atributo de la entidad débil. LINEA_PEDIDO no tiene un atributo pedido_id: la pertenencia al pedido la expresa la relación de identificación. El identificador completo se “hereda” a través de esa relación, y solo aparecerá como columna (clave ajena) al pasar al modelo relacional. Dibujar pedido_id como atributo de LINEA_PEDIDO es el mismo error que dibujar una clave ajena como atributo (módulo 05).


5. La relación de identificación

5.1 Propiedades

📘 Concepto: La relación de identificación (o relación débil) es la relación que une una entidad débil con su propietaria y a través de la cual la débil obtiene la dependencia (y, en su caso, el identificador).

Sus propiedades características son:

  1. Junto a la propietaria, la cardinalidad es siempre (1,1): cada ocurrencia de la débil pertenece a exactamente una ocurrencia de la propietaria.
    • El mínimo es 1 porque no puede existir sin ella (dependencia en existencia).
    • El máximo es 1 porque, si una habitación perteneciera a dos hoteles, no sabríamos qué código de hotel usar para identificarla.
  2. Junto a la débil, la cardinalidad suele ser (1,n) o (0,n): una propietaria tiene una o varias débiles (un pedido tiene al menos una línea) o puede no tener ninguna (un hotel recién registrado del que aún no se han cargado las habitaciones). También puede ser un número concreto: un préstamo a 240 meses tiene (240,240) plazos.
  3. La participación de la débil es total y no puede cambiar de propietaria: la línea 2 del pedido 5001 no puede “pasar” al pedido 5002; si se quisiera, se borraría y se crearía otra línea en el pedido 5002.
  4. Normalmente es binaria y de tipo 1:N. Puede ser 1:1 (una entidad débil con una única ocurrencia por propietaria, por ejemplo, la FICHA_MEDICA de un DEPORTISTA), aunque en ese caso conviene preguntarse si no basta con poner sus atributos en la propietaria.
  5. La relación de identificación no suele tener atributos propios: como es 1:N y la débil está en el lado N, cualquier atributo se coloca directamente en la débil.

5.2 La relación de identificación frente a las demás relaciones de la débil

Una entidad débil puede participar en otras relaciones normales además de la de identificación. LINEA_PEDIDO se relaciona con PRODUCTO (cada línea es de un producto), pero esa relación no la identifica: el producto de una línea se podría corregir si se grabó mal, y la línea seguiría siendo la misma línea 2 del pedido 5001.

flowchart LR
    classDef debil stroke-width:4px
    PEDIDO[PEDIDO] ---|"(1,1)"| contiene{"contiene<br/>ID"}:::debil
    contiene ---|"(1,n)"| LINEA_PEDIDO[LINEA_PEDIDO]:::debil
    LINEA_PEDIDO ---|"(1,1)"| de_producto{"de_producto<br/>1:N"}
    de_producto ---|"(0,n)"| PRODUCTO[PRODUCTO]
    LINEA_PEDIDO --- l_num(["<u>num_linea</u> parcial"])
    LINEA_PEDIDO --- l_cant([cantidad])

Léelo con la convención del curso: “un pedido contiene de 1 a n líneas”; “una línea pertenece a exactamente un pedido”; “una línea es de exactamente un producto”; “un producto aparece en 0 a n líneas” (el producto 14 de EMPRESA no se ha vendido nunca).


6. Representación

6.1 En la notación del curso

Elemento Representación Mermaid
Entidad débil Rectángulo de borde grueso (equivale al doble rectángulo) X[NOMBRE]:::debil
Relación de identificación Rombo de borde grueso (equivale al doble rombo) r{verbo}:::debil
Tipo de dependencia (opcional) E (existencia) o ID (identificación) dentro del rombo, como en los libros de de Miguel y Piattini r{"verbo<br/>ID"}:::debil
Identificador parcial Subrayado, seguido de la palabra parcial a(["<u>numero</u> parcial"])
Identificador completo de una débil por existencia Subrayado normal a([<u>codigo</u>])
Cardinalidad junto a la propietaria Siempre (1,1) ---\|"(1,1)"\|

Recuerda declarar al principio de cada diagrama Mermaid la clase debil:

flowchart LR
    classDef debil stroke-width:4px
    HOTEL[HOTEL] ---|"(1,1)"| tiene{"tiene<br/>ID"}:::debil
    tiene ---|"(0,n)"| HABITACION[HABITACION]:::debil
    HOTEL --- h_cod([<u>codigo</u>])
    HOTEL --- h_nom([nombre])
    HOTEL --- h_ciu([ciudad])
    HABITACION --- hab_num(["<u>numero</u> parcial"])
    HABITACION --- hab_tipo([tipo])
    HABITACION --- hab_pre([precio_noche])

💡 Consejo: Algunos diseñadores solo marcan como débiles (borde grueso) las entidades con dependencia en identificación, y tratan la dependencia en existencia como una simple participación obligatoria anotada en el texto. Es una simplificación aceptable, porque en el modelo relacional la dependencia en existencia se traduce igual que una relación 1:N normal (con una clave ajena NOT NULL y, si procede, ON DELETE CASCADE). Lo que no es aceptable es marcar como débil una entidad que solo tiene participación obligatoria, como PEDIDO.

6.2 En otras notaciones

Notación Entidad débil Relación de identificación Identificador parcial
Chen / Elmasri y Navathe Doble rectángulo Doble rombo; participación total con doble línea Subrayado discontinuo
Chen extendida (curso) Borde grueso (doble) Rombo de borde grueso, con E o ID Subrayado + parcial
Pata de gallo (Mermaid erDiagram) Entidad normal Línea continua (--) = identificadora; discontinua (..) = no identificadora La PK de la débil incluye la FK de la propietaria
IDEF1X Caja con esquinas redondeadas (entidad dependiente) Línea continua (identificadora); discontinua (no identificadora) Claves sobre la línea, con (FK)
Barker Entidad normal Barra perpendicular a la línea junto a la débil (la relación forma parte de su UID) # en el atributo propio
UML Clase normal Composición (rombo relleno en el lado del “todo”) Restricción o calificador

El mismo fragmento PEDIDO–LINEA_PEDIDO–PRODUCTO en pata de gallo. Fíjate en que la relación con PEDIDO es identificadora (línea continua) y la relación con PRODUCTO no (línea discontinua):

erDiagram
    PEDIDO ||--|{ LINEA_PEDIDO : "contiene"
    PRODUCTO ||..o{ LINEA_PEDIDO : "aparece en"
    PEDIDO {
        int pedido_id PK
        date fecha_pedido
    }
    LINEA_PEDIDO {
        int pedido_id PK, FK
        int num_linea PK
        int producto_id FK
        int cantidad
        decimal precio_unitario
        decimal descuento
    }
    PRODUCTO {
        int producto_id PK
        string nombre
        decimal precio
    }

Y en UML, la composición expresa exactamente la idea de “parte que no existe sin el todo y se destruye con él”:

classDiagram
    class Pedido {
        +pedidoId : Integer
        +fechaPedido : Date
    }
    class LineaPedido {
        +numLinea : Integer
        +cantidad : Integer
        +precioUnitario : Decimal
        +descuento : Decimal
    }
    class Producto {
        +productoId : Integer
        +nombre : String
    }
    Pedido "1" *-- "1..*" LineaPedido : contiene
    LineaPedido "0..*" --> "1" Producto : de

7. Cadenas de entidades débiles

7.1 Débiles de débiles

Una entidad débil puede ser, a su vez, propietaria de otra entidad débil. Se forma así una cadena de dependencias, y el identificador se va acumulando a lo largo de ella.

Ejemplo: una plataforma de streaming organiza el contenido en series, temporadas y episodios. Las temporadas se numeran dentro de cada serie (temporada 1, 2, 3…) y los episodios dentro de cada temporada (episodio 1, 2, 3…).

flowchart LR
    classDef debil stroke-width:4px
    SERIE[SERIE] ---|"(1,1)"| tiene_t{"tiene<br/>ID"}:::debil
    tiene_t ---|"(1,n)"| TEMPORADA[TEMPORADA]:::debil
    TEMPORADA ---|"(1,1)"| tiene_e{"tiene<br/>ID"}:::debil
    tiene_e ---|"(1,n)"| EPISODIO[EPISODIO]:::debil
    SERIE --- s_cod([<u>codigo</u>])
    SERIE --- s_tit([titulo])
    TEMPORADA --- t_num(["<u>num_temporada</u> parcial"])
    TEMPORADA --- t_anio([anio_estreno])
    EPISODIO --- e_num(["<u>num_episodio</u> parcial"])
    EPISODIO --- e_tit([titulo])
    EPISODIO --- e_dur([duracion])
Entidad Identificador parcial Identificador completo
SERIE — (codigo)
TEMPORADA num_temporada (codigo, num_temporada)
EPISODIO num_episodio (codigo, num_temporada, num_episodio)

El episodio “S0042, temporada 2, episodio 5” se identifica con tres valores. Es exactamente como lo dicen los usuarios (“el quinto episodio de la segunda temporada”), lo cual es una buena señal de que el modelo es natural.

7.2 Consecuencias de las cadenas largas

  • El identificador completo crece con cada nivel. Con cuatro o cinco niveles, las claves primarias compuestas del modelo relacional se vuelven incómodas y se propagan a todas las tablas que referencien al último nivel.
  • Si otra entidad se relaciona con EPISODIO (por ejemplo, VISUALIZACION: qué perfil ha visto qué episodio), su clave ajena tendrá tres columnas.
  • Por eso, a partir de dos o tres niveles, muchos diseñadores dan a la entidad del último nivel un identificador propio (un código de episodio) y la tratan como débil solo por existencia, o directamente como fuerte. Lo veremos en la sección 9.

✏️ Ejercicio: Un campus universitario tiene edificios (código A, B, C…), cada edificio tiene plantas (0, 1, 2…) y cada planta tiene despachos numerados (1, 2, 3…). Dibuja la cadena y escribe el identificador completo de un despacho. ¿Cuántos atributos tiene? (Solución: EDIFICIO → PLANTA → DESPACHO, con identificador (codigo_edificio, num_planta, num_despacho).)


8. Entidades débiles con varias propietarias

8.1 El caso

A veces una ocurrencia necesita los identificadores de dos (o más) entidades para identificarse. Pensemos en las convocatorias de examen: un alumno puede presentarse varias veces al examen de una misma asignatura (convocatoria 1, 2, 3…), y de cada intento interesa la fecha y la nota.

Recuerda la trampa del módulo 06: si modelamos esto como una relación N:M entre ALUMNO y ASIGNATURA con los atributos fecha y nota, solo hay una ocurrencia por cada pareja (alumno, asignatura), y por tanto solo cabe una nota. Los intentos anteriores se pierden.

La solución es una entidad débil EXAMEN que depende a la vez de ALUMNO y de ASIGNATURA, con el discriminador num_convocatoria:

flowchart LR
    classDef debil stroke-width:4px
    ALUMNO[ALUMNO] ---|"(1,1)"| realiza{"realiza<br/>ID"}:::debil
    realiza ---|"(0,n)"| EXAMEN[EXAMEN]:::debil
    ASIGNATURA[ASIGNATURA] ---|"(1,1)"| evalua{"evalua<br/>ID"}:::debil
    evalua ---|"(0,n)"| EXAMEN
    ALUMNO --- a_nia([<u>nia</u>])
    ASIGNATURA --- s_cod([<u>codigo</u>])
    EXAMEN --- ex_conv(["<u>num_convocatoria</u> parcial"])
    EXAMEN --- ex_fecha([fecha])
    EXAMEN --- ex_nota([nota])

El identificador completo de un examen es (nia, codigo, num_convocatoria): “la tercera convocatoria del alumno 1002 en Bases de Datos”.

nia codigo_asignatura num_convocatoria fecha nota
1002 BD 1 15/01/2026 3.5
1002 BD 2 20/06/2026 6.0
1002 PROG 1 18/01/2026 7.25
1003 BD 1 15/01/2026 8.0

8.2 Entidad débil con varias propietarias o relación ternaria

Otra forma de resolver el mismo problema es una relación ternaria entre ALUMNO, ASIGNATURA y una entidad CONVOCATORIA (o FECHA). Ambas soluciones son equivalentes en información, y el módulo de relaciones ternarias las compara. En general:

  • La entidad débil con varias propietarias es más natural cuando el “intento” o la “vez” tiene atributos propios y, sobre todo, cuando participa en otras relaciones (por ejemplo, un EXAMEN es corregido por un PROFESOR, o tiene una REVISION).
  • La ternaria es más natural cuando la tercera entidad tiene sentido propio en el sistema (las convocatorias oficiales con su calendario, por ejemplo).

⚠️ Importante: Una entidad débil con varias propietarias necesita una relación de identificación con cada propietaria, y en todas ellas la cardinalidad junto a la propietaria es (1,1). Algunas notaciones lo dibujan como una única relación de identificación ternaria; en el curso usaremos relaciones binarias separadas, que son más fáciles de leer.


9. ¿Débil o fuerte con identificador propio?

9.1 El dilema

Casi cualquier entidad débil por identificación puede convertirse en fuerte dándole un identificador propio: un código de línea global, un número de habitación único en toda la cadena, un identificador de episodio. Y al revés: muchas entidades fuertes podrían modelarse como débiles. ¿Cuál es mejor?

9.2 Criterios

Criterio Favorece modelarla como débil Favorece darle identificador propio
Cómo la identifica el negocio “La línea 2 del pedido 5001”, “la habitación 101 del hotel de Valencia” El negocio ya le asigna un código global (código de barras, número de factura)
Vida propia Es una parte o detalle de la propietaria Tiene sentido por sí misma
Cambio de propietaria Nunca cambia Puede cambiar (se traslada, se reasigna)
Relaciones con otras entidades Pocas o ninguna aparte de la de identificación Muchas entidades la referencian
Longitud de la cadena Uno o dos niveles Tres o más niveles
Borrado de la propietaria Debe borrar también las dependientes Hay que conservarlas
Número de propietarias Una Varias propietarias y muchas relaciones (identificador muy largo)

9.3 Ventajas e inconvenientes

Modelar como débil (dependencia en identificación):

  • Ventaja: refleja fielmente cómo se piensa en el negocio (“línea 2 del pedido 5001”).
  • Ventaja: garantiza por diseño que no hay dos líneas con el mismo número en un pedido.
  • Ventaja: en el modelo relacional, la clave primaria compuesta incluye la clave ajena, lo que hace imposible “mover” una línea a otro pedido sin cambiar su identidad, y el borrado en cascada encaja de forma natural.
  • Inconveniente: las claves compuestas se propagan a todas las tablas que referencian a la débil.
  • Inconveniente: las cadenas largas producen claves muy largas.

Modelar como fuerte con identificador propio (subrogado):

  • Ventaja: claves cortas y estables, fáciles de referenciar desde otras tablas.
  • Ventaja: es lo que prefieren muchos frameworks y ORM, que trabajan mejor con una única columna de identificador.
  • Inconveniente: hay que añadir restricciones explícitas para conservar la semántica: por ejemplo, UNIQUE (pedido_id, num_linea) para que no se repita el número de línea en un pedido.
  • Inconveniente: el diagrama oculta que la entidad es una parte de otra, salvo que se marque la dependencia en existencia (E).

💡 Consejo: Una regla práctica razonable: en el diseño conceptual, modela como débil todo lo que el negocio identifica “dentro de” otra cosa; es la representación más fiel. En el diseño lógico y físico, si la cadena es larga o la entidad se referencia mucho, valora sustituir la clave compuesta por una subrogada manteniendo la clave compuesta como UNIQUE. Así no pierdes ninguna restricción.


10. Atributos multivaluados frente a entidades débiles

10.1 Son “casi lo mismo”

Un atributo multivaluado y una entidad débil tienen mucho en común: ambos representan varios valores que pertenecen a una ocurrencia y que no tienen sentido sin ella. De hecho, al pasar al modelo relacional los dos se transforman igual: en una tabla aparte cuya clave primaria incluye la clave de la entidad “dueña” (módulo 17).

flowchart LR
    CLIENTE[CLIENTE] --- c_dni([<u>dni</u>])
    CLIENTE --- c_nom([nombre])
    CLIENTE --- c_tel(((telefono)))
flowchart LR
    classDef debil stroke-width:4px
    CLIENTE[CLIENTE] ---|"(1,1)"| tiene{"tiene<br/>ID"}:::debil
    tiene ---|"(0,n)"| TELEFONO[TELEFONO]:::debil
    CLIENTE --- c_dni([<u>dni</u>])
    CLIENTE --- c_nom([nombre])
    TELEFONO --- t_num(["<u>numero</u> parcial"])
    TELEFONO --- t_tipo([tipo])
    TELEFONO --- t_hor(["horario_contacto (0,1)"])

10.2 Cuándo pasar de multivaluado a entidad débil

Usa un atributo multivaluado cuando los valores son simples y no interesa nada más de ellos (los idiomas que habla un guía, las alergias de un paciente si solo son texto).

Convierte el multivaluado en una entidad débil cuando:

  • Cada valor tiene atributos propios: el teléfono tiene tipo (fijo, móvil, trabajo), extensión, horario de contacto, si es el preferido…
  • El multivaluado es compuesto: las direcciones de envío de un cliente, cada una con calle, cp, localidad y nombre del destinatario. Un multivaluado compuesto es una entidad débil disfrazada.
  • Los valores participan en relaciones: un pedido se envía a una de las direcciones del cliente (relación PEDIDO–DIRECCION_ENVIO).
  • Hay que identificar cada valor para referirse a él.

Y conviértelo en una entidad fuerte (con su propia relación) si los valores forman un catálogo compartido entre ocurrencias: si las alergias se eligen de una lista de sustancias con su código, lo correcto es una entidad SUSTANCIA y una relación N:M con PACIENTE.

Situación Modelo recomendado
Varios valores simples, sin más información Atributo multivaluado
Varios valores con estructura o atributos propios Entidad débil
Varios valores que se relacionan con otras entidades Entidad débil (o fuerte)
Varios valores elegidos de un catálogo compartido Entidad fuerte + relación N:M

11. Adelanto: entidades débiles y claves compuestas en el modelo relacional

Aunque la transformación al modelo relacional se estudia en el módulo 17, conviene ver ya cómo se traduce una entidad débil, porque explica muchas tablas que verás en el bloque de SQL.

Regla: una entidad débil por identificación se transforma en una tabla cuya clave primaria está formada por la clave primaria de la propietaria (que es, a la vez, clave ajena hacia ella) más el identificador parcial. Lo habitual es que la clave ajena tenga la acción ON DELETE CASCADE, que es la traducción directa de la dependencia en existencia.

Para el ejemplo del hotel:

HOTELES (codigo, nombre, ciudad)

HABITACIONES (*codigo_hotel*, numero, tipo, precio_noche)

  • codigo_hotel → HOTELES(codigo), con borrado en cascada.

Para la cadena de streaming:

SERIES (codigo, titulo)

TEMPORADAS (*codigo_serie*, num_temporada, anio_estreno)

  • codigo_serie → SERIES(codigo)

EPISODIOS (*codigo_serie*, *num_temporada*, num_episodio, titulo, duracion)

  • (codigo_serie, num_temporada) → TEMPORADAS(codigo_serie, num_temporada)

Fíjate en que la clave ajena de EPISODIOS hacia TEMPORADAS es compuesta (dos columnas), porque la clave primaria de TEMPORADAS también lo es. Así es como “crecen” las claves en las cadenas.

Para la débil con dos propietarias:

EXAMENES (*nia*, *codigo_asignatura*, num_convocatoria, fecha, nota)

  • nia → ALUMNOS(nia)
  • codigo_asignatura → ASIGNATURAS(codigo)

⚠️ Importante: No toda tabla con clave primaria compuesta viene de una entidad débil. Las relaciones N:M también se transforman en tablas con clave compuesta (la tabla asignaciones de EMPRESA, con PK (emp_id, proyecto_id)). La diferencia es que en la tabla de una N:M la clave está formada solo por claves ajenas, mientras que en la de una entidad débil incluye además el discriminador propio.


12. El caso LINEAS_PEDIDO del esquema EMPRESA

12.1 Los requisitos

El esquema EMPRESA gestiona los pedidos de los clientes. Los requisitos relevantes son:

  • Cada pedido tiene un número único, la fecha del pedido, la fecha de envío (que no existe mientras no se envía) y un estado (PENDIENTE, ENVIADO, ENTREGADO o CANCELADO).
  • Cada pedido lo realiza un único cliente y puede estar gestionado por un empleado (los pedidos 5014 y 5023 no tienen empleado).
  • Un pedido consta de una o varias líneas, numeradas 1, 2, 3… dentro del pedido.
  • Cada línea es de un único producto, con la cantidad, el precio unitario aplicado y un porcentaje de descuento.
  • Si se elimina un pedido, se eliminan sus líneas.

12.2 El diagrama E/R

flowchart TB
    classDef debil stroke-width:4px
    classDef derivado stroke-dasharray: 5 5
    CLIENTE[CLIENTE] ---|"(1,1)"| realiza{"realiza<br/>1:N"}
    realiza ---|"(0,n)"| PEDIDO[PEDIDO]
    EMPLEADO[EMPLEADO] ---|"(0,1)"| gestiona{"gestiona<br/>1:N"}
    gestiona ---|"(0,n)"| PEDIDO
    PEDIDO ---|"(1,1)"| contiene{"contiene<br/>ID"}:::debil
    contiene ---|"(1,n)"| LINEA_PEDIDO[LINEA_PEDIDO]:::debil
    LINEA_PEDIDO ---|"(1,1)"| de_producto{"de_producto<br/>1:N"}
    de_producto ---|"(0,n)"| PRODUCTO[PRODUCTO]

Y los atributos de PEDIDO y LINEA_PEDIDO:

flowchart LR
    classDef debil stroke-width:4px
    classDef derivado stroke-dasharray: 5 5
    PEDIDO[PEDIDO] --- p_id([<u>pedido_id</u>])
    PEDIDO --- p_fp([fecha_pedido])
    PEDIDO --- p_fe(["fecha_envio (0,1)"])
    PEDIDO --- p_est([estado])
    PEDIDO --- p_tot([importe_total]):::derivado
    LINEA_PEDIDO[LINEA_PEDIDO]:::debil --- l_num(["<u>num_linea</u> parcial"])
    LINEA_PEDIDO --- l_cant([cantidad])
    LINEA_PEDIDO --- l_pre([precio_unitario])
    LINEA_PEDIDO --- l_desc([descuento])
    LINEA_PEDIDO --- l_imp([importe]):::derivado

12.3 Decisiones de diseño comentadas

¿Por qué LINEA_PEDIDO es débil por identificación?

  • No tiene sentido sin su pedido (dependencia en existencia): una línea “suelta” no significa nada.
  • Se identifica dentro del pedido: el número de línea 1 se repite en todos los pedidos.
  • No puede cambiar de pedido.
  • Al borrar un pedido deben desaparecer sus líneas.

¿Por qué (1,n) junto a LINEA_PEDIDO? Porque un pedido sin líneas no es un pedido válido. En los datos de EMPRESA, los 24 pedidos tienen al menos una línea. Ahora bien, como vimos en el módulo 06, esta mínima 1 en el lado N no se puede imponer con una clave ajena: la base de datos, por sí sola, no impide que exista un pedido sin líneas.

¿Por qué precio_unitario es un atributo almacenado de la línea y no un derivado del precio del producto? Porque representa el precio en el momento de la venta. Los precios de los productos cambian; las facturas antiguas no deben cambiar con ellos. Por la misma razón, descuento es de la línea: se negocia en cada pedido.

¿Y los derivados? El importe de una línea (cantidad × precio_unitario × (1 − descuento/100)) y el importe_total del pedido (suma de los importes de sus líneas) son derivados. El esquema EMPRESA no los almacena: se calculan con consultas SQL (lo harás en el bloque de DML).

¿Por qué PEDIDO no es débil de CLIENTE? Ya lo vimos en la sección 3.3: tiene identidad propia (pedido_id), valor contable propio y no debe borrarse con el cliente.

12.4 La alternativa: una relación N:M entre PEDIDO y PRODUCTO

Se podría haber modelado lo mismo como una relación N:M entre PEDIDO y PRODUCTO, con los atributos cantidad, precio_unitario y descuento:

flowchart LR
    PEDIDO[PEDIDO] ---|"(0,n)"| incluye{"incluye<br/>N:M"}
    incluye ---|"(1,n)"| PRODUCTO[PRODUCTO]
    incluye --- i_cant([cantidad])
    incluye --- i_pre([precio_unitario])
    incluye --- i_desc([descuento])

Es un diseño correcto y muy frecuente, pero no es equivalente:

Aspecto Entidad débil LINEA_PEDIDO Relación N:M incluye
¿Puede aparecer el mismo producto dos veces en un pedido? Sí (dos líneas con distinto descuento, o una de regalo) No: solo hay una ocurrencia por pareja (pedido, producto)
Orden de las líneas Lo da num_linea No existe (habría que añadir un atributo)
¿Otras entidades pueden referirse a una línea concreta? Sí (por ejemplo, una DEVOLUCION de la línea 2 del pedido 5001) Solo indirectamente, a través de la pareja (pedido, producto)
Clave primaria en el relacional (pedido_id, num_linea) (pedido_id, producto_id)

En los datos de EMPRESA no hay ningún pedido con el mismo producto en dos líneas, pero el diseño elegido lo permite, lo cual da flexibilidad a la empresa. Es una decisión de diseño, no una imposición técnica.

12.5 La traducción en el esquema EMPRESA

Este es el esquema relacional resultante:

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

  • cliente_id → CLIENTES(cliente_id), no admite nulos.
  • empleado_id → EMPLEADOS(emp_id), admite nulos.

LINEAS_PEDIDO (*pedido_id*, num_linea, producto_id, cantidad, precio_unitario, descuento)

  • pedido_id → PEDIDOS(pedido_id), con borrado en cascada.
  • producto_id → PRODUCTOS(producto_id), no admite nulos.

Y este es el código real del script empresa_crear.sql:

-- ---------------------------------------------------------------------
-- LINEAS_PEDIDO (entidad débil de PEDIDOS: clave primaria compuesta)
-- ---------------------------------------------------------------------
CREATE TABLE lineas_pedido (
    pedido_id        NUMBER(8),
    num_linea        NUMBER(3),
    producto_id      NUMBER(6)    CONSTRAINT nn_lin_producto NOT NULL,
    cantidad         NUMBER(5)    CONSTRAINT nn_lin_cantidad NOT NULL,
    precio_unitario  NUMBER(8,2)  CONSTRAINT nn_lin_precio NOT NULL,
    descuento        NUMBER(4,2)  DEFAULT 0 CONSTRAINT nn_lin_descuento NOT NULL,
    CONSTRAINT pk_lineas_pedido PRIMARY KEY (pedido_id, num_linea),
    CONSTRAINT ck_lin_cantidad  CHECK (cantidad > 0),
    CONSTRAINT ck_lin_precio    CHECK (precio_unitario >= 0),
    CONSTRAINT ck_lin_descuento CHECK (descuento BETWEEN 0 AND 100),
    CONSTRAINT fk_lin_pedido    FOREIGN KEY (pedido_id)   REFERENCES pedidos (pedido_id) ON DELETE CASCADE,
    CONSTRAINT fk_lin_producto  FOREIGN KEY (producto_id) REFERENCES productos (producto_id)
);

Cada elemento del diagrama tiene su reflejo en el código:

Elemento del diseño conceptual Traducción en Oracle
LINEA_PEDIDO es débil por identificación respecto de PEDIDO PRIMARY KEY (pedido_id, num_linea): la PK incluye la clave de la propietaria
num_linea es el identificador parcial Segunda columna de la PK
(1,1) junto a PEDIDO en contiene pedido_id forma parte de la PK, luego no puede ser nulo
Dependencia en existencia: al borrar el pedido desaparecen sus líneas FOREIGN KEY (pedido_id) ... ON DELETE CASCADE
(1,1) junto a PRODUCTO en de_producto (relación normal) producto_id NOT NULL + FK sin cascada: no se puede borrar un producto vendido
Dominios de cantidad, precio_unitario, descuento Restricciones CHECK
(1,n) junto a LINEA_PEDIDO (todo pedido tiene líneas) No se refleja: no puede imponerse con una FK

12.6 Contraste con ASIGNACIONES

La tabla asignaciones de EMPRESA también tiene clave primaria compuesta, (emp_id, proyecto_id), y también tiene una FK con ON DELETE CASCADE (hacia proyectos). ¿Es otra entidad débil? No: es la transformación de una relación N:M con atributos (fecha_asignacion, horas, funcion) entre EMPLEADO y PROYECTO.

flowchart LR
    EMPLEADO[EMPLEADO] ---|"(0,n)"| asignado{"asignado<br/>N:M"}
    asignado ---|"(0,n)"| PROYECTO[PROYECTO]
    asignado --- as_f([fecha_asignacion])
    asignado --- as_h(["horas (0,1)"])
    asignado --- as_fu(["funcion (0,1)"])

La diferencia está en la clave: en asignaciones la PK está formada solo por las dos claves ajenas, sin discriminador. Por eso un empleado solo puede estar asignado una vez a cada proyecto. Si la empresa quisiera registrar varias asignaciones del mismo empleado al mismo proyecto en periodos distintos, tendría que añadir un discriminador (por ejemplo, un número de asignación o la fecha de inicio a la PK), y ASIGNACION pasaría a ser una entidad débil con dos propietarias, como EXAMEN en la sección 8.

El ON DELETE CASCADE hacia proyectos indica que, al borrar un proyecto, se borran las ocurrencias de la relación asignado en las que participa, lo cual es lógico: una asignación a un proyecto que ya no existe no tiene sentido. Las acciones referenciales se estudian en el módulo 24.


13. Errores frecuentes

Error Ejemplo Solución
Marcar como débil una entidad que solo tiene participación obligatoria PEDIDO débil de CLIENTE Entidad fuerte con (1,1) junto a CLIENTE
Dibujar el identificador de la propietaria como atributo de la débil pedido_id como atributo de LINEA_PEDIDO El identificador se hereda por la relación de identificación
Identificador parcial sin marcar num_linea sin subrayar Subrayado + parcial
Débil sin relación de identificación LINEA_PEDIDO suelta, o unida a PEDIDO con un rombo normal Rombo de identificación (borde grueso)
Cardinalidad distinta de (1,1) junto a la propietaria (0,1) o (1,n) junto a PEDIDO en contiene Siempre (1,1)
Débil que “cambia” de propietaria EMPLEADO débil de DEPARTAMENTO Si puede cambiar, no es débil
Discriminador que no discrimina FAMILIAR identificado por parentesco (un empleado puede tener varios hijos) Elegir un atributo único dentro de la propietaria (nombre, número)
Relación N:M con atributos cuando hay repeticiones Préstamos del mismo ejemplar al mismo socio Entidad débil con discriminador (fecha o número) o entidad fuerte
Multivaluado compuesto “escondido” direcciones_envio como texto Entidad débil DIRECCION_ENVIO
Cadena demasiado larga sin valorar alternativas Cinco niveles de débiles Identificador propio en algún nivel

14. Ejercicios

Ejercicio 1: ¿Débil, y de qué tipo?

Para cada caso, indica si la entidad en cursiva es fuerte, débil por existencia (E) o débil por identificación (ID), y justifícalo con las preguntas de la sección 3.3.

a) Un banco concede préstamos a clientes; cada préstamo tiene un número único y siempre tiene un cliente titular. b) Cada préstamo se devuelve en plazos mensuales numerados 1, 2, 3…; de cada plazo se guarda la fecha de vencimiento, el importe y si está pagado. c) Una aseguradora registra los familiares beneficiarios de cada asegurado, identificados por su nombre dentro de cada póliza. d) Un museo registra las obras, cada una con un número de inventario, que pertenecen a una colección; las obras pueden cambiar de colección. e) Un ayuntamiento registra las viviendas de cada calle por su número de portal, piso y puerta. f) Un club deportivo registra las cuotas mensuales de cada socio; cada cuota tiene un número de recibo único y no tiene sentido sin el socio.

Ver solución
Caso Tipo Justificación
a) PRESTAMO Fuerte Tiene identificador propio (número) y valor por sí mismo (contrato). La obligación de tener titular es solo participación obligatoria ((1,1) junto a CLIENTE)
b) PLAZO ID Se numera dentro de cada préstamo (el plazo 7 se repite en todos); no tiene sentido sin el préstamo; no cambia de préstamo. Identificador completo: (num_prestamo, num_plazo)
c) FAMILIAR ID Se identifica por el nombre dentro de la póliza; desaparece si se cancela la póliza
d) OBRA Fuerte Tiene número de inventario propio y puede cambiar de colección: no depende de ella
e) VIVIENDA ID (respecto de CALLE) El “portal 12, 3.º B” solo identifica dentro de una calle; identificador completo (codigo_calle, portal, piso, puerta), con identificador parcial compuesto (portal, piso, puerta)
f) CUOTA E No tiene sentido sin el socio y desaparece con él, pero el número de recibo la identifica por sí sola

Un detalle sobre f): si el club debe conservar los recibos por motivos fiscales aunque el socio se dé de baja, la cuota no desaparecería con el socio y pasaría a ser fuerte. Una vez más, la respuesta depende de los requisitos.

Ejercicio 2: Edificios, plantas y aulas

Un instituto tiene varios edificios (identificados por una letra), cada edificio tiene varias plantas (numeradas desde 0) y cada planta tiene aulas numeradas desde 1. De cada edificio se guarda su nombre; de cada planta, si tiene ascensor; de cada aula, su capacidad y si tiene proyector. Además, cada aula puede estar asignada como aula de referencia a un grupo (cada grupo tiene, como mucho, un aula de referencia).

a) Dibuja el diagrama E/R. b) Escribe el identificador completo de cada entidad. c) Escribe el esquema relacional resultante (adelanto del módulo 17).

Ver solución

a)

flowchart LR
    classDef debil stroke-width:4px
    EDIFICIO[EDIFICIO] ---|"(1,1)"| tiene_p{"tiene<br/>ID"}:::debil
    tiene_p ---|"(1,n)"| PLANTA[PLANTA]:::debil
    PLANTA ---|"(1,1)"| tiene_a{"tiene<br/>ID"}:::debil
    tiene_a ---|"(1,n)"| AULA[AULA]:::debil
    AULA ---|"(0,1)"| referencia{"referencia<br/>1:1"}
    referencia ---|"(0,1)"| GRUPO[GRUPO]
    EDIFICIO --- ed_letra([<u>letra</u>])
    EDIFICIO --- ed_nom([nombre])
    PLANTA --- pl_num(["<u>num_planta</u> parcial"])
    PLANTA --- pl_asc([ascensor])
    AULA --- au_num(["<u>num_aula</u> parcial"])
    AULA --- au_cap([capacidad])
    AULA --- au_pro([proyector])
    GRUPO --- gr_cod([<u>codigo</u>])

Lectura de referencia: “un grupo tiene 0 o 1 aulas de referencia” → (0,1) junto a AULA; “un aula es de referencia de 0 o 1 grupos” → (0,1) junto a GRUPO.

b)

Entidad Identificador completo
EDIFICIO (letra)
PLANTA (letra, num_planta)
AULA (letra, num_planta, num_aula)
GRUPO (codigo)

c)

EDIFICIOS (letra, nombre)

PLANTAS (*letra*, num_planta, ascensor)

  • letra → EDIFICIOS(letra)

AULAS (*letra*, *num_planta*, num_aula, capacidad, proyector)

  • (letra, num_planta) → PLANTAS(letra, num_planta)

GRUPOS (codigo, letra_aula, planta_aula, num_aula)

  • (letra_aula, planta_aula, num_aula) → AULAS(letra, num_planta, num_aula), admite nulos.
  • UK: (letra_aula, planta_aula, num_aula): un aula es de referencia como mucho de un grupo.

Observa cómo la clave de AULAS (tres columnas) se propaga a GRUPOS. Si muchas otras tablas referenciaran aulas (horarios, incidencias, reservas), sería razonable dar a AULA un código propio (por ejemplo, “B-2-05”) y mantener la terna como clave alternativa.

Ejercicio 3: El historial de préstamos de la biblioteca

En el ejercicio 2 del módulo 06 la biblioteca solo guardaba los préstamos activos con una relación SOCIO–EJEMPLAR. Ahora se quiere el historial completo: un socio puede tomar prestado el mismo ejemplar muchas veces. De cada préstamo se guarda la fecha de préstamo, la fecha de devolución prevista y la fecha de devolución real (que no existe mientras el libro no se devuelve). Los ejemplares se numeran dentro de cada libro.

Propón dos diseños: uno con PRESTAMO como entidad débil y otro con PRESTAMO como entidad fuerte. Compáralos.

Ver solución

Primero, EJEMPLAR es débil (ID) de LIBRO, con identificador parcial num_ejemplar.

Diseño 1: PRESTAMO débil con dos propietarias. Un préstamo se identifica por el socio, el ejemplar y la fecha de préstamo (un socio no toma el mismo ejemplar dos veces el mismo día).

flowchart LR
    classDef debil stroke-width:4px
    LIBRO[LIBRO] ---|"(1,1)"| tiene{"tiene<br/>ID"}:::debil
    tiene ---|"(1,n)"| EJEMPLAR[EJEMPLAR]:::debil
    SOCIO[SOCIO] ---|"(1,1)"| hace{"hace<br/>ID"}:::debil
    hace ---|"(0,n)"| PRESTAMO[PRESTAMO]:::debil
    EJEMPLAR ---|"(1,1)"| prestado{"prestado<br/>ID"}:::debil
    prestado ---|"(0,n)"| PRESTAMO
    LIBRO --- l_sig([<u>signatura</u>])
    EJEMPLAR --- e_num(["<u>num_ejemplar</u> parcial"])
    SOCIO --- s_num([<u>num_socio</u>])
    PRESTAMO --- p_fp(["<u>fecha_prestamo</u> parcial"])
    PRESTAMO --- p_fdp([fecha_devolucion_prevista])
    PRESTAMO --- p_fdr(["fecha_devolucion_real (0,1)"])

Identificador completo de PRESTAMO: (num_socio, signatura, num_ejemplar, fecha_prestamo). ¡Cuatro atributos!

Diseño 2: PRESTAMO fuerte con un número propio.

flowchart LR
    classDef debil stroke-width:4px
    LIBRO[LIBRO] ---|"(1,1)"| tiene{"tiene<br/>ID"}:::debil
    tiene ---|"(1,n)"| EJEMPLAR[EJEMPLAR]:::debil
    SOCIO[SOCIO] ---|"(1,1)"| hace{"hace<br/>1:N"}
    hace ---|"(0,n)"| PRESTAMO[PRESTAMO]
    EJEMPLAR ---|"(1,1)"| prestado{"prestado<br/>1:N"}
    prestado ---|"(0,n)"| PRESTAMO
    PRESTAMO --- p_num([<u>num_prestamo</u>])
    PRESTAMO --- p_fp([fecha_prestamo])
    PRESTAMO --- p_fdp([fecha_devolucion_prevista])
    PRESTAMO --- p_fdr(["fecha_devolucion_real (0,1)"])

Comparación:

Aspecto Débil (diseño 1) Fuerte (diseño 2)
Identificador 4 atributos 1 atributo
Garantía “un socio no toma el mismo ejemplar dos veces el mismo día” Por diseño (es la clave) Hay que añadir una restricción de unicidad
Referencias desde otras entidades (por ejemplo, SANCION por un préstamo devuelto tarde) Clave ajena de 4 columnas Clave ajena de 1 columna
¿Se borra el historial si se borra el socio? Sí (dependencia en existencia) Se decide aparte (lo normal sería conservarlo o anonimizarlo)
Uso real “El préstamo del ejemplar 2 de tal libro a tal socio el día X” Las bibliotecas suelen numerar los préstamos

Ambos diseños son correctos. El diseño 2 es el más práctico, sobre todo si el préstamo se relaciona con otras entidades (sanciones, renovaciones). El diseño 1 es el más fiel si no se usa un número de préstamo en el negocio. Observa además que ninguno de los dos expresa la restricción “un ejemplar no puede estar prestado dos veces a la vez” (dos préstamos del mismo ejemplar sin devolver): hay que documentarla.

Ejercicio 4: Préstamo bancario y plazos

Un banco concede préstamos personales. De cada préstamo se guarda un número, el importe, el tipo de interés, la fecha de concesión y el número de meses. Cada préstamo tiene un único titular (un cliente) y puede tener avalistas (otros clientes). Cada préstamo genera tantos plazos como meses: de cada plazo se guarda su número, la fecha de vencimiento, el importe de capital, el importe de intereses, el importe total del plazo y la fecha de pago (si se ha pagado). Dibuja el diagrama completo y comenta cardinalidades y atributos.

Ver solución
flowchart LR
    classDef debil stroke-width:4px
    classDef derivado stroke-dasharray: 5 5
    CLIENTE[CLIENTE] ---|"(1,1) titular"| es_titular{"es_titular<br/>1:N"}
    es_titular ---|"(0,n)"| PRESTAMO[PRESTAMO]
    CLIENTE ---|"(0,n) avalista"| avala{"avala<br/>N:M"}
    avala ---|"(0,n)"| PRESTAMO
    PRESTAMO ---|"(1,1)"| genera{"genera<br/>ID"}:::debil
    genera ---|"(1,n)"| PLAZO[PLAZO]:::debil
    PRESTAMO --- pr_num([<u>num_prestamo</u>])
    PRESTAMO --- pr_imp([importe])
    PRESTAMO --- pr_int([tipo_interes])
    PRESTAMO --- pr_fc([fecha_concesion])
    PRESTAMO --- pr_mes([num_meses])
    PLAZO --- pl_num(["<u>num_plazo</u> parcial"])
    PLAZO --- pl_fv([fecha_vencimiento])
    PLAZO --- pl_cap([importe_capital])
    PLAZO --- pl_int([importe_intereses])
    PLAZO --- pl_tot([importe_total]):::derivado
    PLAZO --- pl_fp(["fecha_pago (0,1)"])

Decisiones comentadas:

  • PLAZO es débil por identificación: se numera dentro de cada préstamo, no tiene sentido sin él y no puede cambiar de préstamo.
  • Junto a PLAZO la cardinalidad es (1,n). Se podría precisar más: el número de plazos coincide con num_meses, una restricción que el diagrama no puede expresar con una pareja fija (cada préstamo tiene un número distinto). Se documenta.
  • Dos relaciones entre CLIENTE y PRESTAMO, con papeles distintos: titular (1:N, obligatoria para el préstamo) y avalista (N:M, opcional). Restricción adicional: el titular no puede ser avalista de su propio préstamo (se documenta).
  • importe_total del plazo es derivado (capital + intereses). En cambio, importe_capital e importe_intereses se almacenan: se calculan con la fórmula del sistema de amortización al conceder el préstamo, pero quedan fijados como parte del contrato.
  • num_meses podría considerarse derivado (número de plazos), pero es un dato del contrato que se fija antes de generar los plazos: se almacena.
  • fecha_pago es opcional: no existe hasta que se paga.

Ejercicio 5: Familiares de los empleados

Una empresa quiere registrar los familiares de sus empleados para el seguro médico: nombre, parentesco (cónyuge, hijo/a…) y fecha de nacimiento. a) Modélalo como entidad débil. b) ¿Qué problema puede tener nombre como identificador parcial y cómo se resuelve? c) La empresa descubre que algunos familiares son también empleados de la empresa (dos hermanos que trabajan en ella, un matrimonio…) y quiere que, en ese caso, el familiar quede relacionado con su ficha de empleado. ¿Cambia el diseño?

Ver solución

a)

flowchart LR
    classDef debil stroke-width:4px
    EMPLEADO[EMPLEADO] ---|"(1,1)"| tiene{"tiene<br/>ID"}:::debil
    tiene ---|"(0,n)"| FAMILIAR[FAMILIAR]:::debil
    EMPLEADO --- e_cod([<u>codigo</u>])
    EMPLEADO --- e_nom([nombre])
    FAMILIAR --- f_nom(["<u>nombre</u> parcial"])
    FAMILIAR --- f_par([parentesco])
    FAMILIAR --- f_fn([fecha_nacimiento])

b) Es improbable, pero no imposible, que un empleado tenga dos familiares con el mismo nombre (un hijo y un padre llamados igual; dos hijos de distintos matrimonios con el mismo nombre). Si ocurre, el diseño no permite registrar al segundo. Soluciones: usar un número de familiar (1, 2, 3…) como identificador parcial; o un identificador parcial compuesto (nombre, fecha_nacimiento). La opción del número es la más robusta.

c) Sí cambia. Si el familiar es también empleado, aparece una segunda relación entre FAMILIAR y EMPLEADO, distinta de la de identificación. Razonemos sus cardinalidades con las cuatro preguntas:

  • Una ficha de familiar, ¿a cuántos empleados corresponde? A ninguno (no trabaja en la empresa) o a uno → (0,1) junto a EMPLEADO.
  • Un empleado, ¿en cuántas fichas de familiar aparece? En ninguna o en varias: Ana puede figurar como familiar de su hermano y de su marido, ambos empleados → (0,n) junto a FAMILIAR.
flowchart LR
    classDef debil stroke-width:4px
    EMPLEADO[EMPLEADO] ---|"(1,1)"| tiene{"tiene<br/>ID"}:::debil
    tiene ---|"(0,n)"| FAMILIAR[FAMILIAR]:::debil
    FAMILIAR ---|"(0,n)"| es_empleado{"es_empleado<br/>1:N"}
    es_empleado ---|"(0,1)"| EMPLEADO
    FAMILIAR --- f_num(["<u>num_familiar</u> parcial"])
    FAMILIAR --- f_nom([nombre])
    FAMILIAR --- f_par([parentesco])

Es fácil equivocarse aquí y escribir (0,1) junto a FAMILIAR “porque el familiar es como mucho un empleado”: es el fallo de convención más común. Lee cada pareja con la frase “un ‹partida› ‹verbo› ‹pareja› ‹llegada›”: “un familiar es ‹(0,1)› empleado”; “un empleado es ‹(0,n)› fichas de familiar”. Observa también que en el diagrama hay dos relaciones entre las mismas entidades con significados muy distintos: tiene (de quién es familiar) y es_empleado (quién es ese familiar dentro de la empresa).

Una alternativa más radical sería modelar una entidad fuerte PERSONA de la que EMPLEADO y FAMILIAR fueran papeles o subtipos (módulo 11), pero para el seguro médico la solución anterior suele bastar.

Ejercicio 6: ¿Multivaluado o entidad débil?

Para cada caso, decide si modelarías un atributo multivaluado, una entidad débil o una entidad fuerte con relación N:M. Dibuja el caso c).

a) Los idiomas que habla un guía turístico (solo el nombre del idioma). b) Los idiomas que habla un guía turístico, con el nivel (A1 a C2) y la fecha del certificado de cada uno. c) Las direcciones de envío de un cliente de una tienda en línea (calle, cp, localidad, nombre del destinatario); cada pedido se envía a una de ellas. d) Las etiquetas (tags) de una publicación de un blog, que se eligen de una lista común y por las que se puede navegar. e) Las fotografías de un inmueble en una inmobiliaria (fichero, orden, descripción).

Ver solución
Caso Modelo Motivo
a) Atributo multivaluado idioma Valores simples sin más información
b) Entidad fuerte IDIOMA + relación N:M habla con atributos nivel y fecha_certificado Hay información de la pareja guía–idioma; un catálogo de idiomas evita valores inconsistentes. (Una débil IDIOMA_GUIA con discriminador idioma también sería aceptable si no se quiere un catálogo)
c) Entidad débil DIRECCION_ENVIO Multivaluado compuesto que, además, participa en una relación con PEDIDO
d) Entidad fuerte ETIQUETA + relación N:M Catálogo compartido entre publicaciones, con existencia propia (se navega por ellas)
e) Entidad débil FOTO Cada valor tiene atributos propios (fichero, orden, descripción) y se numera dentro del inmueble

c)

flowchart LR
    classDef debil stroke-width:4px
    CLIENTE[CLIENTE] ---|"(1,1)"| tiene{"tiene<br/>ID"}:::debil
    tiene ---|"(0,n)"| DIRECCION_ENVIO[DIRECCION_ENVIO]:::debil
    PEDIDO[PEDIDO] ---|"(0,n)"| se_envia{"se_envia<br/>1:N"}
    se_envia ---|"(1,1)"| DIRECCION_ENVIO
    CLIENTE --- c_id([<u>codigo</u>])
    DIRECCION_ENVIO --- d_num(["<u>num_direccion</u> parcial"])
    DIRECCION_ENVIO --- d_calle([calle])
    DIRECCION_ENVIO --- d_cp([cp])
    DIRECCION_ENVIO --- d_loc([localidad])
    DIRECCION_ENVIO --- d_dest([destinatario])
    PEDIDO --- p_num([<u>num_pedido</u>])

Lectura de se_envia: “un pedido se envía a exactamente una dirección” → (1,1) junto a DIRECCION_ENVIO; “a una dirección se envían de 0 a n pedidos” → (0,n) junto a PEDIDO.

Una restricción que el diagrama no expresa: la dirección de envío de un pedido debe ser del mismo cliente que realiza el pedido. Este tipo de restricciones entre caminos de relaciones se estudia en el módulo 13.

Pregunta de diseño importante: si el cliente borra una dirección, ¿se borran los pedidos enviados a ella? Evidentemente no. Por tanto, no se pueden borrar direcciones con pedidos, o habría que guardar en el pedido una copia de la dirección de envío (como se hace con el precio en LINEA_PEDIDO). Muchas tiendas reales hacen precisamente eso.

Ejercicio 7: Del diagrama a pata de gallo y al relacional

Traduce el diagrama del hotel de la sección 6.1, ampliado con la entidad fuerte RESERVA (cada reserva es de una única habitación, una habitación tiene muchas reservas; de cada reserva se guarda un código, la fecha de entrada y la de salida), a erDiagram y al esquema relacional.

Ver solución
erDiagram
    HOTEL ||--o{ HABITACION : "tiene"
    HABITACION ||..o{ RESERVA : "se reserva en"
    HOTEL {
        string codigo PK
        string nombre
        string ciudad
    }
    HABITACION {
        string codigo_hotel PK, FK
        int numero PK
        string tipo
        decimal precio_noche
    }
    RESERVA {
        int codigo PK
        string codigo_hotel FK
        int numero_habitacion FK
        date fecha_entrada
        date fecha_salida
    }

La relación HOTEL–HABITACION es identificadora (línea continua, --): la clave de HOTEL forma parte de la clave de HABITACION. La relación HABITACION–RESERVA es no identificadora (línea discontinua, ..): la reserva tiene su propio código, y la clave de la habitación solo aparece como clave ajena.

Esquema relacional:

HOTELES (codigo, nombre, ciudad)

HABITACIONES (*codigo_hotel*, numero, tipo, precio_noche)

  • codigo_hotel → HOTELES(codigo), con borrado en cascada.

RESERVAS (codigo, codigo_hotel, numero_habitacion, fecha_entrada, fecha_salida)

  • (codigo_hotel, numero_habitacion) → HABITACIONES(codigo_hotel, numero), no admite nulos.

Observa que la reserva necesita dos columnas para referenciar una habitación, porque la clave de la habitación es compuesta. Si hubiera muchas tablas que referenciaran habitaciones, sería un argumento para darle a HABITACION un identificador propio. Y la restricción “las fechas de dos reservas de la misma habitación no se pueden solapar” no puede expresarse ni en el diagrama ni con restricciones declarativas simples: se documenta.

Ejercicios propuestos

✏️ Ejercicio: Propuesto 1 — Clínica. Cada paciente tiene un historial con varias visitas, numeradas dentro de cada paciente; en cada visita se registran varios tratamientos, numerados dentro de la visita. Cada visita la atiende un médico. Dibuja el diagrama, indica los identificadores completos y escribe el esquema relacional. Después, razona si darías a VISITA un identificador propio.

✏️ Ejercicio: Propuesto 2 — Competición deportiva. Una federación organiza competiciones; cada competición tiene varias jornadas numeradas, y en cada jornada se juegan varios partidos numerados dentro de la jornada. Cada partido enfrenta a un equipo local y uno visitante. Modela la cadena COMPETICION → JORNADA → PARTIDO y compara este diseño con el del ejercicio 5 del módulo 04, donde PARTIDO tenía un número propio.

✏️ Ejercicio: Propuesto 3 — Taller mecánico. Retoma el supuesto del taller del módulo 04 y añade: “cada reparación consta de varias tareas numeradas, y en cada tarea trabaja un único mecánico durante un número de horas”. ¿Qué entidad débil aparece? ¿Qué pasa con la relación N:M trabaja entre MECANICO y REPARACION que habíamos dibujado?

✏️ Ejercicio: Propuesto 4 — Facturas y líneas de factura. Una empresa emite facturas con series (A para particulares, B para empresas) y números correlativos dentro de cada serie: A-2026-0001, A-2026-0002, B-2026-0001… Cada factura tiene líneas. ¿Es FACTURA una entidad débil de SERIE? Razona las dos posibilidades y dibuja la que te parezca más adecuada, con sus líneas.

✏️ Ejercicio: Propuesto 5 — Reconstruir el E/R desde las tablas. Lee el script empresa_crear.sql completo e identifica, para cada tabla con clave primaria compuesta, si procede de una entidad débil o de una relación N:M. Para cada clave ajena con ON DELETE CASCADE, explica qué dependencia del diseño conceptual representa.


Resumen

Concepto Idea clave
Entidad débil Depende de otra (la propietaria) para existir y, en el caso habitual, para identificarse
Dependencia en existencia (E) No existe sin la propietaria, desaparece con ella y no cambia de propietaria, pero tiene identificador propio
Dependencia en identificación (ID) Además, necesita el identificador de la propietaria; implica dependencia en existencia
Participación obligatoria Solo mínima 1: no convierte a una entidad en débil (PEDIDO respecto de CLIENTE)
Identificador parcial Distingue las débiles de una misma propietaria: num_linea, numero de habitación
Identificador completo Identificador de la propietaria + identificador parcial
Relación de identificación Une débil y propietaria; (1,1) junto a la propietaria; rombo de borde grueso con E o ID
Notación del curso Entidad y rombo con borde grueso (:::debil); <u>x</u> parcial
Otras notaciones Doble rectángulo y doble rombo (Chen), línea identificadora (pata de gallo, IDEF1X), barra UID (Barker), composición (UML)
Cadenas Débiles de débiles: el identificador se acumula (serie, temporada, episodio)
Varias propietarias Una relación de identificación con cada una (EXAMEN de ALUMNO y ASIGNATURA)
¿Débil o fuerte? Débil si el negocio la identifica “dentro de” otra; código propio si se referencia mucho o la cadena es larga
Multivaluado vs débil Multivaluado compuesto o con relaciones = entidad débil
En el relacional PK = PK de la propietaria (FK, normalmente ON DELETE CASCADE) + identificador parcial
LINEAS_PEDIDO (EMPRESA) PK (pedido_id, num_linea), FK a pedidos con ON DELETE CASCADE, precio_unitario almacenado