🎯 ATIVIDADE 04 — A ARTE DA ORGANIZAÇÃO

📖 Fundamentação Teórica

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_PedClienteEnderecoProdutosValor_Un
1001João SilvaRua A, 10Pneus, Óleo400.00, 50.00
1002Maria SouzaRua B, 20Filtro Ar80.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_PedProduto
1001Pneus
1001Óleo

🛠️ Prática Obrigatória 1: Diagnóstico de Anomalias

Cenário: Analise a PLANILHA_MESTRA da TecProExpress.

  1. Aponte 2 anomalias que ocorrem se deletarmos o pedido 1002.
  2. 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.

  1. Crie tabelas separadas para: CLIENTE, PEDIDO, PRODUTO e ITEM_PEDIDO.
  2. Mova o Endereco para a tabela CLIENTE.
  3. Mova o Valor_Un para a tabela PRODUTO.

🏁 Resultado Esperado (Seed das Tabelas Normalizadas)

Tabela CLIENTE:

idnomeendereco
1João SilvaRua A, 10

Tabela ITEM_PEDIDO:

id_pedid_prodqtd
100150 (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:

  1. Exporte a imagem do diagrama conceitual/lógico normalizado no formato .png.
  2. Salve o arquivo fonte do draw.io no formato .drawio.
  3. Caso tenha escrito scripts SQL adicionais para testes, você pode anexá-los.
  4. Envie ambos os arquivos (Atividade_04_SeuNome.drawio e Atividade_04_SeuNome.png) na tarefa correspondente no Microsoft Teams para validação de integridade física.

💡 Checkpoint de Lógica

Importante

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.