?>
1-mysql Básico
Exercícios
?>

Capítulo 5

5-Anomalias e Normalização

Introdução

As tabelas de banco de dados relacional podem sofrer com alguns problemas bastante sérios em termos de desempenho, integridade e facilidade de manutenção.

Por exemplo, quando um banco de dados é definido como uma única e grande tabela, isso pode resultar em uma grande quantidade de dados redundantes e pesquisas demoradas mesmo para pequenas quantidades de linhas.

Uma única tabela pode resultar em atualizações longas e dispendiosas, e as exclusões em particular podem provocar a eliminação de dados úteis como um efeito colateral indesejado.

Essa situação pode ser demonstrada na Figura 1, na qual produtos, vendedores, clientes e pedidos são todos armazenados em uma única tabela, chamada Vendas.



fig1
Figura 1: Exemplo de uma tabela que pode gerar diferentes anomalias na gestão do banco de dados.

Nessa tabela, notamos que certas informações de produto e cliente são armazenadas de forma redundante, desperdiçando espaço de armazenamento.

Outros problemas óbvios (e intuitivos) podem ser percebidos facilmente, antes mesmo de uma análise mais profunda, tais como:

  • Consultas:, tais como "Quais clientes pediram aspiradores de pó no mês passado?" exigiriam uma pesquisa na tabela inteira.

  • Atualizações, tais como ,por exemplo, a alteraração do endereço do cliente Bruno, exigiriam a alterarações de mais de uma linha (obviamente o problema aumenta na medida que temos mais linhas com o mesmo cliente).

  • A exclusão de um pedido de um cliente, por exemplo da Elaine, excluirá a única cópia do seu endereço. Essa informação pode ser difícil (ou às vezes impossível) de ser recuperada.

Um outro exemplo de uma tabela com informações organizadas de forma inadequada (redundantes ou mal organizadas) é dada na Figura 2. Nela, por exemplo, o campo telefone não é único. Outro problema é a repetição desnecessária do número da agência.



fig1
Figura 2: Exemplo de uma tabela com dados multivalorados (telefone), criada de forma inadequada.

Poderíamos pensar que para resolver o problema do telefone não ser único uma solução seria fazer como dado na figura 3. Nela tempos vários campos "fone". Mas isso também não está certo.

Esses e outros problemas nos remetem ao estudo das anomalias dos bancos e da forma de resolvê-las.



fig1
Figura 3: Uma possível solução para o problema multivalorado da tabela da figura 2. Mas essa não é uma boa solução....

Anomalias

(voltar início)

Um banco de dados mal projetado pode sofrer algumas anomalias.

Anomalias são mudanças em dados que podem gerar uma inconsistência no banco de dados relacional.

Podemos ter anomalia de:

  • Anomalia de Inclusão

  • Anomalia de Exclusão

  • Anomalia de Alteração (ou de modificação ou de atualização)

  • A figura 4 apresenta uma tabela que gera anomalias

FIGURA 4
anomalia

Na figura 4 temos uma tabela chamada AgenciaFuncionario que armazena os dados dos funcionários de um banco e também os dados sobre as agências. Como essas duas informações (Funcionário e Agência) são armazenadas na mesma tabela, é possível também saber onde cada funcionário trabalha (agência, endereço, telefone).

Ou seja, à primeira vista, a tabela AgenciaFuncionario parece ser uma ótima opção para reduzir o número de tabelas e aumentar a velocidade do sistema.

Entretanto, tal solução pode gerar várias anomalias.

Anomalia de Inserção

Uma anomalia de inserção acontece quando, ao inserir um dado, este dado pode gerar uma inconsistência no banco de dados. No exemplo da figura 4 para inserir os detalhes (NumAg, Endereço, Tel.) de um novo funcionário, você deve tomar cuidado para usar exatamente os dados já cadastrados por outros funcionários.

Por exemplo, um novo funcionário para a agência 1550 deve usar exatamente o mesmo endereço dos outros dois funcionários que também trabalham nesta agência.

