Dados e analytics: do OLTP ao lakehouse
Duas perguntas aparecem em toda empresa: por que o relatório derrubou a produção, e por que o número do meu painel é diferente do seu. As duas têm a mesma causa raiz.
Alguém rodou um relatório pesado no banco da aplicação e a latência do checkout dobrou. Alguém apresentou um número de receita e outra pessoa apresentou outro. As duas situações vêm do mesmo lugar: dado analítico e dado transacional foram tratados como se fossem a mesma coisa.
OLTP e OLAP: dois mundos
OLTP é o banco da aplicação. Muitas transações pequenas, cada uma tocando poucas linhas, escrita e leitura misturadas, latência de milissegundos. Armazenamento por linha, porque você quase sempre quer a linha inteira.
OLAP é o mundo da análise. Poucas consultas, cada uma varrendo milhões de linhas e agregando, e você tolera segundos. Armazenamento por coluna.
Por que colunar muda tudo: se você quer a soma de uma coluna sobre cem milhões de linhas, no formato por linha você lê tudo, inclusive as quarenta colunas que não interessam. No colunar, você lê só aquela coluna.
E como valores da mesma coluna são parecidos, comprimem muito melhor: dez vezes é comum. Menos byte lido é menos tempo e, na nuvem, literalmente menos dinheiro, porque a cobrança é frequentemente por byte processado.
É por isso que rodar relatório no banco da aplicação é ruim de duas formas: é lento, porque o formato é errado; e é perigoso, porque consome o mesmo recurso que atende o cliente pagante.
Os nomes que você vai encontrar: Parquet e ORC como formato de arquivo colunar; DuckDB para análise local, que é surpreendentemente eficiente; ClickHouse para análise em tempo real; BigQuery, Snowflake e Redshift como warehouse gerenciado.
OLTP: o banco da aplicação
- Muitas transações pequenas, poucas linhas cada
- Armazenamento por linha: você quer a linha inteira
- Latência de milissegundos, escrita e leitura misturadas
- Normalizado: cada fato mora num lugar só
OLAP: o mundo da análise
- Poucas consultas varrendo milhões de linhas
- Armazenamento por coluna: lê só a coluna que interessa
- Comprime dez vezes melhor, e na nuvem isso é dinheiro
- Desnormalizado de propósito: esquema estrela
Modelagem: normalizar ou desnormalizar
No OLTP você normaliza. Cada fato mora em um lugar só, e você evita anomalia de atualização. Terceira forma normal resolve quase tudo.
Duas armadilhas frequentes:
Exclusão lógica. Uma coluna deletado parece inofensiva e contamina todas as consultas para sempre. Alguém vai esquecer o filtro, e o bug vai ser sutil.
Guardar valor mutável apenas por referência. O preço do produto mudou, e o pedido de dois anos atrás agora mostra o valor errado. Pedido guarda o preço praticado, sempre. Isso não é desnormalização indevida: é registro histórico.
No OLAP você desnormaliza de propósito. O modelo é o esquema estrela: no centro, a tabela fato, com uma linha por evento, as medidas numéricas e as chaves. Em volta, as dimensões: cliente, produto, tempo, loja, cada uma larga e descritiva.
Funciona porque o analista escreve uma junção simples e o motor otimiza bem. Você troca normalização por velocidade e clareza, e num sistema onde ninguém atualiza linha, a duplicação não gera anomalia.
E o conceito que confunde: dimensão que muda lentamente, ou SCD. O cliente mudou de cidade.
Tipo 1: você sobrescreve e perde a história, e o relatório do ano passado passa a mostrar a cidade nova.
Tipo 2: você cria uma linha nova com data de início e fim, e mantém a história, e o relatório do ano passado continua correto.
Tipo 2 é mais trabalhoso e é o que você quer quando alguém pergunta "quanto vendemos em São Paulo em 2023".
Como o dado chega lá
ETL x ELT. ETL é a ordem clássica: extrai, transforma fora, carrega pronto. Fazia sentido quando o destino era caro e limitado.
ELT inverte: extrai, carrega cru, e transforma dentro do destino usando o poder dele. É o padrão hoje, e a vantagem prática é grande: se a regra de transformação estava errada, você reprocessa a partir do dado cru que já está lá, sem extrair de novo da origem.
Batch x streaming. Batch processa em janelas: de hora em hora, todo dia. Simples, barato, fácil de reprocessar. Streaming processa evento a evento, com latência de segundos, e é muito mais caro em complexidade: evento atrasado, janela de tempo, estado.
A pergunta certa antes de escolher streaming: alguém vai tomar uma decisão diferente por saber disso agora em vez de daqui a uma hora? Na maioria das vezes, não.
CDC (captura de mudança de dados) é como o dado sai do banco transacional hoje. Em vez de "select tudo" toda noite (que é pesado, perde deleções e perde estados intermediários), você lê o log de replicação do próprio banco. Você recebe cada insert, update e delete como um evento.
O cuidado com CDC no Postgres: o slot de replicação. Se o consumidor parar, o banco segura o WAL para ele, e o disco enche. Já derrubou muito banco de produção. Monitore o atraso do slot.
Warehouse, lake e lakehouse
Warehouse: estruturado e governado, com esquema definido na escrita. Ótimo para consumo, rígido para dado novo.
Lake: arquivo cru em armazenamento barato, com esquema na leitura. Flexível, e vira pântano se ninguém governar.
Lakehouse: a síntese. Arquivos abertos no armazenamento barato mais uma camada de metadados (Iceberg, Delta, Hudi) que traz transação, viagem no tempo e evolução de esquema.
Hoje, para começar do zero, é o padrão que eu escolheria.
E a organização em camadas: bronze é o cru, exatamente como chegou, imutável: é a sua rede de segurança para reprocessar. Prata é limpo, tipado, deduplicado. Ouro é agregado e pronto para o negócio.
Parece burocracia até o dia em que uma regra sai errada. Aí ela salva a semana, porque você reprocessa do bronze.
Confiança no dado
O jeito mais comum de um pipeline quebrar não é bug: é alguém no time da aplicação renomear uma coluna sem saber que dez painéis dependiam dela.
Contrato de dados é o acordo explícito entre quem produz e quem consome: esquema, significado de cada campo, garantias de frescor e volume, e o processo de mudança. Com contrato, quebrar vira violação detectável no pipeline do produtor, e não surpresa na sexta.
Teste de dado é diferente de teste de código: você testa o dado que passou, não a função:
→ Esquema: as colunas e tipos estão lá?
→ Volume: o número de linhas de hoje está na faixa esperada?
→ Distribuição: média e nulos parecidos com ontem?
→ Regra de negócio: nada negativo, nada no futuro, chaves batem.
Frescor é a métrica mais importante e a mais esquecida: quando essa tabela foi atualizada pela última vez? Dado velho servido como atual é pior que dado ausente, porque ausente todo mundo percebe.
Idempotência é a propriedade que separa pipeline profissional de artesanal: rodar duas vezes dá o mesmo resultado. A técnica padrão é sobrescrever por partição: em vez de inserir, você reescreve inteira a partição daquele dia. Reprocessar vira trivial, e você vai reprocessar muito mais vezes do que imagina.
Evento, partição e a métrica única
Se você é dev de aplicação, a sua maior contribuição ao time de dados é emitir evento bom: nome no passado (PedidoConfirmado, não ConfirmarPedido), identificador único para deduplicação, o instante em que aconteceu separado do de processamento, versão do esquema, e os dados que descrevem o fato, não referências que vão mudar depois.
E use o padrão outbox, para o evento e a gravação serem atômicos.
Particionamento no lado analítico: os arquivos ficam em pastas por data, e a consulta que filtra por data lê só aquelas pastas. Isso é poda de partição, e é a diferença entre varrer dois gigabytes e dois terabytes, o que na nuvem é a diferença entre centavos e centenas de reais na mesma consulta.
Cuidado com o extremo oposto: particionar por algo de alta cardinalidade gera milhões de arquivos minúsculos, e aí o custo vira abrir arquivo. O alvo é arquivo de algumas centenas de megabytes.
E o problema mais político: qual é a receita do mês? Marketing tem um número, financeiro tem outro. Nenhum está errado. Eles definiram diferente: com ou sem imposto, com ou sem cancelamento, na data do pedido ou do pagamento.
A solução é uma camada semântica: a métrica é definida uma vez, em código, versionada, e todo mundo consome dali. Ferramenta ajuda; o essencial é que alguém seja dono da definição.
Contra o hype
Para a maioria das empresas, a stack certa é: um warehouse gerenciado, dbt para transformação em SQL versionado, um orquestrador simples e um BI. Ponto.
Você não precisa de Kafka, Spark e data mesh para trinta gigabytes de dado. Trinta gigabytes cabem confortavelmente num DuckDB no seu laptop, e respondem em segundos.
Data mesh, especificamente, é um modelo organizacional: domínios sendo donos dos próprios dados como produto. Sem a mudança organizacional, adotar as ferramentas só distribui a bagunça.
Leia depois disto
- IA AplicadaPasso 22IA em produção: RAG, eval e prompt injectionTodo mundo consegue montar uma demo que impressiona. O que separa a demo do produto são três disciplinas, e a maioria dos times não tem nenhuma das três.Ler artigo
- EngenhariaPasso 20Legado: caracterizar, costurar e estrangularTrês técnicas que permitem mexer com segurança num sistema que você não escreveu, não entende, e não pode parar.Ler artigo
- EngenhariaPasso 19Testes que valem o que custamTeste não existe para provar que o código está certo. Existe para você poder mudá-lo amanhã sem medo. Essa mudança de objetivo reorganiza tudo.Ler artigo