📐 CAPÍTULO 10: NORMALIZAÇÃO (1FN A 3FN)
A Normalização é a "vacina" contra dados ruins. É um processo passo a passo (algoritmo) que aplicamos nas nossas tabelas para eliminar redundâncias (dados repetidos à toa) e prevenir anomalias (erros que acontecem quando tentamos salvar ou apagar algo). 🛡️🧩
🎯 Objetivo Curricular
Compreender o conceito de Dependência Funcional e aplicar, na prática (via DDL), a 1ª, 2ª e 3ª Formas Normais (FN) para decompor tabelas doentes em uma arquitetura saudável.
🏢 O Cenário Prático (Seu Desafio)
O setor comercial da TecProExpress criou uma planilha gigante para controlar Vendas. Nela, eles colocaram o Nome do Cliente, o Nome do Entregador, a Placa do Caminhão e o Valor do Frete — tudo na mesma linha! Quando o Entregador mudava de caminhão, o pessoal tinha que atualizar essa informação em 500 linhas diferentes manualmente, causando um caos no faturamento.
"Seu desafio é pegar esse 'Galinheiro de Dados' não normalizado e aplicar as três regras de ouro da Normalização para quebrá-lo em tabelas menores, perfeitamente integradas e imunes a anomalias."
🧠 Fundamentos: As Anomalias e a Dependência Funcional
Se não normalizarmos, o banco sofrerá três doenças fatais:
- Anomalia de Inserção: Você não consegue cadastrar um Caminhão novo no sistema porque ele ainda não fez nenhuma venda (e a tabela exige os dados da venda na mesma linha).
- Anomalia de Atualização: Você precisa alterar o endereço de um cliente em 500 registros antigos. Se o computador travar no registro 250, o banco ficará inconsistente.
- Anomalia de Exclusão: Se você deletar o registro da única venda que um cliente fez, você acidentalmente deleta o cadastro do cliente inteiro junto!
📊 O Algoritmo de Normalização
flowchart LR
UNF["❌ Tabela Caótica<br/>(A Planilha)"] --> FN1["✅ 1FN:<br/>Atomicidade"]
FN1 --> FN2["✅ 2FN:<br/>Sem Dependência Parcial"]
FN2 --> FN3["✅ 3FN:<br/>Sem Dependência Transitiva"]
🔍 Dependência Funcional: O que é isso?
Dizemos que B depende funcionalmente de A (ou A -> B) quando: se eu te der o valor de A, você consegue descobrir com certeza absoluta qual é o valor de B.
- Exemplo: O
CPFdetermina oNome(Um CPF só tem um dono). Mas oNomenão determina oCPF(Existem muitos "Joões"). A Chave Primária (PK) deve sempre ser o determinador de tudo na tabela!
📖 A Jornada das Formas Normais (DDL na Prática)
Vamos resolver o problema da TecProExpress passo a passo.
1️⃣ Primeira Forma Normal (1FN)
Regra: Todos os atributos devem ser atômicos. Sem "células duplas" ou grupos repetitivos.
- A Violação: O Excel tinha a coluna "Itens do Pedido" com
"Teclado, Mouse, Monitor"dentro da mesma célula. - A Correção (1FN): Quebramos isso. O Pedido vira 3 linhas diferentes.
2️⃣ Segunda Forma Normal (2FN)
Regra: Estar na 1FN + Nenhuma coluna pode depender apenas de metade da Chave Primária Composta.
- A Violação: Imagine que a Chave da nossa tabela seja
(ID_Venda, ID_Produto). A colunaNome_do_Produtosó depende do ID do Produto, ela não quer nem saber qual foi a Venda! Isso é dependência parcial. - A Correção (2FN): Puxamos o Produto para uma tabela separada.
3️⃣ Terceira Forma Normal (3FN)
Regra: Estar na 2FN + Nenhuma coluna "não-chave" pode depender de outra coluna "não-chave" (Dependência Transitiva).
- A Violação: Na tabela de Venda, temos o ID do Cliente, o Nome do Cliente e a Cidade do Cliente. A Cidade depende do Nome, que depende do ID. Se o Cliente não é a Chave Primária da tabela de Vendas, ele não pode morar lá com seus atributos.
- A Correção (3FN): Puxamos o Cliente para sua própria tabela.
🛠️ Prática Obrigatória: Quebrando o Monstro (DDL -> DML)
Cenário: O resultado da 3FN.
Após a sua análise, a planilha gigante virou três tabelas limpas: Cliente, Produto e a associativa Venda.
🚀 Script de Seed (Gabarito da 3FN)
-- PASSO 1: DDL (As Tabelas Bases - Fortes)
CREATE TABLE cliente_norm (
id_cliente INT PRIMARY KEY,
nome VARCHAR(100),
cidade VARCHAR(50)
);
CREATE TABLE produto_norm (
id_produto INT PRIMARY KEY,
descricao VARCHAR(100)
);
-- PASSO 2: DDL (A Tabela Normalizada que liga tudo sem redundância)
CREATE TABLE venda_norm (
id_venda INT PRIMARY KEY,
id_cliente INT, -- A FK apontando para o cliente (Nada de escrever a cidade dele aqui!)
id_produto INT,
FOREIGN KEY (id_cliente) REFERENCES cliente_norm(id_cliente),
FOREIGN KEY (id_produto) REFERENCES produto_norm(id_produto)
);
-- PASSO 3: DML (Carga dos Dados Sem Repetição)
INSERT INTO cliente_norm VALUES (1, 'Maria Silva', 'São Paulo');
INSERT INTO produto_norm VALUES (10, 'Teclado Gamer');
-- Agora registramos 100 vendas sem nunca digitar "São Paulo" de novo!
INSERT INTO venda_norm VALUES (1001, 1, 10);
🔍 Detalhamento do Código:
- Note que a tabela
venda_normé extremamente leve! Ela só guarda os números dos IDs. Se a Maria mudar de 'São Paulo' para 'Rio de Janeiro', você fará oUPDATEem exatamente 1 linha na tabelacliente_norm, e todas as milhares de vendas dela já estarão magicamente atualizadas! Isso é a força da 3FN.
📤 Instruções de Entrega (Microsoft Teams)
Após validar seus códigos práticos e de estudo:
Use o operador e para critérios rigorosos e ou para critérios flexíveis. Salve os arquivos com a extensão .sql (Ex: Atividade_XX_SeuNome.sql ou Atividade_XX_SeuNome.png ou Atividade_XX_SeuNome.drawio
💡 Checkpoint de Lógica
[!IMPORTANT] Reflexão Profissional: Um banco de dados 100% normalizado é sempre a melhor escolha? (Resposta: Para sistemas Transacionais/Operacionais, SIM! Mas em Data Warehouses de Analytics - onde a leitura de relatórios pesados é mais importante que a escrita - às vezes os arquitetos aplicam a Desnormalização propositalmente para evitar muitos cruzamentos de JOINs e acelerar a velocidade do painel). 🧠🛡️