🎯Da Normalização de Dados (até a Terceira Forma Normal) ao Modelo Físico no Live SQL

Em modelagem de dados relacionais, o processo de normalização é um tema muito importante para definir a organização dos dados em uma banco de dados, afim de minimizar as dependências indesejadas e reduzir as redundâncias. Garantindo que as tabelas e seus relacionamentos estejam bem estruturado

O principal objetivo é:

  • Redução da redundância: Menos dados repetidos, economizando espaço.
  • Melhora da integridade dos dados: Menos chances de informações inconsistentes.
  • Facilidade de atualização: Alterar uma informação em um só lugar.
  • Maior flexibilidade: Estrutura mais adaptável a mudanças.

🛠️ Testando no Oracle Live SQL

Você pode testar os scripts diretamente no Live SQL:
(Crie uma conta gratuita, cole os scripts e execute.)

🧱 Cenário Inicial: Um modelo não normalizado

Imagine que recebemos a seguinte tabela, contendo dados de notas de alunos em um curso: 


Comando SQL:

--CRIAÇÃO DA TABELA
CREATE TABLE notas_brutas (
    AlunoID         NUMBER,
    NomeAluno       VARCHAR2(100),
    DisciplinaID    NUMBER,
    NomeDisciplina  VARCHAR2(100),
    ProfessorID     NUMBER,
    NomeProfessor   VARCHAR2(100),
    Nota            NUMBER
);

-- INSERÇÃO DOS DADOS

INSERT INTO notas_brutas VALUES (1, 'João', 101, 'Matemática', 201, 'Silva', 8.5);
INSERT INTO notas_brutas VALUES (2, 'Maria', 102, 'História', 202, 'Santos', 7.0);
INSERT INTO notas_brutas VALUES (3, 'Pedro', 103, 'Geografia', 203, 'Oliveira', 9.0);
INSERT INTO notas_brutas VALUES (1, 'João', 102, 'História', 202, 'Santos', 7.8);
INSERT INTO notas_brutas VALUES (2, 'Maria', 103, 'Geografia', 203, 'Oliveira', 6.5);
INSERT INTO notas_brutas VALUES (1, 'João', 104, 'Física', 204, 'Ferreira', 8.0);
INSERT INTO notas_brutas VALUES (4, 'Ana', 101, 'Matemática', 201, 'Silva', 6.0);
INSERT INTO notas_brutas VALUES (5, 'José', 102, 'História', 202, 'Santos', 9.2);
INSERT INTO notas_brutas VALUES (3, 'Pedro', 104, 'Física', 204, 'Ferreira', 7.3);
INSERT INTO notas_brutas VALUES (1, 'João', 105, 'Química', 205, 'Almeida', 8.9);

Essa estrutura pode parecer conveniente em um primeiro momento, mas possuí redundância, anomalias de atualização, inserção e exclusão, além de violação de boas práticas de modelagem relacional.

Problemas Observados:

  • Redundância de dados: Nome do aluno, nome do professor e nome da disciplina se repetem.
  • Dependências indiretas: O nome do professor depende da disciplina, não da nota.
  • Atualizações inconsistentes: Se o nome de um professor mudar, é necessário atualizar em todas as linhas.
  • Falta da chave primaria: Não existe uma chave primária definida.

✅ ETAPA 1 – Aplicando a 1ª Forma Normal (1FN)

Regras da 1FN:

  • Os atributos devem conter valores atômicos (não multivalorados ou compostos).
  • Não pode haver campos repetidos ou grupos de repetição.
  • Toda tabela deve ter uma chave primária.

Problema: falta a chave primária.

Não Está em 1FN.

Considerando que:

  • Um aluno pode cursar várias disciplinas.
  • Uma disciplina pode ser cursada por vários alunos.
  • Mas cada aluno só tem uma nota por disciplina.
Solução: Criação da chave primária composta pelas colunas AlunoID e DisciplinaID.

Comando SQL:
--ADIÇÃO DA CHAVE PRIMARIA
ALTER TABLE notas_brutas ADD CONSTRAINT notas_brutas_pk
PRIMARY KEY(AlunoID,DisciplinaID);

✅ ETAPA 2 – Aplicando a 2ª Forma Normal (2FN)

Regras da 2FN:

  • Deve estar em 1FN.
  • Todos os atributos não-chave devem depender totalmente da chave primária (não parcialmente).

