Dimensiones role-playing en un star schema: paso a paso
En un data warehouse es habitual que una tabla de hechos guarde varias fechas — la fecha del pedido, la fecha de envío y la fecha prevista de entrega. Crear una dimensión de fecha separada para cada una multiplica el mantenimiento y abre la puerta a inconsistencias. Las dimensiones role-playing resuelven esto: una única dimensión, reutilizada en varios roles dentro del mismo star schema. El nombre viene del teatro — el mismo "actor" (la dimensión) sale a escena en papeles distintos.
Requisitos previos
- Un data warehouse con una dimensión de fecha (
DimDate) ya creada, con clave sustituta (surrogate key). - Una tabla de hechos con más de una fecha (por ejemplo,
FactSales). - Acceso a SQL Server o un motor equivalente y, para el segundo enfoque, a un modelo en Power BI.
- Nociones básicas del esquema en estrella (hechos y dimensiones).
Paso 1: Diseñar la tabla de hechos con varias fechas
Empiece por asegurarse de que la tabla de hechos tiene una clave foránea por cada fecha relevante, todas apuntando a la misma DimDate. Observe que no hay tres dimensiones: hay una sola, referenciada varias veces. Las fechas que aún no han ocurrido (envío, entrega) pueden quedar en NULL hasta que sucedan.
CREATE TABLE FactSales (
SalesKey BIGINT IDENTITY(1,1) PRIMARY KEY,
OrderDateKey INT NOT NULL, -- FK to DimDate
ShipDateKey INT NULL, -- FK to DimDate
DueDateKey INT NULL, -- FK to DimDate
ProductKey INT NOT NULL,
Quantity INT NOT NULL,
Amount DECIMAL(18,2) NOT NULL
);
Paso 2: Mantener una sola dimensión de fecha
No duplique DimDate. Una única tabla — con una fila por día y columnas como CalendarYear, trimestre, mes y día de la semana — sirve para todos los roles. Así, "T1" significa exactamente lo mismo sea cual sea la fecha analizada, y el mantenimiento se concentra en un solo lugar.
Paso 3: Enfoque A — vistas por rol en la base de datos
Cuando el modelo se consume directamente mediante SQL, la opción más clara es exponer la misma dimensión a través de vistas con nombres significativos. Cada vista representa un rol de DimDate.
CREATE VIEW DimOrderDate AS SELECT * FROM DimDate;
GO
CREATE VIEW DimShipDate AS SELECT * FROM DimDate;
GO
CREATE VIEW DimDueDate AS SELECT * FROM DimDate;
GO
Cada unión pasa a usar su vista correspondiente, lo que hace la consulta fácil de leer:
SELECT od.CalendarYear AS OrderYear,
SUM(f.Amount) AS Sales
FROM FactSales AS f
JOIN DimOrderDate AS od ON od.DateKey = f.OrderDateKey
GROUP BY od.CalendarYear
ORDER BY od.CalendarYear;
Este enfoque es simple y universal: cualquier herramienta que lea SQL ve tres dimensiones con nombres distintos. La contrapartida es gestionar más objetos en la base de datos, por lo que conviene documentar que todas comparten la misma DimDate.
Paso 4: Enfoque B — múltiples relaciones en el modelo semántico
En Power BI o Analysis Services, importe DimDate una sola vez y cree una relación por cada clave de fecha de la tabla de hechos. El motor solo permite una relación activa entre dos tablas; las demás quedan inactivas (con línea discontinua en el diagrama). Esto evita ambigüedad: por defecto, el motor necesita saber qué camino seguir entre las tablas. La relación activa suele ser la de la fecha del pedido.
Para analizar por una fecha inactiva, active la relación solo dentro de la medida, con USERELATIONSHIP:
Sales by Ship Date =
CALCULATE (
SUM ( FactSales[Amount] ),
USERELATIONSHIP ( FactSales[ShipDateKey], DimDate[DateKey] )
)
La medida de ventas normal sigue usando la fecha del pedido; esta nueva medida filtra por la fecha de envío, sin necesidad de duplicar la dimensión.
Consejo: dé a cada medida de rol un nombre claro — "Sales by Ship Date", "Sales by Due Date" — para que quien lea el informe sepa de inmediato qué fecha se está usando.
Verificar el resultado
Coloque las dos medidas una al lado de la otra en una matriz, con los años de DimDate en las filas. Si los totales anuales difieren entre la medida de pedido y la de envío, los roles funcionan: cada uno filtra por una fecha distinta. En el enfoque SQL, compare el total agrupado por DimOrderDate con el mismo total agrupado por DimShipDate — los valores deben divergir siempre que el pedido y el envío caigan en años diferentes.
Conclusión
Con una única dimensión de fecha reutilizada en varios roles, el modelo se vuelve más simple, coherente y fácil de mantener. La misma técnica se aplica a otras dimensiones — por ejemplo, un DimEmployee en los roles de "vendedor" y "aprobador". ¿Cuál de las fechas de su negocio merece ya su propia medida?