Normalização vs. Desnormalização
Normalização e desnormalização são geralmente apresentadas como opostas, mas elas respondem à mesma questão subjacente a partir de direções diferentes: quanta redundância este esquema deve tolerar.
A normalização remove a redundância para proteger a correção; a desnormalização reintroduz parte dela, de propósito, para tornar leituras específicas mais rápidas.
Esta página explica o raciocínio por trás de ambas, para que o restante das páginas desta seção sobre formas normais, views materializadas e desnormalização intencional sejam lidas como ferramentas em um espectro, em vez de campos concorrentes.
Resumo
- A normalização elimina dados redundantes e duplicados para prevenir contradições; a desnormalização reintroduz redundância controlada para reduzir o trabalho em tempo de leitura.
- Por que Importa: Escolher o ponto errado no espectro para uma determinada tabela produzirá anomalias de atualização (super-desnormalizada) ou custo de
JOINdesnecessário (super-normalizada) em escala de produção. - Conceitos-Chave: forma normal, anomalia de atualização, dependência funcional, view materializada, razão leitura/escrita.
- Quando Usar: Qualquer decisão de design de esquema sobre se um atributo pertence a uma tabela própria ou se deve ser duplicado em uma tabela frequentemente lida.
- Limitações / Trade-offs: A normalização custa
JOINs em tempo de leitura; a desnormalização custa trabalho de consistência em tempo de escrita. - Tópicos Relacionados: dependências funcionais, views materializadas, formato da carga de trabalho de leitura/escrita, design OLTP vs. OLAP.
Fundamentos
Normalização é o processo de organizar colunas e tabelas de forma que cada fato seja armazenado em exatamente um lugar.
É impulsionada por dependências funcionais: se um valor como nome_produto é totalmente determinado por sku, então nome_produto pertence à tabela com chave sku, não copiado em cada linha que referencia esse produto.
As formas normais formais (1NF, 2NF, 3NF e adiante) são pontos de verificação nomeados ao longo deste processo, cada uma fechando uma categoria específica de redundância.
O benefício da normalização é que uma anomalia de atualização se torna estruturalmente impossível: um fato armazenado em um lugar não pode entrar em conflito consigo mesmo.
Desnormalização viola deliberadamente esse princípio armazenando um valor derivado ou duplicado em um lugar onde não era estritamente necessário, em troca de evitar um JOIN em tempo de leitura.
As duas técnicas não são estágios de maturidade, onde a normalização é "correta" e a desnormalização é uma alternativa; elas são um trade-off genuíno entre garantias de correção em tempo de escrita e custo em tempo de leitura.
-- Normalizado: order_items não tem dados de produto duplicados
SELECT oi.order_id, p.name, p.sku
FROM order_items oi
JOIN products p ON p.product_id = oi.product_id;A maioria dos esquemas de produção não é puramente um ou outro; eles normalizam o núcleo do domínio com muitas escritas e desnormalizam um pequeno número de caminhos de leitura específicos e conhecidos como "quentes".
Mecânicas e Interações
A decisão de onde se situar neste espectro deve seguir a razão leitura/escrita real de uma tabela, não uma preferência geral.
Uma tabela escrita uma vez e lida milhares de vezes por escrita é um forte candidato para alguma desnormalização, porque o custo de manter um valor duplicado em sincronia é pago raramente em relação a quantas vezes o atalho compensa.
Uma tabela escrita e lida em taxas semelhantes ganha pouco com a desnormalização, porque o custo de sincronização e o benefício de evitar JOINs se cancelam aproximadamente.
O PostgreSQL oferece uma view materializada como uma forma estruturada de desnormalizar sem abandonar as tabelas normalizadas como fonte de verdade.
CREATE MATERIALIZED VIEW order_totals AS
SELECT order_id, SUM(amount) AS total
FROM order_items
GROUP BY order_id;
-- Atualizada explicitamente, não em cada escrita subjacente
REFRESH MATERIALIZED VIEW order_totals;A view materializada contém uma forma desnormalizada e pré-computada, mas as tabelas normalizadas subjacentes permanecem a fonte de verdade a partir da qual a view é atualizada.
Essa etapa de atualização é o cerne de toda decisão de desnormalização: alguém tem que decidir quão desatualizada a cópia desnormalizada pode ser, e qual mecanismo (um trigger, um job agendado, uma escrita em nível de aplicação) a mantém dentro desse limite.
Uma coluna desnormalizada sem um caminho de atualização definido não é uma otimização de performance, é um bug de correção que se acumula lentamente.
Considerações Avançadas e Aplicações
Em escala, o argumento da razão leitura/escrita se estende à distinção OLTP versus OLAP que molda o design de um sistema inteiro, não apenas uma tabela.
Cargas de trabalho OLTP (muitas transações pequenas, fortes necessidades de consistência) tendem à normalização, porque a correção sob escritas concorrentes é mais importante do que economizar um JOIN em um relatório raro.
Cargas de trabalho OLAP (grandes consultas agregadas sobre dados históricos) tendem à desnormalização, frequentemente em tabelas de fatos e dimensões no estilo de esquema estrela, porque os dados são escritos uma vez por um processo em lote e lidos repetidamente por analistas.
A desnormalização intencional em um sistema OLTP, feita corretamente, é restrita e documentada: uma coluna específica, uma consulta "quente" específica, um mecanismo de consistência específico declarado, em vez de uma política geral de duplicação de dados onde quer que pareça conveniente.
| Abordagem | Força | Fraqueza | Melhor Ajuste |
|---|---|---|---|
| Normalização completa (3NF+) | Sem anomalias de atualização; fonte única de verdade por fato | Caminhos de leitura podem exigir vários JOINs | Tabelas OLTP com escritas frequentes e concorrentes |
| View materializada | Velocidade de leitura desnormalizada com uma fonte de verdade normalizada intacta | Dados podem estar desatualizados entre atualizações | Agregados caros lidos com muito mais frequência do que a origem muda |
| Coluna desnormalizada ad hoc | Leitura mais rápida possível para essa única coluna | Requer um mecanismo de sincronização explícito; fácil de esquecer | Um único caminho "quente" comprovado com um proprietário claro |
| Esquema estrela (fato/dimensão) | Otimizado para grandes varreduras agregadas | Mau ajuste para escritas transacionais de alta concorrência | Cargas de trabalho OLAP e de relatórios |
O modo de falha honesto neste espectro não é escolher a desnormalização, é escolhê-la silenciosamente, sem anotar a tolerância à desatualização ou o mecanismo de atualização em qualquer lugar que um futuro engenheiro possa encontrar.
Equívocos Comuns
- "Desnormalização significa desistir da normalização." A maioria dos sistemas desnormalizados mantém uma fonte de verdade normalizada e deriva uma cópia desnormalizada dela, em vez de abandonar a normalização completamente.
- "3NF é sempre o alvo certo." 3NF é um padrão razoável para tabelas OLTP, mas alguns designs param mais cedo ou vão mais longe (BCNF) dependendo de quais anomalias realmente ameaçam o domínio.
- "Views materializadas estão sempre atualizadas." Uma view materializada reflete apenas o estado em sua última
REFRESH, e o PostgreSQL não a atualiza automaticamente a menos que algo seja agendado ou acionado para fazê-lo. - "JOINs são sempre lentos, então desnormalize proativamente." Um
JOINbem indexado em um esquema normalizado é frequentemente rápido o suficiente, e a desnormalização prematura adiciona risco de sincronização para um problema de performance que pode ainda não existir. - "A desnormalização estilo OLAP funciona bem para tabelas OLTP também." A duplicação estilo esquema estrela é ajustada para dados analíticos pesados em leitura e escritos em lote, e aplicá-la a uma tabela transacional de alta concorrência geralmente apenas realoca anomalias de atualização em vez de evitá-las.
FAQs
Qual é a diferença central entre normalização e desnormalização?
A normalização armazena cada fato em exatamente um lugar para prevenir contradições entre cópias duplicadas.
A desnormalização duplica ou pré-computa dados deliberadamente para evitar o custo de JOIN de remontá-los em tempo de leitura.
Devo sempre normalizar primeiro e desnormalizar depois, se necessário?
Sim, essa é a ordem padrão mais segura: normalize para estabelecer uma fonte de verdade correta, então desnormalize caminhos específicos e comprovadamente "quentes" assim que você tiver evidências de que eles precisam disso.
Desnormalizar especulativamente, antes que um padrão de leitura real exista, adiciona risco sem um benefício correspondente.
O que é uma dependência funcional e por que ela importa aqui?
Uma dependência funcional A -> B significa que o valor de A determina completamente o valor de B.
A normalização usa dependências funcionais para decidir em qual tabela um atributo pertence - se sku determina nome_produto, esse nome pertence ao SKU, não duplicado em cada linha que o referencia.
Como uma view materializada se encaixa nesse trade-off?
Uma view materializada armazena um resultado desnormalizado e pré-computado, enquanto as tabelas normalizadas subjacentes permanecem a fonte de verdade real.
Ela oferece velocidade em tempo de leitura sem descartar a correção em tempo de escrita, ao custo da view estar desatualizada até ser atualizada.
Quão desatualizada uma view materializada pode ficar?
Tão desatualizada quanto o tempo entre as chamadas de REFRESH MATERIALIZED VIEW, já que o PostgreSQL não a atualiza automaticamente em escritas subjacentes.
A janela de desatualização aceitável é uma decisão que a equipe tem que tomar explicitamente, não uma propriedade que o PostgreSQL impõe para você.
A desnormalização é sempre sobre performance?
Nesta seção, sim - a razão para desnormalizar é quase sempre para evitar o custo de JOIN em um caminho específico e frequentemente lido.
Outras razões às vezes citadas, como conveniência, geralmente são um sinal de que a desnormalização não foi deliberada o suficiente.
Como decido se uma tabela deve ser normalizada ou desnormalizada?
Olhe para sua razão de leitura/escrita real: uma tabela lida muito mais vezes do que é escrita é um candidato razoável para alguma desnormalização.
Uma tabela lida e escrita em taxas semelhantes geralmente ganha pouco com isso.
Qual é o maior risco de desnormalizar uma coluna?
Fazer isso sem um mecanismo definido para manter o valor duplicado em sincronia com sua origem.
Uma coluna desnormalizada dessincronizada deriva silenciosamente para dados incorretos ao longo do tempo.
Sistemas OLTP e OLAP usam a mesma estratégia de normalização?
Não - sistemas OLTP geralmente tendem à normalização porque a correção de escrita concorrente é mais importante, enquanto sistemas OLAP tendem à desnormalização, frequentemente em esquemas estrela, porque os dados são escritos em lotes e lidos repetidamente para análise.
3NF é a forma normal mais alta que devo almejar?
3NF remove as categorias de anomalias que importam para a maioria dos esquemas de aplicação, e BCNF fecha um caso de borda mais estreito envolvendo chaves candidatas sobrepostas.
A maioria das equipes tem como alvo 3NF por padrão e recorre a BCNF apenas quando esse caso de borda específico está presente.
Normalização e desnormalização podem coexistir no mesmo esquema?
Sim, e na prática quase sempre o fazem - a maioria dos esquemas de produção normaliza suas tabelas centrais com muitas escritas, enquanto desnormaliza um pequeno número de caminhos de leitura conhecidos e medidos.
Tratar a escolha como abrangendo todo o esquema em vez de por tabela é geralmente um erro.
O que devo verificar antes de desnormalizar uma coluna?
Confirme se a razão leitura/escrita realmente a justifica e anote o mecanismo de atualização ou consistência antes de enviar a alteração.
Uma desnormalização sem um plano de desatualização declarado é um bug esperando para surgir, não uma otimização finalizada.
Relacionados
- Bases da Normalização - exemplos práticos de decomposição e dependência funcional
- 3NF e BCNF - as formas normais formais em detalhe
- Views Materializadas - desnormalização estruturada com um mecanismo de atualização
- Desnormalização Intencional - quando e como quebrar a normalização deliberadamente
- Fundamentos de Modelagem de Dados - o processo de modelagem conceitual para física em que isso se encaixa
- Modelagem de Entidade-Relacionamento - as formas de relacionamento em que a normalização se baseia
Versões da Stack: Esta página foi escrita para PostgreSQL 18.4 (estável 18, manutenção 17).