Problema: O campo NomeAluno depende apenas de AlunoID, não do par (AlunoID, DisciplinaID). Já o campo NomeDisciplina e NomeProfessor dependem apenas de DisciplinaID.

Solução: Separar os dados em entidades distintas.

  • Alunos: (AlunoID, NomeAluno).
  • Disciplinas: (DisciplinaID, NomeDisciplina).
  • Professores: (ProfessorID, NomeProfessor).
  • Notas: (AlunoID, DisciplinaID, Nota).

Agora, cada entidade representa uma tabela onde os atributos dependem da chave primária completa.

✅ A estrutura agora está em 2FN.

Comando SQL:

-- Tabela de Alunos
CREATE TABLE alunos (
    AlunoID    NUMBER PRIMARY KEY,
    NomeAluno  VARCHAR2(50)
);

INSERT INTO alunos VALUES (1, 'João');
INSERT INTO alunos VALUES (2, 'Maria');
INSERT INTO alunos VALUES (3, 'Pedro');
INSERT INTO alunos VALUES (4, 'Ana');
INSERT INTO alunos VALUES (5, 'José');

-- Tabela de Professores
CREATE TABLE professores (
    ProfessorID    NUMBER PRIMARY KEY,
    NomeProfessor  VARCHAR2(50)
);

INSERT INTO professores VALUES (201, 'Silva');
INSERT INTO professores VALUES (202, 'Santos');
INSERT INTO professores VALUES (203, 'Oliveira');
INSERT INTO professores VALUES (204, 'Ferreira');
INSERT INTO professores VALUES (205, 'Almeida');

-- Tabela de Disciplinas
CREATE TABLE disciplinas (
    DisciplinaID    NUMBER PRIMARY KEY,
    NomeDisciplina  VARCHAR2(50),
    ProfessorID     NUMBER REFERENCES professores(ProfessorID)
);

INSERT INTO disciplinas VALUES (101, 'Matemática', 201);
INSERT INTO disciplinas VALUES (102, 'História',   202);
INSERT INTO disciplinas VALUES (103, 'Geografia',  203);
INSERT INTO disciplinas VALUES (104, 'Física',     204);
INSERT INTO disciplinas VALUES (105, 'Química',    205);

-- Tabela de Notas (relação Aluno-Disciplina)
CREATE TABLE notas (
    AlunoID      NUMBER REFERENCES alunos(AlunoID),
    DisciplinaID NUMBER REFERENCES disciplinas(DisciplinaID),
    Nota         NUMBER(3,1),
    PRIMARY KEY (AlunoID, DisciplinaID)
);

-- Dados para tabela "notas"
INSERT INTO notas VALUES (1, 101, 8.5);
INSERT INTO notas VALUES (2, 102, 7.0);
INSERT INTO notas VALUES (3, 103, 9.0);
INSERT INTO notas VALUES (1, 102, 7.8);
INSERT INTO notas VALUES (2, 103, 6.5);
INSERT INTO notas VALUES (1, 104, 8.0);
INSERT INTO notas VALUES (4, 101, 6.0);
INSERT INTO notas VALUES (5, 102, 9.2);
INSERT INTO notas VALUES (3, 104, 7.3);
INSERT INTO notas VALUES (1, 105, 8.9);

✅ ETAPA 3 – Aplicando a 3ª Forma Normal (3FN)

Regras da 3FN:

  • Deve estar em 2FN.
  • Nenhum atributo não-chave pode depender transitivamente de atributos não chave.

O NomeProfessor depende de ProfessorID e já esta separado.

Solução: Na estrutura acima, NomeProfessor depende de ProfessorID, que já está separado. Portanto, a estrutura já está em 3FN.

A estrutura está em 3FN.

Após a normalização, caso queira consultar os dados da mesma foram que eram exibidos na tabela sem a normalização, basta fazer um join entre as tabelas notas, alunas, disciplinas e professores.

Comando SQL:

SELECT
    a.aluno_id,
    a.nome AS nome_aluno,
    d.disciplina_id,
    d.nome AS nome_disciplina,
    p.professor_id,
    p.nome AS nome_professor,
    n.nota
FROM notas n
JOIN alunos a ON n.aluno_id = a.aluno_id
JOIN disciplinas d ON n.disciplina_id = d.disciplina_id
JOIN professores p ON d.professor_id = p.professor_id
ORDER BY a.aluno_id, d.disciplina_id;


Comentários