Normalização de Dados

// Garantindo Integridade e Eliminando Redundâncias

A normalização organiza tabelas no nível conceitual (ANSI/SPARC) para eliminar redundâncias, evitar anomalias e garantir integridade (C.J. Date).

Objetivo: Criar esquemas relacionais otimizados, respeitando as Formas Normais (1FN, 2FN, 3FN, BCNF).

Objetivo Descrição Reduzir Redundâncias Evitar dados duplicados em múltiplas tuplas. Eliminar Anomalias Prevenir problemas em inserção, atualização e exclusão. Garantir Integridade Manter consistência via chaves e DFs.
Atividade Prática: Cite um benefício da normalização.

Dependências Funcionais

// Base da Normalização

Uma Dependência Funcional (DF) ocorre quando um atributo (ou conjunto) determina unicamente outro atributo. Ex.: FID → FNAME.

db_design@postgres:~#

-- Tabela: Funcionários
-- FID determina FNAME
CREATE TABLE funcionarios (
  fid SERIAL PRIMARY KEY,
  fname VARCHAR(100)
);
-- DF: FID -> FNAME
      
Atividade Prática: Identifique uma DF em uma tabela de Projetos (JID, JNAME, DATAINICIO).

Anomalias de Dados

// Problemas de Bancos Não Normalizados

Tipos de Anomalias

Anomalia Descrição
Inserção Impossibilidade de inserir dados sem informações completas.
Atualização Atualizar o mesmo dado em múltiplas tuplas.
Exclusão Perda de dados ao excluir uma tupla.
db_design@postgres:~#

-- Tabela não normalizada
CREATE TABLE equipe_funcionarios (
  eid INT,
  ename VARCHAR(100),
  fid INT,
  fname VARCHAR(100),
  PRIMARY KEY (eid, fid)
);
-- Anomalia: Atualizar ENAME exige mudar
-- todas as tuplas com mesmo EID.
      
Atividade Prática: Cite uma anomalia na tabela acima.

Formas Normais: 1FN e 2FN

// Primeiros Passos da Normalização

1ª Forma Normal (1FN)

Todos os atributos devem ser atômicos (valores únicos por célula).

2ª Forma Normal (2FN)

1FN + nenhum atributo não-chave depende parcialmente da chave primária.

db_design@postgres:~#

-- Não 1FN: Habilidades não atômico
CREATE TABLE funcionarios (
  fid SERIAL PRIMARY KEY,
  fname VARCHAR(100),
  habilidades TEXT
);
-- 1FN: Separar habilidades
CREATE TABLE funcionario_habilidades (
  fid INT,
  habilidade VARCHAR(50),
  PRIMARY KEY (fid, habilidade),
  FOREIGN KEY (fid) REFERENCES funcionarios(fid)
);
-- 2FN: Evitar dependência parcial
-- Ex.: EID, FID -> ENAME (parcial)
      
Atividade Prática: Converta a tabela não 1FN acima para 1FN.

Formas Normais: 3FN e BCNF

// Eliminação de Dependências Transitivas

3ª Forma Normal (3FN)

2FN + nenhum atributo não-chave depende transitivamente da chave primária.

BCNF (Boyce-Codd)

Para toda DF X → Y, X é uma superchave.

db_design@postgres:~#

-- Não 3FN: Dependência transitiva
CREATE TABLE projetos (
  jid SERIAL PRIMARY KEY,
  jname VARCHAR(100),
  gerente_id INT,
  gerente_nome VARCHAR(100)
);
-- DF: JID -> GERENTE_ID -> GERENTE_NOME
-- 3FN: Separar gerentes
CREATE TABLE gerentes (
  gerente_id SERIAL PRIMARY KEY,
  gerente_nome VARCHAR(100)
);
CREATE TABLE projetos (
  jid SERIAL PRIMARY KEY,
  jname VARCHAR(100),
  gerente_id INT REFERENCES gerentes(gerente_id)
);
      
Atividade Prática: Identifique uma dependência transitiva na tabela não 3FN acima.

Desnormalização

// Otimização para Leitura

Desnormalização introduz redundância controlada para otimizar consultas (ex.: data warehousing, OLAP), mas pode reintroduzir anomalias.

db_design@postgres:~#

-- Normalizado
CREATE TABLE projetos (
  jid SERIAL PRIMARY KEY,
  jname VARCHAR(100),
  gerente_id INT REFERENCES gerentes
);
CREATE TABLE gerentes (
  gerente_id SERIAL PRIMARY KEY,
  gerente_nome VARCHAR(100)
);
-- Desnormalizado (melhor para leitura)
CREATE TABLE projetos_denorm (
  jid SERIAL PRIMARY KEY,
  jname VARCHAR(100),
  gerente_nome VARCHAR(100)
);
      
Atividade Prática: Cite um motivo para desnormalizar uma tabela.

