Quais alternativas existem quando uma tabela requer muitas chaves estrangeiras?

8

Temos uma tabela base que define as peças e mantém informações como número da peça, descrição, preço, peso etc. Também temos aproximadamente 400 tabelas que fazem referência à tabela base e fornecem informações adicionais sobre as peças com base em seu tipo / categoria.

Começamos usando restrições de chave estrangeira para que uma parte não possa ser excluída da tabela base se estiver sendo referenciada em uma das tabelas específicas de 400 partes, mas rapidamente alcançamos o máximo de 253 chaves estrangeiras recomendadas para o SQL Server 2005.

Existem alternativas para chaves estrangeiras nessa situação que garantam a integridade dos dados? Não vimos problemas de desempenho ao acessar os dados, mas a atualização de uma peça existente na tabela base falhará, pois o plano de consulta é muito complexo.

jellomonkey
fonte
14
Você realmente acha que precisa de 400 tabelas específicas de peças? Qual é a diferença de cada uma dessas tabelas, na verdade? Acho que você está tentando corrigir a parte errada desse design.
Aaron Bertrand
2
Aproximadamente com quantas linhas você está lidando neste banco de dados?
precisa
4
Eu tenho que concordar com Aaron Bertrand, se o seu projeto exigir que você maximize ao máximo o suporte ao servidor sql de chaves estrangeiras, talvez seja hora de considerar uma reformulação.
DForck42
5
Já fiz muitos projetos nessa área - preços, gerenciamento de produtos, especificações do produto. Mesmo em projetos altamente normalizados, nunca cheguei perto de tantos FKs na mesma mesa. Você talvez esteja fazendo algum tipo de estratégia de particionamento de dados (por cliente, horário ou algo parecido) que o levou a projetar nessa direção? É difícil fornecer uma resposta sem mais informações sobre seus objetivos de design e design.
Karen Lopez
4
Você poderia fornecer exemplo de esquema para dizer 5 destas tabelas ...
Damir Sudarevic

Respostas:

6

Se houver alguma maneira de agrupar partes, você poderá introduzir tabelas intermediárias como solução alternativa. Isso não vai funcionar.

Parts
+ Table 1
+ Table 2
+ ...
+ Table 400

Mas algo nesse sentido pode.

Parts
+ RedOrangeYellow parts
  + Table 1
  + Table 2
  + ...
  + Table 200

+ GreenBlueIndigoViolet parts
  + Table 201
  + Table 202
  + ...
  + Table 400

Eu gostaria de dar uma olhada no seu DDL antes de recomendar isso, no entanto. E se você fizer isso, não comece a lançar números de identificação em todos os lugares. Você deve poder ingressar na "Tabela 400" diretamente em "Peças" sem incluir "peças GreenBlueIndigoViolet".

Mike Sherrill 'Recolha de Gatos'
fonte
-4

Substitua as mais de 400 tabelas por uma. Precisa apenas de 3 campos (+1 de numeração automática ou qualquer chave primária, se desejar, não precisa ter, você pode formar a partir dos outros campos)

Valor do atributo do ID do item

Portanto, onde em suas outras tabelas cada campo representa um atributo, nessa tabela seus atributos estão todos em um campo. Você teria algo parecido com isto

Valor do atributo ItemID

Lã de material de meia

Meia Cor Vermelho

Peso da meia 20 libras

Alien Planet Alpha Centauri

Alien Color Purple

Alienígena Não

Os ItemIDs provavelmente devem ser um número / alfanumérico ofc. Em seguida, basta fazer a tabela de referência cruzada com Atributos como cabeçalhos de coluna quando necessário para gerar as tabelas como você desejar. Isso também permite melhores consultas para coisas como "Mostre-me todos os itens que são de Alpha Centauri", que podem devolver o Alien e também o fragmento de Meteorito que continha a praga que destrói a humanidade (está chegando .....)

A otimização pode ser complicada, dependendo de quantos registros existem, mas é uma maneira muito melhor de projetar isso. Fiz o mesmo para um banco de dados que continha várias receitas (10k +) com poucas sobreposições. Funcionou bem nesse caso. Realmente não tinha nenhum problema de velocidade. O seu pode ser mais difícil, dependendo de com quem você está lidando.

user2125055
fonte
4
Isso é chamado de modelo de valor de atributo de entidade e normalmente é uma péssima ideia por vários motivos. Para o seu exemplo do cenário "alfa-centauro", você provavelmente examinaria duas varreduras de tabela e os índices não podem ser usados. Além disso, anula qualquer vantagem para os tipos de dados, impossibilita restrições relacionais e geralmente não é otimizável ou escalável em nenhum grau. Se você precisar armazenar mais de cem linhas como essa, não faça.
JNK
2
Como aponta o @JNK, geralmente não é uma boa solução. E ainda pior quando você faz isso com apenas uma mesa. Eu diria que o mínimo é de 3 mesas ( Entity, Entity_Attribute, Entity_Attribute_Value). Se você deseja adicionar tratamento semi-adequado para diferentes tipos de dados e restrições de referência, precisará de mais.
ypercubeᵀᴹ
11
Embora o OP possa estar se aproximando de algum tipo de limite com o projeto normalizado tradicional devido à grande complexidade das entidades em seu sistema, os sistemas extremamente complexos não são realmente melhor tratados no EAV, já que oferece suporte ao tipo mais fraco e nível de aplicativo integridade referencial, já que os dados são todos armazenados de maneira bastante genérica. O EAV tem seu lugar útil, mas eu não estaria pronto para recomendá-lo como uma resposta para esse problema, conforme indicado atualmente.
Cade Roux #
Aprenda algo novo todos os dias. Sou autodidata e esse foi o objetivo que eu resolvi para resolver o problema da receita que eu estava tendo, o que soa semelhante a esse problema dos caras. Ah bem. Obrigado pela informação, vou procurar no EAV, talvez haja uma maneira mais limpa de resolver meu problema também. Poderia ser mais fácil para mim, pois todos os valores eram do mesmo tipo de dados. Não sei.
user2125055
2
@ user2125055 Não há problema e não leve nenhuma das críticas pessoalmente. Estamos apenas rejeitando a ideia de usar o EAV! Definitivamente, existem casos de uso em que isso faz sentido, mas, devido às desvantagens, você precisa ter muito cuidado com isso.
JNK