Modelado Avanzado: Jerarquías, Categorías y Patrones de Diseño de Datos

Capítulo 7

Tiempo estimado de lectura: 9 minutos

+ Ejercicio

Generalización y especialización (herencia): cuándo usarla

La generalización/especialización modela un conjunto de entidades que comparten atributos comunes (supertipo) y, a la vez, tienen atributos o reglas específicas (subtipos). En bases de datos relacionales no existe “herencia” nativa, así que se implementa con estrategias de mapeo.

Decisiones clave antes de mapear

  • Disyunta vs. solapada: ¿una instancia puede pertenecer a más de un subtipo a la vez?
  • Total vs. parcial: ¿toda instancia del supertipo debe pertenecer a algún subtipo?
  • Estabilidad: ¿los subtipos cambian con frecuencia (nuevas variantes) o son estables?
  • Consultas dominantes: ¿se consulta más el supertipo (vista unificada) o cada subtipo por separado?

Ejemplo conceptual: Persona como supertipo y subtipos Cliente y Empleado. Si una persona puede ser ambas cosas, el modelo es solapado; si toda persona debe ser cliente o empleado, es total.

Estrategias de mapeo relacional para herencia

1) Tabla por jerarquía (Single Table Inheritance)

Se usa una sola tabla para el supertipo y todos los subtipos, con una columna discriminadora (por ejemplo, tipo) y columnas opcionales para atributos específicos.

PERSONA( id PK, tipo, nombre, email, ... , salario, fecha_contratacion, limite_credito )
  • Ventajas: consultas simples (no requiere joins), inserciones rápidas, ideal cuando se consulta “todo junto”.
  • Desventajas: muchas columnas nulas, validaciones complejas (asegurar que salario solo aplique a empleados), riesgo de “tabla monstruo”.
  • Cuándo elegirla: pocos subtipos, pocos atributos específicos, alta necesidad de lectura unificada, y tolerancia a nulos.

2) Tabla por subtipo (Class Table Inheritance)

Una tabla para el supertipo con atributos comunes y una tabla por subtipo con atributos específicos. La PK del subtipo también es FK al supertipo (relación 1 a 1).

PERSONA( id PK, nombre, email, ... )
EMPLEADO( id PK/FK -> PERSONA.id, salario, fecha_contratacion )
CLIENTE( id PK/FK -> PERSONA.id, limite_credito )
  • Ventajas: modelo limpio, sin nulos innecesarios, reglas por subtipo más fáciles, extensible.
  • Desventajas: más joins para obtener la vista completa, inserciones requieren varias operaciones, cuidado con integridad (totalidad/disyunción).
  • Cuándo elegirla: atributos específicos relevantes, necesidad de integridad fuerte por subtipo, crecimiento moderado de subtipos.

3) Tabla por clase concreta (Concrete Table Inheritance)

No hay tabla del supertipo; cada subtipo tiene su propia tabla con atributos comunes duplicados.

Continúa en nuestra aplicación.
  • Escuche el audio con la pantalla apagada.
  • Obtenga un certificado al finalizar.
  • ¡Más de 5000 cursos para que explores!
O continúa leyendo más abajo...
Download App

Descargar la aplicación

EMPLEADO( id PK, nombre, email, salario, fecha_contratacion )
CLIENTE( id PK, nombre, email, limite_credito )
  • Ventajas: consultas por subtipo sin joins, tablas autónomas.
  • Desventajas: duplicación de columnas, difícil garantizar unicidad global (por ejemplo, email único entre empleados y clientes), reportes unificados requieren UNION, mantenimiento más costoso.
  • Cuándo elegirla: subtipos casi nunca se consultan juntos, reglas y ciclos de vida muy distintos, o cuando se prioriza independencia por subtipo.

Criterios prácticos de elección (checklist)

CriterioTabla por jerarquíaTabla por subtipoTabla por clase concreta
Consultas unificadas frecuentesAltaMediaBaja
Integridad por subtipo (atributos obligatorios)Baja/MediaAltaAlta (por tabla)
Nulos/columnas opcionalesMuchosPocosNinguno (pero duplicación)
Facilidad de evolución (agregar subtipo)Media (alter table)AltaMedia (nueva tabla + reportes)
Riesgo de duplicaciónBajoBajoAlto

Guía paso a paso para decidir

  1. Lista atributos comunes y atributos exclusivos por subtipo.
  2. Define reglas: disyunción/solapamiento y totalidad/parcialidad.
  3. Revisa consultas: ¿necesitas listar “todas las personas” con frecuencia?
  4. Evalúa integridad: ¿es crítico que ciertos campos sean obligatorios solo en un subtipo?
  5. Prototipa 2 opciones y estima: número de joins, nulos, y complejidad de constraints.
  6. Elige la que minimice complejidad total (modelo + consultas + validaciones).

