Como criar uma Fact table de tipo 'Event Stream' em Modelação de Dados (Kimball)
Este tutorial ensina como modelar uma Fact table do tipo "Event Stream" em Modelação de Dados (Kimball) para registar eventos transaccionais contínuos (logs, cliques, mensagens). Uma Event Stream fact table é útil para análises de comportamento, funnel, latência e séries temporais, permitindo agregar por tempo e dimensão.
Pré-requisitos
- Conhecimentos básicos de Modelação de Dados (Kimball), star schema e conceitos de dimensões e fact tables.
- Ambiente SQL (ex.: SQL Server, PostgreSQL ou Azure SQL) para criar tabelas e carregar dados.
- Exemplo de fonte de eventos (CSV, stream ou tabela de staging) com timestamp, user_id, event_type e payload mínimo.
Passo 1: Definir o propósito e o grain da Event Stream Fact
Antes de criar tabelas, explique claramente o propósito: analisar eventos individuais (cada linha = 1 evento) com resolução temporal elevada. O grain define que cada registo representa um evento gerado num instante por um sujeito ou sistema. Isto evita ambiguidades na agregação.
Passo 2: Escolher as dimensões conformed e os atributos essenciais
Selecione dimensões necessárias para as análises: DimDate (tempo), DimUser, DimEventType e, se necessário, DimDevice ou DimSession. Não carregue payloads grandes na fact; guarde referências ou chaves para atributos detalhados em dimensões ou numa área de OneLake/Lakehouse.
Passo 3: Esquema físico da Event Stream Fact
Crie a estrutura mínima com chaves surrogate para dimensões, timestamp e medidas de contagem. Inclui colunas para event_id, event_ts, keys e medidas (event_value se aplicável). Exemplo 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
);
Passo 4: População e enriquecimento (ETL/ELT)
Ao carregar, atribua as surrogate keys das dimensões. Se usar ELT, faça JOINs entre a staging de eventos e as dimensões conformed para obter as SKs. Mantenha o processo idempotente usando event_id como chave 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
);
Passo 5: Otimizações para alta cardinalidade e performance
Event streams geram muitos registos. Use partição por date_sk ou por event_ts (dia/mês) e índices nas colunas de lookup (event_ts, user_sk, eventtype_sk). Evite NVARCHAR(MAX) em produção; mantenha raw_payload separado num storage de logs ou OneLake.
Passo 6: Tratamento de eventos duplicados e ordenação
Defina política para duplicados: deduplicação por event_id e, em streams idênticos sem id, por (user_id,event_ts,event_type). Para ordenação temporal, use event_ts com precisão suficiente e, se necessário, uma coluna sequence_number gerada no produtor.
-- 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 o resultado
Valide que o grain está correcto e que não há duplicados. Exemplos de queries de verificação:
-- 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;
Conclusão
Uma Event Stream fact table permite analisar eventos em detalhe e em escala — a chave é definir o grain, usar dimensões conformed, partição e deduplicação. Próximos passos: criar agregações pré-computadas (materialized views), ajustar retenção e integrar com Power BI ou ferramentas de streaming. Dica: comece por um conjunto reduzido de eventos e monitorize o crescimento da cardinalidade.