Faz muito tempo que não estudei design relacional, mas tinha uma vaga lembrança de que isso me incentivava a não dividir uma tabela desnecessariamente. Por exemplo, dadas as dependências funcionais
K -> A
K -> B
K -> C
minha suposição era que o "melhor" esquema é justo {KABC}
e não algo como {KAB, KC}
ou mesmo {KA, KB, KC}
. Pelo menos na prática é assim que eu vi os designers de banco de dados implementarem a tabela.
No entanto, uma rápida atualização na Wikipedia indica que o formalismo de normalização
- não faz nenhuma declaração no sentido de obter um "esquema mínimo",
- 6NF exigiria mesmo
{KA, KB, KC}
. Uma vez que 6NF implica as outras formas normais, isso implica que é mesmo impossível para eles fazerem um requisito mínimo.
Estou um pouco confuso que eu tenho isso errado o tempo todo. A noção de "obter um número mínimo de tabelas" realmente não desempenha nenhum papel no design relacional formal e é apenas uma prática comum?
As “Formas Normais” são estritamente definidas em termos de eliminação de dados redundantes e “atualizações de anomalias”. Se a correção de outros problemas de design de esquema conta como “Normalização” pode ser debatido, mas em linguagem geral Normalização significa apenas garantir que o banco de dados esteja em conformidade com alguma Forma Normal.
Reduzir o número de tabelas não é um objetivo, nem na teoria do design nem na prática. Reduzir tabelas pode ajudar ou prejudicar o desempenho, e é por isso que, na prática, as pessoas aumentam ou reduzem tabelas (independentemente de dados duplicados).
Grosso modo, aumentar o número de tabelas é útil quando você tem dados que raramente são usados em conjunto, diminuir o número de tabelas é útil quando você tem dados frequentemente usados em conjunto. A teoria relacional não se importa com o quão rápido ou lento algo é. A teoria evita que você entre em estados inválidos, falando de forma prática, alguns estados inválidos podem ser aceitáveis desde que tudo dê certo no final.
Para adicionar às outras respostas sobre normalização, fora da teoria sobre como um banco de dados deve ser estruturado para representar os dados, pode haver considerações práticas que podem tornar a divisão de uma tabela sensata.
Uma possível implementação do ACID que você encontraria no Postgres, por exemplo, envolve a exclusão e reinserção de uma linha na atualização e, posteriormente, a recuperação das linhas excluídas por meio de limpeza. Portanto, se você tiver uma tabela que pode conter muitos dados lidos principalmente e um bit sujo para marcar linhas para processamento, dividir o bit sujo em uma tabela separada pode melhorar significativamente o desempenho, pois os UPDATEs precisam reescrever uma fração dos dados. Ele também pode economizar muito espaço em disco, pois o caso de tabela única continuaria duplicando dados até que um VACUUM pudesse recuperar as tuplas mortas.
Problemas semelhantes podem ocorrer quando parte dos dados é tão grande que é torrada, então você pode querer dividir os campos comumente acessados ou atualizados em uma tabela separada.