Roles múltiples: cuando una entidad “actúa como” varias cosas

Un error común es crear subtipos para roles que en realidad son contextuales. Por ejemplo, una misma Persona puede ser Comprador en una orden y Solicitante en un ticket. Eso no siempre justifica subtipos permanentes.

Patrón recomendado: roles como relaciones

Modela el rol en la relación o en una tabla intermedia con un atributo rol.

PARTICIPACION( id PK, persona_id FK, proceso_id FK, rol, desde, hasta )
  • Ventaja: una persona puede tener múltiples roles simultáneos sin forzar herencia.
  • Cuándo usarlo: roles dependen del contexto (proceso, documento, proyecto) y pueden cambiar con el tiempo.

Cuándo sí usar subtipos para roles

  • Cuando el rol implica atributos propios persistentes (p. ej., Empleado con salario).
  • Cuando el rol tiene reglas de negocio estructurales (p. ej., solo empleados pueden aprobar gastos).

Relaciones recursivas: empleado–supervisor y restricciones típicas

Una relación recursiva conecta una entidad consigo misma. El caso clásico es Empleado que supervisa a otros empleados.

Implementación típica

EMPLEADO( id PK, nombre, supervisor_id FK -> EMPLEADO.id NULL )
  • Cardinalidad usual: un empleado tiene 0..1 supervisor; un supervisor tiene 0..N subordinados.
  • Raíz: el director general puede tener supervisor_id nulo.

Restricciones importantes (y cómo abordarlas)

  • Evitar ciclos (A supervisa a B y B supervisa a A, o ciclos largos). En SQL estándar no es trivial con constraints; suele resolverse con lógica en aplicación, procedimientos, o validación con consultas recursivas antes de actualizar.
  • Profundidad máxima (opcional): si la organización limita niveles, se valida con reglas adicionales.
  • Supervisor debe existir: FK lo asegura; si se permite “supervisor externo”, se modela con otra entidad o un tipo de supervisor.

Si necesitas almacenar jerarquías complejas con consultas frecuentes (por ejemplo, “todos los descendientes”), considera patrones de jerarquías como closure table o materialized path. Úsalos solo si el caso de uso lo exige, porque incrementan complejidad y mantenimiento.

Patrones comunes de diseño de datos

Catálogos y enumeraciones

Los catálogos representan listas controladas (p. ej., tipos de documento, países, estados de una orden). Hay dos enfoques principales:

  • Enumeración en código/DB: valores fijos y pocos cambios (p. ej., tipo_documento = DNI, PASAPORTE). En DB puede ser CHECK o tipo enumerado si el motor lo soporta.
  • Tabla catálogo: valores administrables (altas/bajas), con metadatos (orden, descripción, vigencia).
CAT_ESTADO_ORDEN( id PK, codigo UNIQUE, nombre, activo )
ORDEN( id PK, estado_id FK -> CAT_ESTADO_ORDEN.id, ... )

Criterio: si el negocio necesita administrar la lista sin despliegues, usa tabla catálogo; si es estrictamente fijo y pequeño, una enumeración puede ser suficiente.

Auditoría: created_at, updated_at, y “quién”

Un patrón mínimo de auditoría agrega marcas de tiempo y, si aplica, usuario responsable.

... , created_at, created_by, updated_at, updated_by
  • Buenas prácticas: created_at inmutable; updated_at cambia en cada modificación.
  • Implementación: defaults y triggers pueden ayudar, pero define una convención consistente para todo el esquema.

Historial y vigencia: SCD Tipo 2 (Slowly Changing Dimension)

SCD Tipo 2 guarda el historial de cambios creando nuevas filas con rangos de vigencia. Es útil cuando necesitas responder “¿qué valor tenía este atributo en una fecha pasada?”

Estructura típica

CLIENTE_SCD2( sk PK, cliente_id, nombre, segmento, ...,
             valid_from, valid_to, is_current )
  • cliente_id: identificador de negocio (natural o surrogate estable).
  • sk: clave surrogate de versión (cada cambio crea una nueva).
  • valid_to: puede ser NULL o una fecha “alta” para la versión actual.

Guía paso a paso para aplicar SCD2

  1. Identifica atributos historizables (p. ej., segmento, dirección comercial) y separa los no historizables.
  2. Define la clave de negocio (cliente_id) y la clave de versión (sk).
  3. Diseña vigencia: valid_from, valid_to, is_current.
  4. Regla de actualización: al cambiar un atributo historizable, cierra la versión actual (valid_to = fecha_cambio, is_current = false) e inserta una nueva versión con valid_from = fecha_cambio.
  5. Evita solapamientos: asegura que por cliente_id exista solo una fila is_current = true y que los rangos no se crucen.