Se isto não for feito, teremos um problema de inconsistência de dados, onde dois funcionários que trabalham na mesma agência possuem endereços diferentes.

Como o banco deixa essa possibilidade dizemos que há um erro de projeto. O certo é termos uma estrutura que garanta que não haja anomalias (no caso, por exemplo, podemos te ruma agência com dois endereços difentes...)

Anomalia de Remoção

Uma anomalia de remoção acontece quando, ao remover um registro, você pode gerar inconsistência no banco de dados.

No exemplo da figura 4, uma anomalia de remoção acontece quando removemos o funcionário de número 05. Neste caso, o objetivo é apenas remover os dados do funcionário e preservar os dados da agência 2051. Entretanto, da forma como a tabela está estruturada, os dados da agência também são removidos.

Anomalia de Atualização

Uma anomalia de atualização acontece quando, ao atualizar um registro, você pode gerar inconsistência no banco de dados.

No exemplo da figura 4, uma anomalia de atualização acontece quando modificamos o endereço da agência 1524.

Neste caso, teremos que atualizar o endereço de todos os funcionários da agência 1524.

Caso contrário, teremos uma inconsistência no banco de dados onde funcionários da mesma agência possuem endereços diferentes.

Observação Importante

Note que todas as anomalias acontecem devido à existência de redundância de informação na tabela AgenciaFuncionario.

Por exemplo, o mesmo endereço de uma agência é armazenado várias vezes quando ele poderia ser armazenado apenas uma vez.

Assim, para evitar as anomalias é preciso evitar a redundância.

A redundância é evitada através da normalização das tabelas.

Normalização

(voltar início)

O processo de normalização foi proposto por E. F. Codd, como uma forma de evitar as anomalias mostradas anteriormente.

Assim, o objetivo da normalização é remover a duplicação de dados e, consequentemente, minimizar a redundância. A remoção da duplicação de dados permite:

  • reduzir o espaço físico necessário para armazenar o banco de dados;

  • melhorar a organização dos dados;

  • reduzir o impacto de mudanças, inserções e remoções nos dados do banco de dados.

O processo de normalização é constituído por um conjunto de formas normais. As formas normais especificam critérios que definem quando uma tabela está bem estruturada ou não.

Como comentado acima, a normalização busca melhorar a organização dos dados e com isso ela:

  • Evita redundância de dados.

  • Evita perdas acidentais de informação.

  • Melhora a dependência entre atributos.

  • Resolve inconsistências no Banco de Dados.

Formas Normais

(voltar início)

Para saber se uma tabela está bem estruturada, você deve verificar se sua estrutura satisfaz todas as formas normais.

O processo de normalização consiste num conjunto de ações que levam uma tabela (ou um conjunto de tabelas) a estar numa determinada forma (denominada "forma normal").

São três formas normais que vamos estudar: Primeira, Segunda e Terceira.

Primeira Forma Normal (1FN)

Uma tabela está na Primeira Forma Normal (1FN) se e somente se todos os atributos contiverem apenas dados atômicos (dados atômicos são ). Ou seja, cada atributo pode ter apenas um valor por registro (tupla).

Valores Atômicos

Chamamos de valor atômico m valor único.

Um valor atômico é também chamado de valor indivisível ou valor "mono-valorado".

Exemplo: CEP, telefone, idade, nome (completo, desde que não seja necessário dividi-lo em alguma outra tabela do BD).

A definição de "indivisível" se refere ao banco de dados. Podemos ter um campo "endereço" que receba um endereço completo, desde que não tenha campos de endereço separados no seu BD (rua, bairro, etc.).

Por exemplo, podemos ter uma tabela aluno, com os seguintes atributos:

aluno (id, nome_completo, cpf, matricula)

Nesse caso, podemos trocar o atributo nome_completo por atributos atômicos, como na tabela abaixo:

aluno(id,nome,nome_meio,sobrenome,cpf,matricula)

