Executando verificação de segurança...
11

Normalização de Banco de Dados

O que é?

A normalização se baseia em dois pilares:

				     Formalização
╭──────────────────────────╮───────────────────────────╮
│          Menos           │          Menos            │
│        Dependência       │        Redundância        │
│         ╱    ╲           │         ╱    ╲            │
│        ╱      ╲          │        ╱      ╲           │
│       ╱        ╲         │       ╱        ╲          │
│      ╱          ╲        │      ╱          ╲         │
│     ╱            ╲       │     ╱            ╲        │
│    ╱              ╲      │    ╱              ╲       │
│   ╱                ╲     │   ╱                ╲      │
│  ╱                  ╲    │  ╱                  ╲     │
│ ╱                    ╲   │ ╱                    ╲    │
│╱                      ╲  │╱                      ╲   │
╰──────────────────────────╯───────────────────────────╯

Ou seja, a normalização de uma base de dados (tabelas) visa deixar o banco menos:

  • redundante => muitas informações iguais
  • dependência => menos dependência entre atributos
    Assim devemos fazer a verificação (ou seja, a normalização) no modelo lógico.

Dependências

As dependências são importantes conceitos que deve ser entendido e se trata daquela musica que o Cirilo canta: "Não existo longe de você";
É a mesma coisa que acontece quando um campo tem dependência em outro

Image description

Dependência Funcional

É dito quando tenho um atributo A e um B, tal que o B depende funcionalmente

Nessa dependência um atributo faz com que todos os outros sejam dependentes dele, por exemplo, em uma dependência funcional (DF) de uma entidade (ou tabela) alunos temos:

Matricula \to Nome
Matricula \to Sexo
Matricula \to Celular

Assim, precisamos saber a matricula para saber os atributos Nome, Sexo e Celular do Aluno

O inverso não funciona, já que sexo, celular e nem nome identifica a matricula do aluno
❗Lembre-se que a Matricula é um identificador que consegue identificar outros atributos

Dependência Funcional Parcial

É quando temos uma chave composta e os atributos tem uma dependência por parte da chave.

Por exemplo, para os dados de médicos:

CRM + SinglaEstado \to Nome, Sexo, EstadoEmissor

Note que a chave composta é: CRM + SiglaEstado. E o campo EstadoEmissor depende parcialmente da chave composta já que só precisa da SiglaEstado

💡 Quando temos apenas uma chave primaria simples, ela não terá dependência funcional parcial

Dependência Funcional Transitiva

É definido como uma dependência de um atributo não chave com outro atributo não chave.

Exemplo de DFT com dados de alunos:

Matricula \to Nome, CodCurso, NomeCurso

Tal que o campo não chave NomeCurso depende diretamente do campo não chave CodCurso
O campo chave neste exemplo é a Matricula


Formas

Existem cinco formas e elas são um conjunto de passos para aplicar nas tabelas (modelo lógico).

💡A 4FN e a 5FN não são usadas muito

Antes de tudo

Vamos praticar com um exemplo de um sistema para uma universidade

Departamento
PKCOD_DEPARTAMENTONUMERO
NOM_DEPARTAMENTOCARACTERE
Professor
PKCOD_PROFESSORNUMERO
NOME_PROFESSORCARACTERE
SOBRENOME_PROFESSORCARACTERE
STATUSBOOLEAN
FKCOD_DEPARTAMENTONUMERO

No campo COD_DEPARTAMENTOdependendo dos requisitos pode ser que um professor faça parte de um ou mais departamento, logo teríamos um atributo multivalorado e esse tipo de atributo não respeita a primeira forma, assim teria que aplicar a 1FN

Turma
PKCOD_TURMANUMERO
PERIODOCARACTERE
NUMERO_ALUNOSNUMERO
DATA_INICIODATA
DATA_FIMDATA
FKCOD_CURSONUMERO

Na turma também temos uma questão dependendo do requisito, podemos ter vários valores para as datas, assim teríamos um campo multivalorado e como bem sabe deveríamos então aplicar a 1FN neste campo, isto se nossa regra de negocio pedisse, mas ela não pede então deixaremos, assim como no campo COD_DEPARTAMENTO

Curso
PKCOD_CURSONUMERO
NOME_CURSOCARACTERE
FKCOD_DEPARTAMENTONUMERO

Em geral tabelas menores costumam já estar na 1FN

