Cómo usar una dimensión role-playing en un Data Warehouse
En una venta, la fecha del pedido, la fecha de envío y la fecha de entrega apuntan todas al mismo calendario, pero significan cosas distintas. Una dimensión role-playing resuelve justamente esto: reutiliza una única tabla de dimensión en varios roles dentro del mismo Data Warehouse, manteniendo el modelo simple, coherente y fácil de mantener. Es un patrón clásico del modelado dimensional de Kimball y aparece en casi todos los proyectos reales de BI.
Requisitos previos
- Un Data Warehouse con esquema en estrella (SQL Server, Azure Synapse, Microsoft Fabric o equivalente).
- Una dimensión de fecha (
DimData) ya creada y poblada. - Una tabla de hechos con más de una columna de fecha.
- Conocimientos básicos de SQL (
JOINy views).
Paso 1: Identificar las distintas fechas en la tabla de hechos
Imagina una tabla FactVendas con tres fechas diferentes: cuándo se realizó el pedido, cuándo se envió y cuándo se entregó. Cada una es una clave foránea que apunta a la misma dimensión de fecha. Guardar varias fechas es normal — representan el ciclo de vida del pedido.
CREATE TABLE FactVendas (
VendaKey INT NOT NULL,
DataEncomendaKey INT NOT NULL,
DataEnvioKey INT NOT NULL,
DataEntregaKey INT NOT NULL,
ProdutoKey INT NOT NULL,
Quantidade INT NOT NULL,
ValorTotal DECIMAL(12,2) NOT NULL
);
Paso 2: Reutilizar la misma dimensión con alias
El error más común es crear tres tablas de fecha separadas. No hace falta: basta con unir la misma DimData tres veces, dando un alias distinto a cada rol. Duplicar la dimensión implicaría mantener tres procesos de ETL, ocupar más espacio y arriesgar inconsistencias cuando cambia el calendario; reutilizarla evita todo esto.
SELECT
f.VendaKey,
de.Data AS DataEncomenda,
dv.Data AS DataEnvio,
dt.Data AS DataEntrega,
f.ValorTotal
FROM FactVendas AS f
JOIN DimData AS de ON f.DataEncomendaKey = de.DataKey
JOIN DimData AS dv ON f.DataEnvioKey = dv.DataKey
JOIN DimData AS dt ON f.DataEntregaKey = dt.DataKey;
Cada alias (de, dv, dt) representa un rol de la misma dimensión. Así mantienes una única fuente de verdad para el calendario, sin datos duplicados.
Paso 3: Crear vistas para hacer explícito cada rol
Para que los analistas y las herramientas de BI vean nombres claros, crea una view por rol, renombrando las columnas. Es la forma más limpia de exponer una dimensión role-playing en un Data Warehouse, y las vistas casi no ocupan espacio.
CREATE VIEW dim.DataEncomenda AS
SELECT
DataKey AS DataEncomendaKey,
Data AS DataEncomenda,
Ano AS AnoEncomenda,
NomeMes AS MesEncomenda
FROM DimData;
GO
CREATE VIEW dim.DataEnvio AS
SELECT
DataKey AS DataEnvioKey,
Data AS DataEnvio,
Ano AS AnoEnvio,
NomeMes AS MesEnvio
FROM DimData;
Repite el mismo patrón para dim.DataEntrega. Todas las vistas apuntan a la misma DimData, pero presentan nombres específicos de cada rol.
Paso 4: Consultar a través de las vistas
Ahora las consultas resultan legibles y cada fecha aporta su propio contexto — ideal, por ejemplo, para comparar el total por año de pedido con el total por año de envío.
SELECT
e.AnoEncomenda,
v.AnoEnvio,
SUM(f.ValorTotal) AS Total
FROM FactVendas AS f
JOIN dim.DataEncomenda AS e ON f.DataEncomendaKey = e.DataEncomendaKey
JOIN dim.DataEnvio AS v ON f.DataEnvioKey = v.DataEnvioKey
GROUP BY e.AnoEncomenda, v.AnoEnvio;
Verificar el resultado
Haz dos comprobaciones sencillas. Primero, el número de filas al usar las vistas debe coincidir con el de la tabla de hechos — si es menor, has perdido filas en algún JOIN:
SELECT COUNT(*) AS TotalLinhas
FROM FactVendas AS f
JOIN dim.DataEncomenda AS e ON f.DataEncomendaKey = e.DataEncomendaKey
JOIN dim.DataEnvio AS v ON f.DataEnvioKey = v.DataEnvioKey;
Después, agrupa primero por AnoEncomenda y luego por AnoEnvio: si los totales difieren, confirmas que cada rol funciona de forma independiente.
Conclusión
Con una dimensión role-playing evitas duplicar tablas, garantizas un calendario coherente y haces los informes mucho más claros. El siguiente paso es llevar este modelo a Power BI: como solo puede existir una relación activa entre dos tablas, usarás relaciones inactivas con USERELATIONSHIP o copias de la dimensión. ¿Qué otra dimensión de tu modelo — como cliente o geografía — podría beneficiarse de varios roles?