🎯 ATIVIDADE 04 — A ARTE DA ORGANIZAÇÃO
Para realizar este laboratório com sucesso, certifique-se de ter compreendido os conceitos apresentados no:
👉 CAPÍTULO 04: SETUP POLIGLOTA E CONEXÕES
Bem-vindo à quarta semana (4 aulas) do curso de Banco de Dados. Até aqui, você aprendeu a modelar o mundo real. Mas, às vezes, nossa modelagem inicial contém "armadilhas" — dados repetidos que causam erros. Hoje, vamos aprender a técnica de Normalização, o processo de refinamento que separa o bom design do amadorismo. 🛡️🧩
🎯 Objetivos de Aprendizagem do Laboratório
Ao final deste laboratório prático (estimativa: 4 horas presenciais / autoguiadas), você será capaz de:
- Identificar e corrigir Anomalias de Inserção, Exclusão e Alteração.
- Aplicar a 1ª Forma Normal (1FN): Atomicidade.
- Aplicar a 2ª Forma Normal (2FN): Dependência Total.
- Aplicar a 3ª Forma Normal (3FN): Dependência Transitiva.
🏢 O Cenário Prático (Seu Desafio)
A TecProExpress herdou um banco de dados de uma empresa adquirida. Os dados estão em uma única tabela chamada PLANILHA_MESTRA. Quando um cliente muda de endereço, o sistema precisa atualizar centenas de linhas, gerando inconsistências.
📋 Seed: A Planilha "Bagunçada" (Não Normalizada)
| Cod_Ped | Cliente | Endereco | Produtos | Valor_Un |
|---|---|---|---|---|
| 1001 | João Silva | Rua A, 10 | Pneus, Óleo | 400.00, 50.00 |
| 1002 | Maria Souza | Rua B, 20 | Filtro Ar | 80.00 |
🧠 Fundamentos: A Teoria Traduzida
Normalizar é como organizar uma biblioteca por categorias, autores e títulos, em vez de empilhar tudo na entrada.
O Fluxo da Organização
Veja como os dados "evoluem" durante a normalização:
flowchart TD
subgraph Erro ["Estado Crítico"]
A["Tabela Única (Caos)"]
end
subgraph FN1 ["1ª Forma Normal"]
B["Valores Atômicos (Sem listas)"]
end
subgraph FN2 ["2ª Forma Normal"]
C["Chaves Primárias Definidas"]
end
subgraph FN3 ["3ª Forma Normal"]
D["Tabelas Independentes (Padrão Indústria)"]
end
A -->|Dividir listas| B
B -->|Mover campos parciais| C
C -->|Mover campos indiretos| D
style A fill:#ffcdd2
style D fill:#c8e6c9
📖 Exemplo Guiado: Aplicando a 1FN
Problema: A coluna Produtos tem "Pneus, Óleo". O banco de dados não consegue somar o estoque assim.
Solução: Cada produto deve ter sua própria linha.
| Cod_Ped | Produto |
|---|---|
| 1001 | Pneus |
| 1001 | Óleo |
🛠️ Prática Obrigatória 1: Diagnóstico de Anomalias
Cenário: Analise a PLANILHA_MESTRA da TecProExpress.
- Aponte 2 anomalias que ocorrem se deletarmos o pedido 1002.
- Explique por que o endereço do cliente não deve ficar na tabela de pedidos.
🏁 Resultado Esperado (Para sua Referência)
- Anomalia de Exclusão: Ao deletar o pedido, perdemos os dados de contato da Maria Souza.
- Redundância: O endereço se repete em cada pedido do mesmo cliente.
💻 Refatorador de Anomalias de Normalização (1FN a 3FN) em Python
Para comparar a redução de redundância e a eliminação de anomalias de atualização:
# normalizador_3fn.py
planilha_desnormalizada = [
{"pedido": 1001, "cliente": "João Silva", "endereco": "Rua A, 10", "item": "Pneu", "preco": 350.0},
{"pedido": 1001, "cliente": "João Silva", "endereco": "Rua A, 10", "item": "Óleo", "preco": 45.0}
]
# Modelo Normalizado (3FN)
clientes_db = {1: {"nome": "João Silva", "endereco": "Rua A, 10"}}
produtos_db = {50: {"nome": "Pneu", "preco": 350.0}, 51: {"nome": "Óleo", "preco": 45.0}}
itens_pedido_db = [
{"pedido_id": 1001, "cliente_id": 1, "produto_id": 50, "qtd": 2},
{"pedido_id": 1001, "cliente_id": 1, "produto_id": 51, "qtd": 1}
]
print("=" * 65)
print("📐 REFATORAÇÃO DE DADOS EM 3ª FORMA NORMAL - TECPROEXPRESS")
print("=" * 65)
print("🏠 Atualizando endereço de João Silva (Atualiza 1 único registro):")
clientes_db[1]["endereco"] = "Av. Paulista, 2000"
print(f" • Novo Endereço no Banco: {clientes_db[1]['endereco']}")
print("\n🧾 Itens do Pedido #1001 sincronizados automaticamente:")
for item in itens_pedido_db:
cli = clientes_db[item["cliente_id"]]
prod = produtos_db[item["produto_id"]]
print(f" • Item: {prod['nome']:<10} | Qtd: {item['qtd']} | Destinatário: {cli['nome']} ({cli['endereco']})")
print("=" * 65)
🖥️ Saída Esperada no Terminal:
=================================================================
📐 REFATORAÇÃO DE DADOS EM 3ª FORMA NORMAL - TECPROEXPRESS
=================================================================
🏠 Atualizando endereço de João Silva (Atualiza 1 único registro):
• Novo Endereço no Banco: Av. Paulista, 2000
🧾 Itens do Pedido #1001 sincronizados automaticamente:
• Item: Pneu | Qtd: 2 | Destinatário: João Silva (Av. Paulista, 2000)
• Item: Óleo | Qtd: 1 | Destinatário: João Silva (Av. Paulista, 2000)
=================================================================
🌐 Exemplo de Payload JSON Normalizado em 3FN (Swagger /docs)
{
"cliente_id": 1,
"itens": [
{"produto_id": 50, "quantidade": 2},
{"produto_id": 51, "quantidade": 1}
]
}
🛠️ Prática Obrigatória 2: O Esquema 3FN
Cenário: Projete o banco normalizado no draw.io.
- Crie tabelas separadas para:
CLIENTE,PEDIDO,PRODUTOeITEM_PEDIDO. - Mova o
Enderecopara a tabelaCLIENTE. - Mova o
Valor_Unpara a tabelaPRODUTO.
🏁 Resultado Esperado (Seed das Tabelas Normalizadas)
Tabela CLIENTE:
| id | nome | endereco |
|---|---|---|
| 1 | João Silva | Rua A, 10 |
Tabela ITEM_PEDIDO:
| id_ped | id_prod | qtd |
|---|---|---|
| 1001 | 50 (Pneu) | 2 |
🔍 Detalhamento Técnico:
- Atomicidade: Agora cada célula tem apenas um valor.
- Relacionamento: Usamos IDs (FKs) para conectar as tabelas sem repetir nomes ou endereços.
📤 Instruções de Entrega (Microsoft Teams)
Após projetar seu banco de dados normalizado na 3ª Forma Normal:
- Exporte a imagem do diagrama conceitual/lógico normalizado no formato
.png. - Salve o arquivo fonte do draw.io no formato
.drawio. - Caso tenha escrito scripts SQL adicionais para testes, você pode anexá-los.
- Envie ambos os arquivos (
Atividade_04_SeuNome.drawioeAtividade_04_SeuNome.png) na tarefa correspondente no Microsoft Teams para validação de integridade física.
💡 Checkpoint de Lógica
Reflexão Profissional: Um banco normalizado economiza espaço em disco, mas exige mais "JOINS" nas consultas. Na TecProExpress, a prioridade é a Integridade dos Dados. 🧠🛡️
🔥 Desafio de Fixação (Opcional)
Nível: Expert 🏆
Onde você armazenaria o Preço de Venda? Na tabela PRODUTO ou na tabela ITEM_PEDIDO? (Dica: Pense no que acontece se o preço do produto mudar amanhã).
🔑 Gabarito de Código/Fórmulas Completo
Mapeamento 3FN Final:
CLIENTE (id PK, nome, endereco)PRODUTO (id PK, descricao, valor_unitario)PEDIDO (id PK, data, id_cliente FK)ITEM_PEDIDO (id_pedido FK, id_produto FK, quantidade, valor_historia)
SQL de Criação (Gabarito):
CREATE TABLE cliente (
id INT PRIMARY KEY AUTO_INCREMENT,
nome VARCHAR(100),
endereco VARCHAR(200)
);
CREATE TABLE produto (
id INT PRIMARY KEY AUTO_INCREMENT,
descricao VARCHAR(100),
valor_unitario DECIMAL(10,2)
);
CREATE TABLE pedido (
id INT PRIMARY KEY AUTO_INCREMENT,
data DATE,
id_cliente INT,
FOREIGN KEY (id_cliente) REFERENCES cliente(id)
);
CREATE TABLE item_pedido (
id_pedido INT,
id_produto INT,
quantidade INT,
PRIMARY KEY (id_pedido, id_produto),
FOREIGN KEY (id_pedido) REFERENCES pedido(id),
FOREIGN KEY (id_produto) REFERENCES produto(id)
);
🔍 Explicação do Gabarito:
- PRIMARY KEY (id_pedido, id_produto): Garante que um produto não seja inserido duas vezes no mesmo pedido.
- valor_historia: Armazena o preço cobrado no dia, garantindo que relatórios antigos não mudem de valor se o produto encarecer hoje.
📊 Rubrica Formativa de Avaliação
| Critério de Avaliação | Insuficiente (0% - 40%) | Regular (41% - 70%) | Excelente (71% - 100%) |
|---|---|---|---|
| Aplicação das Formas Normais (1FN a 3FN) | Mantém campos multivalorados (1FN) ou dependências parciais/transitivas (2FN/3FN). | Normaliza até a 2FN mas mantém dependências transitivas. | Aplica 1FN, 2FN e 3FN perfeitamente, garantindo eliminação de redundâncias. |
| Preservação de Histórico de Preços | Omite o campo de valor histórico na tabela de itens do pedido. | Cria o campo mas sem entender o conceito de imutabilidade histórica. | Justifica e mapeia o atributo de valor histórico (`valor_historia`) em `ITEM_PEDIDO`. |
| Entrega no GitHub | Entrega fora da pasta `bd-atv-04-normalizacao/`. | Arquivo entregue mas sem o DDL SQL normalizado. | `Atividade_04.md` publicado no GitHub com esquemas 3FN e SQL validado. |