Aluno
PKRANUMERO
NOME_ALUNOCARACTERE
SOBRENOME_ALUNOCARACTERE
NOME_RUACARACTERE
NUMERO_RUANUMERO
CEPCARACTERE
STATUSBOOLEAN
FILIACAOCARACTERE
SEXOCARACTERE
CONTATOCARACTERE
CPFCARACTERE
TELEFONECARCTERE
FKCOD_CURSONUMERO
FKCOD_TURMANUMERO

💡 Tabelas maiores tem mais chances de não estarem nas formas normais

Curso_Disciplina
PK,
FK
COD_DISCIPLINANUMERO
PK,
FK
COD_CURSONUMERO
Historico
PKCOD_HISTORICONUMERO
PERIODO_REALIZACAODATA
FKRANUMERO
Disciplina
PK,
FK
COD_DISCIPLINANUMERO
NOME_DISCIPLINACARACTERE
DESCRICAOCARACTERE
NUMERO_ALUNOSNUMERO
CARGA_HORARIANUMERO
FKCOD_DEPARTAMENTONUMERO
Aluno_Disciplina
PK,
FK
RANUMERO
PK,
FK
COD_DISCIPLINANUMERO
Disciplina_Historico
PK,
FK
RANUMERO
PK,
FK
COD_DISCIPLINANUMERO
NOTANUMERO
FREQUENCIANUMERO

Forma 1

🥇 Para estar no 1FN:
Tem que ter um atributo único -> cada tabela deve ter sua PK

Image description

Não aceitamos fragmentados -> não ter campos multivalorados ou compostos e se tiver é só desmembrar os campos
✍️ É como dizia Jack Estripador: Corte sempre em picadinhos
Image description

Para um tabela atingir a primeira forma normal, deve-se seguir as regras:

  • EXISTE uma chave primaria
  • Somente POSSUI valores atômicos (atributos simples)
  • As relações também NÃO possui os atributos multivalorados ou relações aninhadas
    • relações aninhadas são tabela dentro de outras tabelas
  • Relação NÃO possui atributos compostos

Aplicando

Tabela Aluno

Como na tabela Aluno temos o campo FILIACAOque por sua vez é um capo que pode guardar mais de um valor, ou seja, filiação diz de quem você é filho e isso resulta em ter um pai e uma mãe => dois valores (a menos que seja um chiquititas).

  • Logo precisamos desmembrar o campo FILIACAO -> por ele ser um campo multivalorado
  • Assim deixaremos a tabela na 1FN

E temos o mesmo na tabela Aluno no campo CONTATOque pode receber tanto email, ou whatsapp ou outra forma de contato.

No campo TELEFONEacontece o mesmo. Já que teremos o telefone residencial e celular

Assim a nova tabela ficara:

Aluno
PKRANUMERO
NOME_ALUNOCARACTERE
SOBRENOME_ALUNOCARACTERE
NOME_RUACARACTERE
NUMERO_RUANUMERO
CEPCARACTERE
STATUSBOOLEAN
NOME_MAECARACTERE
NOME_PAICARACTERE
SEXOCARACTERE
EMAILCARACTERE
WHATSAPPCARACTERE
CPFCARACTERE
TELEFONE_RESIDENCIALCARCTERE
TELEFONE_CELULARCARCTERE
FKCOD_CURSONUMERO
FKCOD_TURMANUMERO
Tabela Historico

Agora se olharmos para a tabela Historico temos o campo PERIODO_REALIZACAO que se refere a data de inicio e fim, ou seja, um campo com dois valores.

Assim a nova tabela ficara:

  • Tiramos o campo PERIODO_REALIZACAO e adicionamos dois campos:
    • DATA_INICIO
    • DATA_FIM
Historico
PKCOD_HISTORICONUMERO
DATA_INICIODATA
DATA_FIMDATA
FKRANUMERO

Forma 2

🥈 Para estar no 2FN tem que:
Ser dependente do Spotify PK (Chave Primaria) -> caso contrario está fora
Image description

Regras da 2FN:

  • Estar na 1FN
  • Todos os atributos simples são funcionalmente dependentes de todas as partes da chave primaria
  • Não deve existir dependência parcial => ou seja. depende da PK e de outro campo
  • Atributos não dependem de chaves candidatas

Caso isso não estiver sendo atingido devemos fazer então uma nova tabela para os dados.

Um atributo-chave é um que é uma PK (Chave Primaria) ou é a parte de uma Chave Composta