Exercício: Normalização

// Aplicando Formas Normais

Exercício Prático:
Normalize a tabela abaixo até a 3FN, identificando DFs:
Tabela: equipe_funcionarios
EID, ENAME, FID, FNAME, JID, JNAME
DFs: EID -> ENAME, FID -> FNAME, JID -> JNAME
      
  1. Identifique anomalias.
  2. Liste as DFs.
  3. Converta para 1FN, 2FN e 3FN.
  4. Escreva o DDL final.
db_design@postgres:~#

-- Tabela não normalizada
CREATE TABLE equipe_funcionarios (
  eid INT,
  ename VARCHAR(100),
  fid INT,
  fname VARCHAR(100),
  jid INT,
  jname VARCHAR(100),
  PRIMARY KEY (eid, fid)
);
-- Anomalias:
-- Inserção: Não inserir EID sem FID.
-- Atualização: ENAME duplicado por EID.
-- Exclusão: Perder ENAME ao excluir FID.
      

Desafio Prático

Normalize a tabela abaixo até a 3FN, identificando dependências funcionais e explicando os impactos. Baseie-se no sistema de gestão de projetos e no esquema de Fornecedores/Peças.

Tabela Não Normalizada:
Tabela: cliente_projetos
CID, CNAME, TELEFONES, JID, JNAME
DFs: CID -> CNAME, TELEFONES
     JID -> JNAME
      
  1. Identifique anomalias.
  2. Liste as DFs.
  3. Normalize até 3FN.
  4. Escreva o DDL final.
  5. Explique os impactos da normalização.

Visualização: Antes e Depois

Normalização de Dados: 1FN para 3FN Antes (Não Normalizado - 1FN) Cliente_Projetos CID (PK) JID (PK) CNAME JNAME TELEFONES Processo de Normalização Depois (Normalizado - 3FN) Clientes CID (PK) CNAME Projetos JID (PK) JNAME Cliente_Telefones CID (FK) TELEFONE (PK Composta: CID + TELEFONE) Legenda Chave Primária Chave Estrangeira Atributo Multivalorado
db_design@postgres:~#

-- Tabela não normalizada
CREATE TABLE cliente_projetos (
  cid SERIAL,
  cname VARCHAR(100),
  telefones TEXT,
  jid INT,
  jname VARCHAR(100),
  PRIMARY KEY (cid, jid)
);
-- Anomalias:
-- Inserção: Não inserir CID sem JID.
-- Atualização: JNAME duplicado por JID.
-- Exclusão: Perder CNAME ao excluir JID.
-- DFs: CID -> CNAME, TELEFONES
--       JID -> JNAME
-- Normalização para 3FN
CREATE TABLE clientes (
  cid SERIAL PRIMARY KEY,
  cname VARCHAR(100)
);
CREATE TABLE cliente_telefones (
  cid INT,
  telefone VARCHAR(20),
  PRIMARY KEY (cid, telefone),
  FOREIGN KEY (cid) REFERENCES clientes(cid)
);
CREATE TABLE projetos (
  jid SERIAL PRIMARY KEY,
  jname VARCHAR(100)
);
CREATE TABLE cliente_projetos (
  cid INT REFERENCES clientes(cid),
  jid INT REFERENCES projetos(jid),
  PRIMARY KEY (cid, jid)
);
      

Quiz Interativo

// Teste suas Habilidades de Normalização

Teste de Conhecimento

Responda às perguntas para consolidar o aprendizado sobre normalização.

1. O que é uma Dependência Funcional?

a) Atributo determina outro atributo
b) Tabela associativa
c) Chave estrangeira
d) Atributo multivalorado
Resposta Correta: a) Atributo determina outro atributo. Ex.: FID → FNAME.

2. Qual é a principal característica da 1FN?

a) Atributos atômicos
b) Sem dependências parciais
c) Sem dependências transitivas
d) Superchave em DFs
Resposta Correta: a) Atributos atômicos. Cada célula contém um único valor.

3. O que caracteriza a 2FN?

a) Atributos atômicos
b) Sem dependências parciais
c) Sem dependências transitivas
d) Tabela associativa
Resposta Correta: b) Sem dependências parciais. Atributos não-chave dependem da chave primária completa.

4. O que é necessário para a 3FN?

a) Atributos atômicos
b) Sem dependências parciais
c) Sem dependências transitivas
d) Superchave em DFs
Resposta Correta: c) Sem dependências transitivas. Atributos não-chave não dependem de outros não-chave.

5. Quando usar desnormalização?

a) Eliminar redundâncias
b) Melhorar consultas OLAP
c) Garantir integridade
d) Criar chaves primárias
Resposta Correta: b) Melhorar consultas OLAP. Desnormalização otimiza leitura em data warehouses.
db_quiz_results:~#

RUN normalization_quiz_check;
-- Quiz finalizado. Parabéns!