(é claro que o "nome_meio" poderá ter mais de um valor, mas nesse caso a busca do banco se preocuparia com o nome e sobrenome apenas).

A figura 5 mostra um exemplo de uma tabela que não está na 1FN. Esta tabela não está na 1FN porque o atributo "Telefones" possui mais de um valor (mais de um número de telefone por registro). Por exemplo, a agência 1524 possui três telefones.

FIGURA 5
1fn

Para adequar uma tabela que não está na 1FN, é necessário realizar os seguintes passos:

  1. criar uma tabela para conter os dados do atributo não atômico;

  2. criar na nova tabela um atributo para conter o atributo não atômico da tabela original;

  3. criar na nova tabela um atributo para conter a chave primária da tabela original;

  4. definir uma chave estrangeira para garantir a relação entre a nova tabela e a tabela original;

  5. definir a chave primária da nova tabela;

  6. remover o atributo não atômico da tabela original.

FIGURA 6
1fn2

A figura 6 mostra o procedimento de normalização realizado para a tabela da figura 5, a partir dos seguintes passos:

  • O primeiro passo é criar uma nova tabela chamada AgenciaTelefone.

  • Depois cria-se na tabela AgenciaTelefone o atributo não atômico da tabela Agencia, no nosso caso, o atributo Telefone.

  • Em seguinda,crie na tabela AgenciaTelefone o atributo chave da tabela Agencia, no nosso caso, o atributo NumAg.

  • Para manter a integridade com a tabela original, você deve definir uma chave estrangeira entre o atributo NumAg da tabela AgenciaTelefone e NumAg da tabela Agencia.

  • Depois você deve definir a chave primária da tabela AgenciaTelefone.

  • No nosso caso, como não podemos ter Agências diferentes com o mesmo telefone, definimos como chave primária da tabela AgenciaTelefone o atributo Telefone.

  • Finalmente, removemos o atributo não atômico da tabela Agencia.


  • Note que o processo de normalização de uma tabela para a 1FN é equivalente ao mapeamento de um atributo multivalorado do modelo ER para o modelo relacional, mostrado anteriormente. Ou seja, se você definir bem seu modelo ER e fizer o mapeamento correto, suas tabelas já estarão na 1FN.


Segunda Forma Normal (2FN)

Uma tabela está na Segunda Forma Normal (2FN) se e somente se ela estiver na 1FN e todos os atributos não chave primária puderem ser obtidos da combinação de todos os atributos que formam a chave primária.

Ou seja, a tabela estará na Segunda Forma Normal 2FN se ela estiver na 1FN e todos os atributos não chave forem totalmente dependentes da chave primária (dependente de toda a chave e não apenas de parte dela).

Na figura 7, a tabela Alocacao armazena as horas trabalhadas por funcionários temporários em determinadas agências de um banco.

A sua chave primária é formada pelos atributos NumEmp e NumAg. Além destes dois atributos, a tabela Alocacao possui mais três atributos que não fazem parte da chave primária. São eles: AgEnd, NomeEmp e horasSem.

Para estar na 2FN todos estes três atributos não chave (AgEnd, NomeEmp e horasSem) devem ser obtidos a partir dos dois atributos chaves (NumEmp e NumAg). Se for possível obter um atributo que não é chave primária através de apenas um dos atributos chave primária, então a tabela não está na 2FN.

FIGURA 7
2fn

Por exemplo, é possível saber o endereço da agência (atributo AgEnd) apenas através do atributo NumAg?

A resposta é sim. O endereço da agência é uma informação intrínseca à agência e pode ser obtido através do atributo NumAg.

Outro exemplo: eu consigo obter o nome do empregado (NomeEmp) através do código do empregado (NumEmp)? Sim, esta informação é intrínseca ao empregado e, através do atributo NumEmp, eu poderia obter seu nome.

Finalmente, eu poderia obter as horas semanais trabalhadas pelo empregado apenas através de seu NumEmp? Não, isso acontece porque as horas semanais de cada empregado dependem da agência onde ele trabalha.

