DP-600: implementar relaciones many-to-many en modelos semánticos
Voy a explicar cómo implementar correctamente relaciones many-to-many (M:N) en modelos semánticos en el contexto del examen DP-600 y en la práctica profesional. Esta competencia es frecuente en modelos reales con granularidades diferentes y es importante para garantizar resultados correctos y un rendimiento aceptable.
Qué necesitas saber
Una relación many-to-many (M:N) ocurre cuando varias filas en una tabla A se relacionan con varias filas en una tabla B. En modelos relacionales simples (star schema) evitamos esto, pero datos del mundo real (p. ej.: productos con múltiples etiquetas, clientes en varias regiones, eventos con múltiples participantes) generan M:N. En el contexto de modelos semánticos (Power BI / Fabric), manejar mal las M:N provoca recuentos erróneos, duplicaciones en agregaciones y problemas de rendimiento.
Hay dos enfoques comunes:
- Bridge table (tabla de enlace) normalizada: una tabla de hechos que expresa la relación entre las dos entidades.
- Modelo con tabla de relación y cardinalidad configurada en el modelo semántico usando propiedades como "Many-to-many (single direction / both directions)" y, ocasionalmente, columnas de conteo distinto para controlar agregaciones.
Ejemplo práctico: tenemos una tabla Product y una tabla Tag. Un producto puede tener varias tags y una tag puede aplicarse a varios productos. Si unimos Product y Tag directamente sin una tabla de enlace, vamos a duplicar métricas (p. ej.: Sales) por cada tag asociada.
Cómo funciona
Pasos conceptuales para implementar correctamente un escenario M:N usando una bridge table:
- Identificar las tablas involucradas y la naturaleza de la relación (A ⇄ B).
- Crear una tabla de enlace (Bridge) que contenga pares de claves: ProductID, TagID. Esta tabla no debe contener valores de métricas factuales que serían duplicados.
- Establecer relaciones 1:N entre Product → Bridge (1 lado es Product) y Tag → Bridge (1 lado es Tag). En el modelo semántico, ambas relaciones deben ser con cardinalidad one-to-many (1:N), con la Bridge en el lado muchos.
- Configurar la direccionalidad del filtro: generalmente se usa Single direction desde las dimensiones hacia la Bridge o Both directions cuando es necesario propagar filtros a través de la bridge hacia hechos, pero Both directions puede afectar al rendimiento e introducir ambigüedad. Prefiere Single y medidas explícitas cuando sea posible.
- Escribir medidas DAX que eviten duplicación: cuando agregas hechos a través de la bridge, usar funciones como DISTINCT, SUMX sobre valores agregados por clave, o medidas que calculen sobre la tabla de hechos original y luego se relacionen con la bridge sin duplicar.
-- Exemplo DAX (padrão) para somar Sales por Tag sem duplicar quando Product tem várias tags
Sales by Tag =
VAR ProductsForTag =
DISTINCT( Bridge[ProductID] )
RETURN
CALCULATE(
SUM( Sales[SalesAmount] ),
KEEPFILTERS( ProductsForTag )
)
Alternativa con SUMX para garantizar una suma única por producto:
Sales by Tag 2 =
SUMX(
VALUES( Bridge[ProductID] ),
CALCULATE( SUM( Sales[SalesAmount] ) )
)
En la práctica
Ejemplo paso a paso en un entorno Fabric / Power BI Desktop:
- En Data Factory / Power Query, crear la Bridge table con pares ProductID-TagID. No importes columnas innecesarias que aumenten la cardinalidad.
- En Model view, conectar Product[ProductID] → Bridge[ProductID] (1 → *), y Tag[TagID] → Bridge[TagID] (1 → *).
- Definir ambas relaciones como Single direction por defecto. Solo usar Both directions si existe una necesidad clara de filtrado bidireccional (p. ej.: slicers que necesitan cruzar ambas dimensiones a través de la Bridge).
- Crear medidas en el espacio de medidas (model) que usen VALUES/DISTINCT para evitar duplicación. Probar con tarjetas y tablas para confirmar que las sumas corresponden al total esperado.
- Monitorizar cardinalidades y compresión: en Fabric / Power BI, tablas con alta cardinalidad en la bridge aumentan el modelo; evaluar si la bridge puede reducirse (por ejemplo, usando enteros más pequeños, eliminando columnas innecesarias, o agregando).
Errores comunes
- Duplicación de hechos al agregar sin usar DISTINCT/VALUES o sin una bridge normalizada — causa totales inflados.
- Usar Both directions de forma automática y sin evaluar — puede resolver filtros pero introducir bucles de relaciones, ambigüedades y degradar el rendimiento.
- Colocar métricas en la bridge (p. ej.: SalesAmount) en lugar de mantenerlas en la tabla de hechos — incrementa la cardinalidad y dificulta cálculos correctos.
Cómo practicar
Practica con un dataset que contenga relaciones M:N (por ejemplo: Products, Tags, Sales). Implementa la bridge y crea medidas que confirmen los totales. Para evaluación oficial, utiliza el Practice Assessment OFICIAL de Microsoft (gratuito) y sigue la study guide de Microsoft (gratuita) para DP-600. Esos recursos son los únicos que reproducen el formato y el tipo de preguntas del examen; úsalos para validar conocimientos e identificar lagunas.
En resumen
- Usa una bridge table para normalizar relaciones M:N y evita duplicación de hechos.
- Prefiere Single direction en las relaciones y escribe medidas DAX con DISTINCT/VALUES o SUMX para sumatorios correctos.
- Evalúa cardinalidad y rendimiento: reduce columnas y tipos innecesarios en la bridge.
- Practica con datasets reales y valida con el Practice Assessment oficial y la study guide de Microsoft (ambos gratuitos).