Aplicando

Para aplicar devemos nos perguntar primeiro:

Tal campo, depende da PK?

  • Caso positivo, então ta okay

Image description

  • Caso negativo, é cilada bino

Image description

Exemplo:

Por exemplo na tabela Professor:

  • Podemos nos perguntar -> NOME_PROFESSOR, SOBRENOME_PROFESSOR e STATUS depende de COD_PROFESSOR?
    • Positivo => logo a tabela Professor está na 2FN
Professor
PKCOD_PROFESSORNUMERO
NOME_PROFESSORCARACTERE
SOBRENOME_PROFESSORCARACTERE
STATUSBOOLEAN
FKCOD_DEPARTAMENTONUMERO

Só devemos aplicar essa lógica nos atributos não chave (ou seja. em FK ou PK não aplicamos isso)

Aluno

Os campos Nome da Rua, Numero da Rua e CEP, não pendependem do RA do Alunos, eles não variam mesmo se o RA variar.

Se olharmos para Telefone_Residencial temos um problema, já que se mudar o RA pode ter a caso do telefone não mudar, então seria melhor colocar em outra tabela;

❗ Lembrando que podemos ou não fazer, isto é, o que estamos fazendo é uma convenção: é melhor fazer mas não é obrigatório

Telefone

Para obedecermos a 2FN iremos criar uma tabela para telefones dos alunos e para o tipo de telefone

Telefone_Aluno
PKCOD_TELEFONE_ALUNONUMERO
FKRANUMERO
FKCOD_TIPO_TELEFONENUMERO
NUMERO_TELEFONENUMERO
Tipo_Telefone
PKCOD_TIPO_TELEFONENUMERO
TIPO_TELEFONECARACTERE
Endereço

Como os campos que são do endereço ficam de forma parcialmente dependente do Aluno logo devemos criar uma tabela para o Endereço.

Endereco_Aluno
PKCOD_ENDERECO_ALUNONUMERO
FKRANUMERO
FKCOD_TIPO_LOGRADOURONUMERO
CEPCARACTERE
NUMERO_RUANUMERO
NOME_RUACARACTERE
COMPLEMENTOCARACTERE
Tipo_Logradouro
PKCOD_TIPO_LOGRADOURONUMERO
TIPO_LOGRADOUROCARACTERE

Agora a tabela Aluno ficara assim:

Aluno
PKRANUMERO
NOME_ALUNOCARACTERE
SOBRENOME_ALUNOCARACTERE
STATUSBOOLEAN
NOME_MAECARACTERE
NOME_PAICARACTERE
SEXOCARACTERE
EMAILCARACTERE
WHATSAPPCARACTERE
CPFCARACTERE
FKCOD_CURSONUMERO
FKCOD_TURMANUMERO

Forma 3

🥉 Para estar na 3FN tem que:
A pessoa deve ser dependente do estado (PK) e não de outra pessoa, ou seja não podemos ter atributos comuns que dependem de outros atributos comuns -> caso contrario está fora;
Ou então pense em classes, a classe dos operários devem ser dependentes dos patrões e não podem se juntar -> senão vão para outra tabela
Image description

Regras:

  • Estar na 2FN
  • Não existe dependências transitivas
  • Nenhuma coluna não chave depender de outra coluna que não é uma chave

Caso não obedeça devemos criar uma nova tabela.

Como na 2FN, devemos nos perguntar, mas agora a pergunta muda um pouco já que devemos questionar se um atributo simples é dependente de um outro atributo simples, ou seja:

Por exemplo na tabela Professor:

  • Podemos nos perguntar -> NOME_PROFESSOR é dependente de STATUS?
    • Vemos que não, já que se o status mudar o nome do professor não muda e vice-versa;

No caso, no exemplo ele já está na terceira forma normal. Então não precisa mexer com mais nada.


Referencias

Carregando publicação patrocinada...
3

Interessante que para normalizar um banco de dados temos que aumentar o número de tabelas, ao mesmo tempo que temos que ficar fazendo chamadas entre tabelas, o que ativamente diminui a performance do sistema ao fazer querys.

Mas temos a prática da desnormalização onde aumentamos o número de dados redundantes para agilizar as querys.

Isso significa que temos que fazer tabelas mais feias? Não. Existe um método para desnormalizar muito melhor, as views materializadas existentes em bancos de dados como postgresql ou mysql.