Assim, o atributo horasSem depende dos dois atributos NumEmp e NumAg que compõem a chave primária para ser obtido.

Para concluir o exemplo, temos que a tabela Alocacao mostrada na figura não está na 2FN porque possui pelo menos um atributo que pode ser obtido de apenas um dos atributos que formam a chave primária. Este é o caso do atributo NomeEmp, que pode ser obtido apenas de NumEmp, e um outro exemplo é o caso do atributo AgEnd, que pode ser obtido apenas do atributo NumAg.

O fato de que uma tabela não estar na 2FN pode gerar as anomalias mostradas anteriormente. Por exemplo, para modificar o endereço da agência de número 1550 você teria que modificar dois registros: o segundo e quarto registro na tabela da figura.

Outro Exemplo de 2FN

Depois de aprender como identificar se uma tabela está ou não na 2FN, agora vamos aprender com reestruturar uma tabela de modo que ela fique na 2FN.

Para adequar uma tabela que não está na 2FN, é necessário fazer os seguintes passos:

  1. criar duas novas tabelas para armazenar os dados dos campos redundantes, onde seus valores apresentam repetição de valores;

  2. remover os campos com valores redundantes da tabela original;

  3. criar chaves primárias nas novas tabelas criadas com base na chave primária da tabela original;

  4. criar relações um-para-muitos entre as novas tabelas criadas e a tabela original.

Esses passos são ilustrados na figura 8 utilizando-se o exemplo da tabela Alocacao. A primeira coisa a fazer é criar as tabelas Empregado e Agencia. Estas tabelas irão armazenar os dados intrínsecos de Empregado e Agencia que, na figura anterior, estavam na tabela Alocacao.

FIGURA 8
2

Terceira Forma Normal (3FN)

Uma tabela está na Terceira Forma Normal (3FN) se e somente se ela estiver na 1FN e na 2FN e todos os atributos não chave primária puderem ser obtidos somente através da chave primária.

Ao ler a definição da 3FN você pode estar se perguntando: qual é a diferença entre a 3FN e a 2FN? Bem, para responder a sua pergunta vamos utilizar o exemplo mostrado na figura 9 abaixo.

FIGURA 9
3fn1

Neste exemplo, temos a estrutura da tabela Funcionario, onde a chave primária é o número do funcionário, FuncN.

A tabela funcionário serve para armazenar todos os dados do funcionário (nome, cargo, salário), incluindo a agência onde ele trabalha (NumAg e Endereço).

Note que a tabela Funcionario está na 1FN porque todos os atributos são atômicos e está na 2FN porque todos os atributos não chave primária podem ser obtidos através da chave primária.

No entanto, a tabela Funcionário não está na 3FN porque o atributo Endereço da agência onde o funcionário trabalha pode ser obtido por meio da chave primária FuncN ou por meio do atributo NumAg.

Esta relação de dependência pode ser vista na Figura 10. Veja que na definição da 3FN cada atributo só deve ser obtido única e exclusivamente através da chave primária. Como isso não acontece na tabela Funcionário, onde você pode obter o endereço da agência por meio de FuncN ou NumAg, então tal tabela não está na 3FN. Por exemplo, se você souber apenas do Número da Agência (atributo NumAg), você consegue obter o seu endereço.

FIGURA 10
3fn2

Depois de aprender como identificar se uma tabela está ou não na 3FN, agora vamos aprender como fazer a adequação da tabela. Para adequar uma tabela que não está na 3FN é necessário fazer os seguintes passos:

  1. criar uma tabela para conter os atributos que não podem ser obtidos exclusivamente da chave primária da tabela original;

  2. definir como chave primária da tabela criada o atributo que é capaz de obter os dados não chaves da tabela original;

  3. mover os atributos não chave que não são obtidos exclusivamente pela chave primária da tabela original para a nova tabela;

  4. definir como chave estrangeira o atributo que é capaz de obter os dados não chaves da tabela original.

FIGURA 11
3fn3

Exercícios

Referências

voltar ao início da página