Cómo crear una Fact table de tipo 'Event Stream' en Modelado de Datos (Kimball)
Este tutorial enseña cómo modelar una Fact table del tipo "Event Stream" en Modelado de Datos (Kimball) para registrar eventos transaccionales continuos (logs, clics, mensajes). Una Event Stream fact table es útil para análisis de comportamiento, funnel, latencia y series temporales, permitiendo agregar por tiempo y dimensión.
Pre-requisitos
- Conocimientos básicos de Modelado de Datos (Kimball), star schema y conceptos de dimensiones y fact tables.
- Entorno SQL (p. ej.: SQL Server, PostgreSQL o Azure SQL) para crear tablas y cargar datos.
- Ejemplo de fuente de eventos (CSV, stream o tabla de staging) con timestamp, user_id, event_type y payload mínimo.
Paso 1: Definir el propósito y el grain de la Event Stream Fact
Antes de crear tablas, explique claramente el propósito: analizar eventos individuales (cada fila = 1 evento) con resolución temporal elevada. El grain define que cada registro representa un evento generado en un instante por un sujeto o sistema. Esto evita ambigüedades en la agregación.
Paso 2: Elegir las dimensiones conformed y los atributos esenciales
Seleccione dimensiones necesarias para los análisis: DimDate (tiempo), DimUser, DimEventType y, si es necesario, DimDevice o DimSession. No cargue payloads grandes en la fact; guarde referencias o claves para atributos detallados en dimensiones o en un área de OneLake/Lakehouse.
Paso 3: Esquema físico de la Event Stream Fact
Crear la estructura mínima con claves surrogate para dimensiones, timestamp y medidas de conteo. Incluye columnas para event_id, event_ts, keys y medidas (event_value si procede). Ejemplo SQL:
CREATE TABLE fact_event_stream (
event_sk BIGINT IDENTITY(1,1) PRIMARY KEY,
event_id VARCHAR(100), -- id original do evento
event_ts DATETIME2 NOT NULL, -- timestamp do evento
date_sk INT NULL, -- FK para DimDate (date part)
user_sk INT NULL, -- FK para DimUser
eventtype_sk INT NULL, -- FK para DimEventType
session_sk INT NULL, -- FK opcional para DimSession
event_value FLOAT NULL, -- medida opcional
raw_payload NVARCHAR(MAX) NULL -- só se necessário para debugging
);
Paso 4: Población y enriquecimiento (ETL/ELT)
Al cargar, asigne las surrogate keys de las dimensiones. Si usa ELT, haga JOINs entre la staging de eventos y las dimensiones conformed para obtener las SKs. Mantenga el proceso idempotente usando event_id como clave natural.
-- Exemplo simplificado (INSERT com lookup de chaves)
INSERT INTO fact_event_stream (event_id,event_ts,date_sk,user_sk,eventtype_sk,event_value)
SELECT s.event_id, s.event_ts, d.date_sk, u.user_sk, et.eventtype_sk, s.value
FROM staging_events s
LEFT JOIN dim_date d ON CAST(s.event_ts AS DATE) = d.calendar_date
LEFT JOIN dim_user u ON s.user_id = u.user_id
LEFT JOIN dim_eventtype et ON s.event_type = et.event_type
WHERE NOT EXISTS (
SELECT 1 FROM fact_event_stream f WHERE f.event_id = s.event_id
);
Paso 5: Optimizaciones para alta cardinalidad y rendimiento
Event streams generan muchos registros. Use partición por date_sk o por event_ts (día/mes) e índices en las columnas de lookup (event_ts, user_sk, eventtype_sk). Evite NVARCHAR(MAX) en producción; mantenga raw_payload separado en un storage de logs o OneLake.
Paso 6: Tratamiento de eventos duplicados y ordenación
Defina política para duplicados: deduplicación por event_id y, en streams idénticos sin id, por (user_id,event_ts,event_type). Para ordenación temporal, use event_ts con precisión suficiente y, si es necesario, una columna sequence_number generada en el productor.
-- Deduplicação por combinação quando não há event_id
WITH candidate AS (
SELECT *, ROW_NUMBER() OVER (PARTITION BY user_id, event_ts, event_type ORDER BY ingest_ts) rn
FROM staging_events
)
INSERT INTO fact_event_stream (...) SELECT ... FROM candidate WHERE rn = 1;
Verificar el resultado
Valide que el grain está correcto y que no hay duplicados. Ejemplos de queries de verificación:
-- Contagem por dia
SELECT d.calendar_date, COUNT(*) total_events
FROM fact_event_stream f
JOIN dim_date d ON f.date_sk = d.date_sk
GROUP BY d.calendar_date
ORDER BY d.calendar_date DESC;
-- Checar duplicados
SELECT event_id, COUNT(*) c FROM fact_event_stream GROUP BY event_id HAVING COUNT(*) > 1;
Conclusión
Una Event Stream fact table permite analizar eventos en detalle y a escala — la clave es definir el grain, usar dimensiones conformed, partición y deduplicación. Próximos pasos: crear agregaciones precomputadas (materialized views), ajustar retención e integrar con Power BI o herramientas de streaming. Consejo: empiece por un conjunto reducido de eventos y monitorice el crecimiento de la cardinalidad.