trilha

System Design/02 - Componentes/Databases2 min

Denormalization

Perguntas-guia
  • Que problema isso resolve?
  • Quando usar / quando NÃO usar?
  • Qual o principal trade-off?
  • Como isso falha em produção?

Conceito

Introduzir redundância deliberada — duplicar dados ou pré-computar agregados — para eliminar junções e acelerar leitura.

normalizado:   pedidos ⋈ clientes ⋈ enderecos     (3 tabelas, 2 junções)
desnormalizado: pedidos (com nome_cliente, cidade) (1 tabela, 0 junções)

Formas comuns

Técnica Exemplo
Coluna duplicada nome_cliente dentro de pedidos
Contador pré-calculado total_comentarios no post
Agregado materializado Total de vendas por dia (Materialized View)
Documento embutido Itens dentro do documento do pedido
Tabela de leitura dedicada CQRS

Trade-offs

O ganho é direto: leitura sem junção, frequentemente uma ordem de grandeza mais rápida — e, num sistema particionado, a diferença entre possível e impossível, já que junções entre shards não existem.

O custo é manter a cópia coerente. Quando o cliente muda de nome, todas as cópias precisam ser atualizadas. Isso pode ser feito por trigger, por evento assíncrono ou por job de reconciliação, e cada opção tem seu modo de falha:

Mecanismo Risco
Trigger no banco Lentidão na escrita; lógica escondida
Evento assíncrono Janela de inconsistência; evento perdido
Job periódico Divergência até a próxima execução

O trade-off honesto é escrita mais cara e mais arriscada em troca de leitura mais barata. Só compensa quando a razão leitura:escrita é alta — e é por isso que a decisão exige medir antes.

Vale também distinguir duplicação de snapshot intencional: guardar o preço do produto dentro do pedido não é desnormalização, é registrar um fato histórico. O preço mudou depois; o pedido deve preservar o que foi cobrado. Confundir os dois leva a "corrigir" dados que estavam certos.

E o alerta prático: desnormalizar cedo demais é otimização prematura que trava a evolução do schema. Normalize primeiro, meça, e desnormalize onde a medição apontar.

Exemplo prático

Uma listagem de posts que precisa exibir o número de comentários. Com COUNT(*) numa tabela de milhões de comentários, cada linha da listagem custa uma varredura.

A desnormalização é uma coluna total_comentarios no post, incrementada a cada comentário. A listagem passa a ler um inteiro.

O que se assume em troca: se um comentário for inserido e o incremento falhar, o contador fica errado — e ninguém percebe até alguém conferir. Por isso contadores desnormalizados costumam vir acompanhados de um job de reconciliação periódico, que recalcula e corrige a deriva.

Relacionado


Parte de Databases · roadmap.sh/system-design

Buscar

Busca por título, seção e texto das notas