Este patrón es potente, pero incrementa volumen y complejidad de consultas; úsalo cuando el historial sea un requisito real, no “por si acaso”.

Manejo de estados: máquinas de estado y trazabilidad

Muchas entidades pasan por estados (p. ej., orden: borrador → confirmada → enviada → entregada → cancelada). Hay dos niveles:

  • Estado actual: una FK a catálogo de estados o un valor enumerado.
  • Historial de estados: tabla de eventos para auditoría y análisis.
ORDEN( id PK, estado_id FK, ... )
ORDEN_ESTADO_HIST( id PK, orden_id FK, estado_id FK, changed_at, changed_by, motivo )

Recomendación: si necesitas saber “cuándo pasó a enviado” o “quién canceló”, crea historial. Si solo importa el estado actual, evita la tabla extra.

Riesgos frecuentes y cómo mantener el modelo comprensible

Riesgo 1: explosión de tablas por subtipos

  • Síntoma: docenas de subtipos con 1–2 atributos cada uno, y consultas llenas de joins.
  • Mitigación: valida si son roles contextuales (mejor como relación con rol), o si son “variantes” que encajan mejor en un catálogo + atributos parametrizados (con cuidado).
  • Regla práctica: si el subtipo no aporta reglas/atributos sustanciales y estables, probablemente no es subtipo.

Riesgo 2: sobreuso de tabla por jerarquía

  • Síntoma: una tabla enorme con muchas columnas nulas y validaciones difíciles.
  • Mitigación: migra a tabla por subtipo cuando la integridad por subtipo sea importante o cuando la tabla crezca sin control.

Riesgo 3: jerarquías recursivas sin control de ciclos

  • Síntoma: datos inconsistentes (ciclos) que rompen reportes y recorridos.
  • Mitigación: define una política de validación (en capa de servicio, triggers, o procedimientos) y pruebas automatizadas con consultas recursivas para detectar ciclos.

Riesgo 4: catálogos “cajón de sastre”

  • Síntoma: una sola tabla de catálogos genérica para todo, sin integridad semántica.
  • Mitigación: prefiere catálogos específicos por dominio (p. ej., CAT_ESTADO_ORDEN, CAT_TIPO_PAGO) o, si usas un catálogo genérico, asegúrate de tener claves compuestas y restricciones claras por “familia”.

Riesgo 5: historial (SCD2) aplicado indiscriminadamente

  • Síntoma: crecimiento acelerado, consultas complejas, confusión entre “actual” e “histórico”.
  • Mitigación: historiza solo atributos con valor analítico/legal; documenta cómo consultar la versión vigente (por is_current o por rango de fechas).

Prácticas para mantener el modelo entendible

  • Nombres consistentes: sufijos como _HIST, _SCD2, CAT_ ayudan a leer el esquema.
  • Documenta reglas de herencia: disyunta/solapada y total/parcial, y cómo se implementa (constraints, lógica).
  • Vistas de consumo: crea vistas que presenten una “cara simple” (por ejemplo, una vista unificada de persona) cuando el modelo físico sea más complejo.
  • Diagrama por contexto: separa el diagrama en áreas (personas, órdenes, auditoría) para evitar un “mapa imposible”.

Ahora responde el ejercicio sobre el contenido:

En un modelo donde una misma Persona puede desempeñar múltiples roles dependiendo del contexto (por ejemplo, en distintos procesos) y esos roles pueden cambiar con el tiempo, ¿qué enfoque de modelado es el más adecuado?

¡Tienes razón! Felicitaciones, ahora pasa a la página siguiente.

¡Tú error! Inténtalo de nuevo.

Cuando el rol es contextual y puede variar en el tiempo, conviene representarlo en la relación (tabla intermedia) con un atributo rol y fechas de vigencia, evitando crear subtipos permanentes innecesarios.

Siguiente capítulo

Modelado Orientado a Consultas: Rendimiento y Escalabilidad sin Perder Integridad

Arrow Right Icon
Portada de libro electrónico gratuitaModelado de Datos desde Cero: Fundamentos para Bases de Datos Profesionales
78%

Modelado de Datos desde Cero: Fundamentos para Bases de Datos Profesionales

Nuevo curso

9 páginas

Descarga la aplicación para obtener una certificación gratuita y escuchar cursos en segundo plano, incluso con la pantalla apagada.