Upload
letu
View
217
Download
0
Embed Size (px)
Citation preview
Unidade 4 – Dependências funcionais e normalização para bancos de
dados relacionais
Nesta unidade, vamos estudar parte da teoria que foi desenvolvida com o
objetivo de avaliar esquemas relacionais para a qualidade do projeto – ou seja, para
medir formalmente porque um conjunto de agrupamento de atributos em um esquema
de relação é melhor que outro.
Começamos esta unidade discutindo informalmente alguns critérios para
esquema de relação bons e ruins na Seção 4.1. Na Seção 4.2 definimos o conceito de
dependência funcional, uma restrição formal entre os atributos que é a principal
ferramenta para medir formalmente a adequação dos agrupamentos de atributo em
esquemas de relação. Na Seção 4.3 vamos discutir as formas normais e o processo de
normalização usado dependências funcionais. As formas normais sucessivas são
definidas para atender a um conjunto de restrições desejáveis, expressas com
dependências funcionais. O procedimento de normalização consiste em aplicar uma
série de testes às relações para atender a esses requisitos cada vez mais rígidos e
decompor as relações quando necessário.
4.1 Introdução
Nas unidades 1 e 2, apresentamos diversos aspectos do modelo relacional e as
linguagens associadas a ele. Cada esquema de relação consiste em uma série de
atributos, e o esquema de banco de dados relacional consiste em uma série de esquemas
de relação. Até aqui, assumimos que os atributos são agrupados para formar um
esquema de relação usando o bom senso do projetista de banco de dados ou mapeando
um projeto de esquema de banco de dados com base no modelo de dados conceitual,
como o modelo de dados ER. Esses modelos fazem o projetista identificar os tipos de
Esta unidade tem como objetivo:
Definir o conceito de dependência funcional, que é a ferramenta básica para
analisar esquemas de banco de dados relacionais; e descrever o processo de
normalização para obter bons projetos, baseados em esquemas de relação que
reduzem a redundância de dados e as chances dos dados se tornarem
inconsistentes.
.
entidade e de relacionamento e seus respectivos atributos, o que leva a um agrupamento
natural e lógico dos atributos em relações quando os procedimentos de mapeamento
discutidos na Unidade 3 são seguidos. Porém, ainda precisaremos de algum modo
formal de análise para medir por que um agrupamento de atributos em esquemas de
relação é melhor do que outro. Ao discutir o projeto de banco de dados na unidade 3,
não desenvolvemos nenhuma medida de adequação ou boas práticas para medir a
qualidade do projeto, além da intuição do projetista. Nesta unidade vamos discutir parte
da teoria que foi desenvolvida com o objetivo de avaliar esquemas relacionais para a
qualidade do projeto.
Começamos esta unidade discutindo informalmente alguns critérios para
esquemas de relação bons e ruins na Seção 4.2. Na Seção 4.3 definimos o conceito de
dependência funcional, uma restrição formal entre os atributos que é a principal
ferramenta para medir formalmente a adequação dos agrupamentos de atributos em
esquemas de relação. Na Seção 4.4, vamos discutir as formas normais e o processo de
normalização usando dependências funcionais.
4.2 Diretrizes de projetos informais para esquemas de relação
Antes de discutirmos a teoria formal do projeto de banco de dados relacional,
vamos abordar quatro diretrizes informais que podem ser usadas como medidas para
determinar a qualidade de projeto do esquema da relação:
Garantir que a semântica dos atributos seja clara no esquema.
Reduzir a informação redundante nas tuplas.
Reduzir os valores NULL nas tuplas.
Reprovar a possibilidade de gerar tuplas falsas.
Essas medidas nem sempre são independentes uma da outra. Algumas situações
levam a esquemas de relações problemáticas e propusemos diretrizes informais para um
bom projeto relacional. Os problemas que apontamos que podem ser detectados sem
ferramentas de análise adicionais, são os seguintes:
Anomalias que causam trabalho redundante durante a inserção e
modificação em uma relação, e que podem causar perda acidental de
informação durante a exclusão de uma relação.
Desperdício de espaço de armazenamento devido a NULLs e a
dificuldade de realizar seleções, operações de agregação e junções por
causa de valores NULL.
Geração de dados inválidos e falsos durante as junções em relações da
base com atributos correspondentes que possam não representar um
relacionamento apropriado (chave estrangeira, chave primária).
No restante desta unidade, apresentaremos os conceitos formais e a teoria que
pode ser usada para definir os pontos positivos e negativos dos esquemas de relação
individuais com mais precisão. Primeiro, discutimos a dependência funcional como uma
ferramenta para análise. Depois, especificaremos as três formas normais para esquemas
de relação. A estratégia para alcançar um bom projeto é decompor de maneira correta
uma relação mal projetada.
4.3 Dependência funcional
Até aqui, lidamos com as medidas informais do projeto de banco de dados.
Agora, vamos introduzir uma ferramenta formal para a análise de esquemas relacionais,
que nos permite detectar e descrever alguns dos problemas mencionados em termos
precisos. O conceito isolado mais importante na teoria de projeto de esquema relacional
é o de uma dependência funcional. Nesta seção definimos formalmente o conceito e na
Seção 4.4, veremos como ele pode ser usado para definir formas normais para esquemas
de relação.
4.3.1 Definição de Dependência Funcional
Segundo Elmasri e Navathe (2011), uma dependência funcional é uma restrição
entre dois conjuntos de atributos do banco de dados. Suponha que nosso esquema de
banco de dados relacional tenha n atributos A1, A2, ... , An. Vamos pensar no banco de
dados inteiro sendo descrito por um único esquema de relação universal R = {A1, A2, ...
, An}. Não queremos dizer que realmente armazenaremos o banco de dados como uma
única tabela universal – usamos esse conceito apenas no desenvolvimento da teoria
formal das dependências de dados1.
1 Essa suposição implica que cada atributo no banco de dados tenha um nome distinto.
Definição. Uma dependência funcional, indicada por X → Y, entre dois
conjuntos de atributos X e Y, que são subconjuntos de R, especifica uma restrição
sobre possíveis tuplas que podem formar um estado da relação r de R. A
restrição é que, para quaisquer duas tuplas t1 e t2 em r que tenham t1[X] = t2[X],
elas também devem ter de ter t1[Y] = t2[Y].
Isso significa que os valores do componente Y de uma tupla em r dependem dos
(ou são determinados pelos) valores do componente X; como alternativa, os valores do
componente X de uma tupla determinam exclusivamente (ou funcionalmente) os
valores do componente Y. Também dizemos que existe uma dependência funcional de X
para Y ou que Y é funcionalmente dependente de X. A abreviação para a dependência
funcional é DF ou d.f. O conjunto de atributos X é chamado de lado esquerdo da DF, e
Y é chamado de lado direito.
Assim, a funcionalidade X determina Y em um esquema de relação R se, e
somente se, sempre que duas tuplas de r(R) combinarem sobre seu valor X, elas devem
necessariamente combinar sobre seu valor Y. Observe o seguinte:
Se uma restrição sobre R declarar que não pode haver mais de uma tupla
com determinado valor X em qualquer instância de relação r(R) – ou seja, X
é uma chave candidata de R –, isso implica que X → Y (porque a restrição
de chave implica que duas tuplas em qualquer estado válido r(R) não terão o
mesmo valor de X). Se X for uma chave candidata de R, então X → R.
Se X → Y em R, isso não quer dizer que Y → X em R.
Uma dependência funcional é uma propriedade da semântica ou significado dos
atributos. Os projetistas de banco de dados usarão seu conhecimento da semântica dos
atributos de R – ou seja, como eles se relacionam entre si – para especificar as
dependências funcionais que devem ser mantidas em todos os estados da relação
(extensões) de r de R. Toda vez que a semântica de dois conjuntos de atributos em R
indicar que uma dependência funcional deveria ser mantida, especificamos a
dependência como uma restrição. As extensões de relação r(R) que satisfazem as
restrições de dependência funcional são chamadas de estados de relação válidos (ou
extensões válidas) de R. Logo, o uso principal das dependências funcionais é para
descrever melhor um esquema de relação R ao especificar restrições sobre seus atributos
que devem ser mantidas o tempo todo. Certas DFs podem ser especificadas sem que se
refiram a uma relação específica, mas como uma propriedade desses atributos, dado o
seu significado comumente entendido. Por exemplo, {Estado, Num_habilitacao} → Cpf
deve ser mantido para qualquer adulto no Brasil, e, por isso, ser mantido sempre que
esses atributos aparecerem em uma relação. Também é possível que certas dependências
funcionais possam deixar de existir no mundo real se o relacionamento mudar. Por
exemplo, a DF Cep → Cod_area costumava existir como um relacionamento entre os
códigos postais e os códigos de área de telefone no Brasil, mas, com a proliferação dos
códigos de área telefônicos, isso não é mais verdadeiro.
CLIENTE_CONTA
Cpf Numero_conta Data_inicio Nome Saldo Tipo_conta
DF1
DF2
DF3
Figura 35 – Um esquema de relação sofrendo anomalias de atualização.
A Figura 35 apresenta uma notação diagramática para exibir DFs: cada DF
aparece como uma linha horizontal. Os atributos do lado esquerdo da DF são
conectados por linhas verticais à linha que representa a DF, enquanto os atributos do
lado direito são conectados pelas linhas com setas que apontam para os atributos.
Considere o esquema de relação CLIENTE_CONTA da Figura 35. Pela semântica
dos atributos e da relação, sabemos que as seguintes dependências funcionais devem ser
mantidas:
a. Cpf → Nome
b. Numero_conta → {Saldo, Tipo_conta}
c. {Cpf, Numero_conta}→ Data_inicio
Essas dependências funcionais especificam que (a) o valor do número do
Cadastro de Pessoa Física (Cpf) de um cliente determina, exclusivamente, o nome do
cliente (Nome), (b) o valor do número de uma conta (Numero_conta) determina,
exclusivamente, o saldo da conta (Saldo) e seu tipo (Tipo_conta) e (c) uma combinação
de valores de Cpf e Numero_conta determina exclusivamente a data que o cliente
tornou-se proprietário da conta (Data_inicio). Como alternativa, dizemos que Nome é
determinado de maneira funcional por (ou dependente funcionalmente de) Cpf, ou dado
um valor de Cpf, sabemos o valor de Nome, e assim por diante.
Uma dependência funcional é uma propriedade do esquema de relação R, e não
um estado de relação válido e específico r de R. Portanto, uma DF não pode ser
deduzida automaticamente por determinada extensão de relação r, mas deve ser definida
de maneira explícita por alguém que conhece a semântica dos atributos de R. Por
exemplo, a Figura 36 mostra um estado em particular do esquema de relação
BANCO_AGENCIA. Embora à primeira vista possamos pensar que Endereco → Agencia,
não podemos confirmar isso a menos que saibamos que é verdadeiro para todos os
estados legais possíveis de BANCO_AGENCIA. É, no entanto, suficiente demonstrar um
único contraexemplo para refutar uma dependência funcional. Por exemplo, como
‘Banco do Brasil’ possui tanto ‘4336’ e ‘3153’, podemos concluir que o Nome_banco
não determina funcionalmente o Numero_agencia.
BANCO_AGENCIA
Nome_banco Numero_agencia Endereco
Banco do Brasil 4336 Av. Weimar G. Torres, 2965
Banco do Brasil 3153 Av. Marcelino Pires, 1960
Itaú 464 Av. Marcelino Pires, 2830
Bradesco 3676 Rua Joaquim Teixeira Alves, 1750
Figura 36 – Um estado de relação de BANCO_AGENCIA com uma possível dependência funcional
Endereco → Numero_agencia. Porém, Nome_banco → Numero_agencia está excluída.
Dada uma relação preenchida, não se podem determinar quais DFs são mantidas
e quais não são, a menos que o significado e os relacionamentos entre os atributos sejam
conhecidos. Tudo o que se pode dizer é que certa DF pode existir se for mantida nessa
extensão em particular. Não se pode garantir sua existência até que o significado dos
atributos correspondentes seja claramente compreendido. Porém, pode-se afirmar de
modo enfático que certa DF não se mantém se houver tuplas que mostrem a violação de
tal DF. Veja a relação de exemplo ilustrativa na Figura 37. Nela, as DFs a seguir podem
ser mantidas porque as quatro tuplas na extensão atual não têm violação dessas
restrições: B → C; C → B; {A, B} → C; {A, B} → D; e {C, D} → B. No entanto, as
seguintes não se mantêm porque já temos violações delas na extensão dada: A → B
(tuplas 1 e 2 violam essa restrição); B → A (tuplas 2 e 3 violam essa restrição); D → C
(tuplas 3 e 4 a violam).
A B C D a1 b1 c1 d1
a1 b2 c2 d2
a2 b2 c2 d3
a3 b3 c4 d3
Figura 37 – Uma relação R (A, B, C, D) com sua extensão.
Indicamos com F o conjunto de dependências funcionais que são especificadas
no esquema de relação R. Em geral, o projetista do esquema especifica as dependências
funcionais que são semanticamente óbvias. Porém diversas outras dependências
funcionais se mantêm em todas as instâncias de relação válidas entre conjuntos de
atributos que podem ser derivados das (e satisfazem as) dependências em F. Essas
outras dependências podem ser deduzidas das DFs em F.
4.4 Formas normais e normalização de relações
Após introduzir as dependências funcionais, agora estamos pronto para usá-las
na especificação de alguns aspectos da semântica dos esquemas da relação.
Consideramos que um conjunto de dependências funcionais é dado para cada relação, e
que cada relação tem uma chave primária designada. Essa informação combinada com
os testes (condições) para formas normais controla o processo de normalização para o
projeto do esquema relacional. A maioria dos projetos relacionais práticos assume uma
das duas técnicas a seguir:
Realiza um projeto de esquema conceitual usando um modelo conceitual
como ER e mapeia o projeto conceitual para um conjunto de relações.
Projeta as relações com base no conhecimento externo derivado de uma
implementação existente de arquivos, formulários ou relatórios.
Ao seguir uma dessas técnicas, é útil avaliar a virtude de relações e decompô-las
ainda mais, conforme a necessidade, para obter formas normais mais altas, usando a
teoria de normalização apresentada nesta unidade. Nesta seção focalizaremos as três
primeiras formas normais para esquemas de relação e a intuição por trás delas, e
discutimos como elas foram desenvolvidas historicamente.
Começaremos discutindo informalmente as formas normais e a motivação por
trás de seu desenvolvimento, bem como revisando algumas definições da Unidade 1,
que são necessárias aqui. Depois discutimos a primeira forma normal (1FN) na Seção
4.4.2, e apresentamos as definições da segunda forma normal (2FN) e terceira forma
normal (3FN), que são baseadas em chaves primárias, nas seções 4.4.3 e 4.4.4,
respectivamente.
4.4.1 Normalização de relações
O processo de normalização, proposto inicialmente por Codd (1972), leva um
esquema de relação por uma série de testes para certificar se ele satisfaz certa forma
normal. O processo, que prossegue em um padrão de cima para baixo, avaliando cada
relação em comparação com os critérios para as formas normais e decompondo as
relações conforme a necessidade, pode assim ser considerado projeto relacional por
análise. Inicialmente, Codd propôs três formas normais, que ele chamou de primeira,
segunda e terceira forma normal. Uma definição mais forte da 3FN – chamada forma
normal Boyce-Codd (FNBC) – foi proposta posteriormente por Boyce e Codd. Todas
essas formas normais estão baseadas em uma única ferramenta analítica: as
dependências funcionais entre os atributos de uma relação. Depois, uma quarta forma
normal (4FN) e uma quinta forma normal (5FN) foram propostas, com base nos
conceitos de dependências multivaloradas e dependências de junção, respectivamente.
A normalização de dados pode ser considerada um processo de analisar os
esquemas de relação dados com base em suas DFs e chaves primárias para conseguir as
propriedades desejadas de (1) minimização de redundância e (2) minimização de
anomalias de inserção, exclusão e atualização, discutidas na Seção 4.2. Esse pode ser
considerado um processo de ‘filtragem’ ou ‘purificação’ para fazer que o projeto tenha
uma qualidade cada vez melhor. Esquemas de relação insatisfatórios, que não atendem a
certas condições – os testes de forma normal –, são decompostos em esquemas de
relação menores, que atendem aos testes e, portanto, possuem as propriedades
desejáveis. Assim, o procedimento de normalização oferece aos projetistas de banco de
dados o seguinte:
Uma estrutura formal para analisar esquemas de relação com base em suas
chaves e nas dependências funcionais entre seus atributos.
Uma série de testes de forma normal que podem ser executados em
esquemas de relação individuais, de modo que o banco de dados relacional
possa ser normalizado para qualquer grau desejado.
Definição. A forma normal de uma relação refere-se à condição de forma
normal mais alta a que ela atende e, portanto, indica o grau ao qual ela foi
normalizada.
As formas normais, quando consideradas isoladamente de outros fatores, não
garantem um bom projeto de banco de dados. Em geral, não é suficiente verificar em
separado se cada esquema de relação do banco de dados está, digamos, na FNBC ou
3FN. Em vez disso, o processo de normalização pela decomposição também precisa
confirmar a existência de propriedades adicionais que os esquemas relacionais, tomados
juntos, devem possuir. Estas incluiriam duas propriedades:
1. A propriedade de junção não aditiva ou junção sem perdas, que garante
que o problema de geração de tuplas falsas, discutido na Seção 4.2, não
ocorra com relação aos esquemas de relação criados após a decomposição.
2. A propriedade de preservação de dependência, que garante que cada
dependência funcional seja representada em alguma relação individual
resultante após a decomposição.
A propriedade da junção não aditiva é extremamente crítica e deve ser
alcançada a todo custo, ao passo que a propriedade de preservação da dependência,
embora desejável, às vezes é sacrificada.
A maioria dos projetos práticos adquire projetos existentes de bancos de dados
anteriores, projetos em modelos legados ou arquivos existentes. A normalização é
executada na prática, de modo que os projetos resultantes sejam de alta qualidade e
atendam às propriedades desejáveis indicadas anteriormente. Embora várias formas
normais mais altas tenham sido definidas, como a 4FN e a 5FN, a utilidade prática
dessas formas normais torna-se questionável quando as restrições sobre as quais elas
estão baseadas são raras, ou difíceis de entender ou detectar pelos projetistas e usuários
de banco de dados que precisam descobrir essas restrições. Assim, o projeto de banco de
dados praticado na indústria hoje presta atenção particular à normalização apenas até a
3FN, FNBC ou, no máximo, 4FN.
Outro ponto que merece ser observado é que os projetistas de banco de dados
não precisam normalizar para a forma normal mais alta possível. As relações podem ser
deixadas em um estado de normalização inferior, como 2FN, por questões de
desempenho. Fazer isso gera as penalidades correspondentes de lidar com as anomalias.
Definição. Desnormalização é o processo de armazenar a junção de relações na
forma normal mais alta como uma relação da base, que está em uma forma
normal mais baixa.
Antes de prosseguirmos, vejamos novamente as definições de chaves de um
esquema de relação, da Unidade 1.
Definição. Uma superchave de um esquema de relação R = {A1, A2,..., An} é um
conjunto de atributos S C R com a propriedade de que duas tuplas t1 e t2, em
qualquer estado de relação válido r de R, não terão t1[S] = t2[S]. Uma chave Ch é
uma superchave com a propriedade adicional de que a remoção de qualquer
atributo de Ch fará que Ch não seja mais uma superchave.
A diferença entre uma chave e uma superchave é que a primeira precisa ser
mínima; ou seja, se tivermos uma chave Ch = { A1, A2,..., An} de R, então Ch = {Ai} não
é uma chave de R para qualquer Ai, 1 ≤ i ≤ k. Na Figura 38, {Cpf} é uma chave para
CLIENTE, enquanto {Cpf}, {Cpf, Nome}, {Cpf, Nome, Sexo} e qualquer conjunto de
atributos que inclua Cpf são todos superchaves.
BANCO
Codigo Nome
CLIENTE
Cpf Nome Sexo Endereco
CONTA
Numero_conta Saldo Tipo_Conta
AGENCIA
Cod_banco Numero_agencia Endereco
HISTORICO
Cpf_cliente Num_conta Data_inicio
TELEFONE_CLIENTE
Cpf_cli Telefone_cli
Figura 38 – Um esquema de banco de dados relacional BANCO.
Se um esquema de relação tiver mais de uma chave, cada uma delas é chamada
chave candidata. Uma das chaves candidatas é arbitrariamente designada para ser
chave primária, e as outras são chamadas de chaves secundárias. Em um banco de
dados relacional prático, cada esquema de relação precisa ter uma chave primária. Na
Figura 38, {Cpf} é a única chave candidata para CLIENTE, de modo que também é a
chave primária.
Definição. Um atributo do esquema de relação R é chamado de atributo
principal de R se ele for um membro de alguma chave candidata de R. Um
atributo é chamado não principal se não for um atributo principal – ou seja, se
não for um membro de qualquer chave candidata.
Na Figura 38, tanto Cpf_cliente quanto Num_conta são atributos principais de
HISTORICO, ao passo que outros atributos de HISTORICO não são principais.
Agora, vamos apresentar as três primeiras formas normais: 1FN, 2FN e 3FN.
Elas foram propostas por Codd (1972) como uma sequência para conseguir o estado
desejável de relações 3FN ao prosseguir pelos estados intermediários de 1FN e 2FN, se
necessário. Conforme veremos, 2FN e 3FN atacam diferentes problemas. Logo, por
definição, uma relação 3FN já satisfaz a 2FN.
4.4.2 Primeira forma normal
A primeira forma normal (1FN) agora é considerada parte da definição formal
de uma relação no modelo relacional básico (plano). Historicamente, ela foi definida
para reprovar atributos multivalorados, atributos compostos e suas combinações. Ela
afirma que o domínio de um atributo deve incluir apenas valores atômicos (simples,
indivisíveis) e que o valor de qualquer atributo em uma tupla deve ser um único valor
do domínio desse atributo. Logo, 1FN reprova ter um conjunto de valores, uma tupla de
valores, ou uma combinação de ambos como um valor de atributo para uma única tupla.
Em outras palavras, a 1FN reprova relações dentro de relações ou relações como
valores de atributo dentro de tuplas. Os únicos valores de atributos permitidos pela 1FN
são valores atômicos (ou indivisíveis).
Considere o esquema de relação CLIENTE da Figura 38, cuja chave primária é
Cpf, e suponha que a estendamos ao incluir o atributo Telefone, conforme mostra a
Figura 39(a). Supomos que cada cliente possa ter certo número de telefones. O esquema
CLIENTE e um exemplo de estado de relação são mostrados na Figura 39. Como
podemos ver, esta não está em 1FN porque Telefone não é um atributo atômico,
conforme ilustrado pela primeira tupla na Figura 39(b). Existem duas maneiras
possíveis para examinar o atributo Telefone:
O domínio de Telefone contém valores atômicos, mas algumas tuplas podem
ter um conjunto desses valores. Nesse caso, Telefone não é funcionalmente
dependente da chave primária Cpf.
O domínio de Telefone contém conjuntos de valores e, portanto, não é
atômico. Nesse caso, Cpf → Telefone, pois cada conjunto é considerado um
único membro do domínio de atributo.2
CLIENTE
Cpf Nome Sexo Endereço Telefone
CLIENTE
Cpf Nome Sexo Endereço Telefone
444.555.666-77 João B Silva M Rua Arapongas, 1234 (67)3421-1122,
(67)3910-3344,
(67)9999-5566
999.666.111-88 Robson Soares M Rua dos Ingleses, 3245 (67)3427-2255
111.222.333-44 Jennifer B Souza F Rua Cuiabá, 1050 (67)3422-7788
CLIENTE
Cpf Nome Sexo Endereço Telefone
444.555.666-77 João B Silva M Rua Arapongas, 1234 (67)3421-1122
444.555.666-77 João B Silva M Rua Arapongas, 1234 (67)3910-3344
444.555.666-77 João B Silva M Rua Arapongas, 1234 (67)9999-5566
999.666.111-88 Robson Soares M Rua dos Ingleses, 3245 (67)3427-2255
111.222.333-44 Jennifer B Souza F Rua Cuiabá, 1050 (67)3422-7788
Figura 39 – Normalização na 1FN. (a) um esquema de relação que não está em 1FN. (b) Exemplo de
estado da relação CLIENTE. (c) Versão 1FN da mesma relação com redundância.
De qualquer forma, a relação CLIENTE da Figura 39 não está na 1FN; de fato, ela
nem sequer se qualifica como uma relação, de acordo com nossa definição na Unidade
1. Existem três técnicas principais para conseguir a primeira forma normal para tal
relação:
1. Remover o atributo Telefone que viola a 1FN e colocá-lo em uma relação
separada TELEFONE_CLIENTE, junto com a chave primária Cpf de CLIENTE. A
chave primária dessa relação é a combinação {Cpf, Telefone}, como mostra
a Figura 40. Existe uma tupla distinta em TELEFONE_CLIENTE para cada
2 Nesse caso, podemos considerar o domínio de Telefone como sendo o conjunto de potência do
conjunto de telefones isolados; ou seja, o domínio é composto por todos os subconjutos possíveis do
conjunto de telefones isolados.
(a)
(b)
(c)
telefone de um cliente. Isso decompõem a relação não 1FN em duas relações
1FN.
TELEFONE_CLIENTE
Cpf Telefone
444.555.666-77 (67)3421-1122
444.555.666-77 (67)3910-3344
444.555.666-77 (67)9999-5566
999.666.111-88 (67)3427-2255
111.222.333-44 (67)3422-7788
Figura 40 – Normalização na 1FN.
2. Expandir a chave de modo que haverá uma tupla separada na relação original
CLIENTE para cada telefone de um CLIENTE, como mostra a Figura 39(c).
Nesse caso, a chave primária torna-se a combinação {Cpf, Telefone}. Essa
solução tem a desvantagem de introduzir a redundância na relação.
3. Se o número máximo de valores for conhecido para o atributo – por
exemplo, se for conhecido que no máximo três telefones poderão existir para
um cliente –, substituir o atributo Telefone pelos três atributos atômicos:
Telefone1, Telefone2 e Telefone3. Essa solução tem a desvantagem de
introduzir valores NULL se a maioria dos clientes tiver menos de três
telefones. Ela ainda introduz uma falsa semântica sobre a ordenação entre os
valores de telefones, que não era intencionado originalmente. A consulta
sobre esse atributo torna-se mais difícil. Por exemplo, considere como você
escreveria a consulta: Listar os clientes que têm ‘(67)3421-1122’ como um
de seus telefones nessa agência.
Das três soluções anteriores, a primeira geralmente é considerada a melhor, pois
não sofre redundância e é completamente genérica, não tendo limite imposto sobre o
número máximo de valores. De fato, se escolhermos a segunda solução, ela será
decomposta ainda mais durante as etapas de normalização subsequentes para a primeira
solução.
4.4.3 Segunda forma normal
A segunda forma normal (2FN) é baseada no conceito de dependência
funcional total. Uma dependência funcional X → Y é uma dependência funcional total
se a remoção de qualquer atributo A de X significar que a dependência não se mantém
mais; ou seja, para qualquer atributo A ɛ X, (X - {A}) não determina Y funcionalmente.
Uma dependência funcional X → Y é uma dependência parcial se algum atributo A ɛ X
puder ser removido de X e a dependência ainda se mantiver; ou seja, para algum A ɛ X,
(X – {A}) → Y. Na Figura 35, {Cpf, Numero_conta} → Data_inicio é uma dependência
total (nem Cpf → Data_inicio nem Numero_conta → Data_inicio se mantêm). Contudo,
a dependência {Cpf, Numero_conta} → Nome é parcial porque Cpf → Nome se
mantém.
Definição. Um esquema de relação R está em 2FN se cada atributo não principal
A em R for total e funcionalmente dependente da chave primária de R.
O teste para 2FN envolve testar as dependências funcionais cujos atributos do
lado esquerdo fazem parte da chave primária. Se a chave primária tiver um único
atributo, o teste não precisa ser aplicado. A relação CLIENTE_CONTA, na Figura 35 está
na 1FN, mas não está na 2FN. O atributo não principal Nome viola a 2FN por causa da
DF2, assim como os atributos não principais Saldo e Tipo_conta, por causa da DF3. As
dependências funcionais DF2 e DF3 tornam Nome, Saldo e Tipo_conta parcialmente
dependentes da chave primária {Cpf, Numero_conta } de CLIENTE_CONTA, violando,
assim, o teste da 2FN.
Se um esquema de relação não estiver na 2FN, ele pode ser segundo
normalizado ou normalizado pela 2FN para uma série de relações 2FN em que os
atributos não principais são associados com a parte da chave primária em que eles são
total e funcionalmente dependentes. Portanto, as dependências funcionais DF1, DF2 e
DF3 da Figura 35 levam à decomposição de CLIENTE_CONTA nos três esquemas de
relação FP1, FP2 e FP3, mostrados na Figura 41(a), cada qual estando na 2FN.
CLIENTE_CONTA
Cpf Numero_conta Data_inicio Nome Saldo Tipo_conta
DF1
DF2
DF3
Normalização 2FN
FP1 FP2 FP3
Cpf Numero_conta Data_inicio Cpf Nome Numero_conta Saldo Tipo_conta
DF1 DF2 DF3
CONTA_AGENCIA
Numero_conta Saldo Tipo_conta Numero_agencia Endereço
Normalização 3FN
DF1 DF2
Numero_conta Saldo Tipo_conta Numero_agencia Numero_agencia Endereço
Figura 41 – Normalizando para 2FN e 3FN. (a) Normalizando CLIENTE_CONTA em relações 2FN. (b)
Normalizando CONTA_AGENCIA em relações 3FN.
4.4.4 Terceira forma normal
A terceira forma normal (3FN) é baseada no conceito de dependência
transitiva. Uma dependência funcional X → Y em um esquema de relação R é uma
dependência transitiva se houver um conjunto de atributos Z em R que nem sejam uma
chave candidata nem um subconjunto de qualquer chave de R, e tanto X → Z e Z → Y se
mantiverem. A dependência Numero_conta → Endereco é transitiva por meio de
Numero_agencia em CONTA_AGENCIA na Figura 41(b), pois ambas as dependências
Numero_conta → Numero_agencia e Numero_agencia → Numero_conta se mantêm e
Numero_agencia não é nem uma chave por si só nem um subconjunto da chave de
CONTA_AGENCIA. Intuitivamente, podemos ver que a dependência de Endereco sobre
Numero_agencia é indesejável em CONTA_AGENCIA, pois Numero_agencia não é uma
chave de CONTA_AGENCIA.
Definição. De acordo com a definição original de Codd, um esquema de relação
R está na 3FN se satisfizer a 2FN e nenhum atributo não principal de R for
transitivamente dependente da chave primária.
(a)
(b)
O esquema de relação CONTA_AGENCIA da Figura 41(b) está na 2FN, pois não
existe dependência parcial sobre uma chave. Porém, CONTA_AGENCIA não está na 3FN
devido à dependência transitiva de Endereco em Numero_conta por meio de
Numero_agencia. Podemos normalizar CONTA_AGENCIA decompondo-o nos dois
esquemas de relação 3FN DF1 e DF2 mostrados na Figura 41(b). Intuitivamente, vemos
que DF1 e DF2 representam fatos de entidades independentes sobre contas e agências.
Uma operação de JUNÇÃO NATURAL sobre DF1 e DF2 recuperará a relação original
CONTA_AGENCIA sem gerar tuplas falsas.
De maneira intuitiva, podemos ver que qualquer dependência funcional de que o
lado esquerdo faz parte (é um subconjunto apropriado) da chave primária, ou qualquer
dependência funcional de que o lado esquerdo é um atributo não chave, é uma DF
problemática. A normalização 2FN e 3FN remove essas DFs problemáticas ao
decompor a relação original em novas relações. Em relação ao processo de
normalização, não é necessário remover as dependências parciais antes das
dependências transitivas, porém, historicamente a 3FN tem sido definida com a
suposição de que uma relação é testada primeiro pela 2FN, antes de ser testada pela
3FN. A Tabela 3 resume informalmente as três formas normais com base nas chaves
primárias, os testes usados em cada uma e a solução ou normalização realizada para
alcançar a forma normal.
Tabela 3. Resumo das formas normais baseadas em chaves primárias e a normalização correspondente.
Forma normal Teste Solução (normalização)
Primeira (1FN) Relação não deve ter atributos multivalorados ou relações aninhadas.
Formar novas relações para cada atributo multivalorado ou relação aninhada.
Segunda (2FN) Para relações em que a chave primária contém
múltiplos atributos, nenhum atributo não chave deverá ser funcionalmente dependente de uma parte da chave primária.
Decompor e montar uma nova relação para cada
chave parcial com seu(s) atributo(s) dependente(s). Certificar-se de manter uma relação com a chave
primária original e quaisquer atributos que sejam total e funcionalmente dependentes dela.
Terceira (3FN) A relação não deve ter um atributo não chave
determinado funcionalmente por outro atributo não chave (ou por um conjunto de atributos não
chave). Ou seja, não deve haver dependência transitiva de um atributo não chave sobre a chave primária.
Decompor e montar uma relação que inclua o(s)
atributo(s) não chave que determina(m) funcionalmente outro(s) atributo(s) não chave.