Estou no processo de projetar um banco de dados e estou tendo dúvidas sobre minhas decisões iniciais de design...
Os tipos de produtos são os seguintes... Modelos, peças, kits de peças de reposição e opções.
Opção A (primeiro projeto): planejei ter tabelas separadas para os tipos de produtos acima. Eu diria que cerca de 75% dos campos seriam iguais em cada tabela.
Criei cada tipo de produto como tabelas separadas por causa das associações que preciso criar entre eles. Por exemplo, um modelo pode ter muitas opções e uma opção pode ter muitos modelos. Uma opção também pode ter muitas partes e uma parte pode ter muitas opções... e assim por diante...
Opção B: Em vez de ter tabelas separadas, eu poderia criar uma tabela chamada Produto que engloba modelo, peça, kits de peças de reposição e opções. Eu poderia ter um campo chamado tipo para diferenciar entre modelo, opções, etc. Suponho que uma desvantagem é que vários campos nunca seriam usados (deixados nulos) para determinados tipos de produtos. Eu estou supondo que é aqui que "não as melhores práticas" entrariam em jogo.
A opção B reduziria bastante a complexidade do design do banco de dados. Eu também não precisaria me preocupar em fazer referência a várias tabelas ao extrair dados para consultas ...
Se essa fosse minha decisão de design, provavelmente escolheria mais uma 'Opção C' (opção a modificada).
Primeiro, por que não 'Opção B':
Por um lado, gosto da clareza que cada produto tem em sua própria mesa. Se for uma grande tabela com um campo para determinar o tipo, a relação não é tão clara.
Por outro lado, a estratégia de indexação sempre exigiria que esse tipo de campo fosse listado. Como são apenas 4 tipos, a cardinalidade do índice é extremamente baixa (
SELECT * FROM product_table WHERE type='X'
é basicamente fazer uma varredura completa da tabela)Opção C
A desvantagem é a complexidade de evitar órfãos quando as coisas são atualizadas/excluídas e, inicialmente, projetar as consultas que usam essas tabelas.
Sugiro que você comece com o modelo relacional "correto", sua opção A. Se o uso típico desse modelo o levar à desnormalização em algumas áreas, não tenha medo de fazê-lo.
Eu estava discutindo com um colega na semana passada como os projetos de esquema são frequentemente considerados como algo que está gravado em pedra e nunca pode mudar. Estranho, considerando como a refatoração é uma prática aceita em todas as outras camadas de um aplicativo, que a refatoração de um esquema de banco de dados ainda seja vista como impraticável.
Se a interface para o banco de dados for bem projetada, nada impedirá que você adapte o esquema à medida que aprende mais sobre os padrões de uso do sistema.
Isso soa muito semelhante à hierarquia de listas de materiais/múltiplas cardinalidades que Paul Neilsen descreve no capítulo 17 da Bíblia do SQL Server 2008 .
O capítulo inteiro é uma leitura muito boa e a seção específica que aborda o problema de muitos para muitos é encontrada nas páginas 416-419.
Esta é a melhor discussão que já vi sobre o tipo de projeto de dados de peças explodidas .
Se você puder imaginar um cenário provável em que haveria consultas frequentes em todos os quatro tipos de produtos (e isso parece provável para mim), sua opção B é a melhor.
Em vez de deixar muitos campos anuláveis não utilizados na tabela Product, por que não adicionar uma tabela ModelProduct, uma tabela PartProduct, uma tabela ReplacementPartKitProduct e ter apenas os campos que são distintos para esses tipos nessas tabelas? Use a mesma chave primária nessas tabelas como sua tabela de produtos. Junte-se à tabela Product e ModelProduct quando quiser trabalhar com modelos. Precisa determinar se o registro do produto que você possui é uma peça? Basta fazer uma junção à esquerda de Product para PartProduct e, se PartProduct.[PrimaryKey] não for nulo, você terá uma peça. Se for nulo, não é uma Parte. Como alternativa, você pode adicionar um campo ProductType à tabela Product.