Orientação para o uso de chaves compostas para identificar linhas

8

É uma boa prática (ou teria efeitos adversos) usar um conjunto de 4 colunas para identificar uma linha como única (uma sendo uma chave estrangeira, as outras três sendo tipos de dados flutuantes)? Estou tentando criar uma tabela que (com 4 chaves vinculadas) descreva uma entrada exclusiva na tabela. Estou curioso para saber se este é um bom plano de ataque ou se existe uma maneira melhor.

Para fins visuais, imagine a tabela a seguir. Temos itens de inventário organizados como a tabela a seguir: ( [K]simboliza a chave primária, as linhas são relacionamentos)

    Sheet_Class        Sheet_Type         Sheet_Size
    ===========        ==========         ==========
[K] Sheet_Class-.  [K] Sheet_Type--.  [K] Sheet_Size
                 '---- Sheet_Class  '---- Sheet_Type
                                          Length
                                          Width
                                          Thickness

Os dados podem se apresentar da seguinte maneira, mas, por uma questão de brevidade, excluí a possibilidade de trazer as colunas vinculadas:

 Sheet_Class    Sheet_Type    Sheet_Size                        (Tables)
[Sheet_Class]  [Sheet_Type]  [Length], [Width], [Thickness]     (Column Values)
=============  ============  ==============================

Aluminum
               5052-H32
                             48, 96, 0.032
                             48, 96, 0.040
                             48, 96, 0.063

               6061-T6
                             60, 120,0.032
                             60, 120,0.040
                             60, 120,0.063

Steel
               1018-CRS
                             48, 96, 0.018
                             48, 96, 0.023
                             48, 96, 0.031

Como está (e mostrei no meu "esquema" acima), uso uma chave primária inteira simples (incremento automático) para entradas na tabela Sheet_Size . No entanto, gostaria de saber se é melhor usar uma combinação das colunas Sheet_Type , Length , Width e Thickness . Dado que cada entrada no Sheet_Size deve compartilhar todas essas qualidades exclusivas e que um campo de incremento automático não demonstraria isso suficientemente bem, esse é o melhor caminho a seguir?

Se não estou explicando a situação suficientemente bem, entre em contato. Estou precisando quebrar essas partes (classe x tipo x tamanho real do estoque) de um material inventariado para outros fins lógicos, mas estou disposto a receber qualquer outro tipo de feedback.

Qualquer orientação seria apreciada.

Atualização (12-08-2011)

Após as respostas postadas, eu decidi fazer uma combinação de Mark resposta e resposta de X-Zero . Decidi que é uma boa ideia colocar uma restrição exclusiva nas colunas de comprimento, largura e espessura, mas também gosto da ideia de dividir os tamanhos dos materiais em linhas únicas e vinculá-los a um relacionamento.

Infelizmente, não posso aceitar as duas respostas, por isso aceitarei o X-Zeros por considerar (o que sinto) uma visão mais crítica do problema e oferecer um ajuste de esquema.

Obrigado a todos por suas respostas.

Brad Christie
fonte

Respostas:

6

Depois de pensar sobre isso, eu revisaria a estrutura da sua tabela um pouco.
Primeiro, revise sua tabela de tamanho de folha:

Sheet_size
===========
Id
Length
Width
Thickness

Segundo, crie uma tabela de relacionamento tamanho / folha:

Sheet_size_type
================
Sheet_Type_Id
Sheet_Size_Id

Em seguida, crie as seguintes restrições:

  1. A chave primária (e o índice) de Sheet_sizedeve ser a coluna de identificação
  2. Deve haver algum tipo de chave (e índice) exclusiva aplicada nas dimensões em Sheet_size. Considere, duas folhas de dimensões (48, 96, 0,5) e (96, 48, 0,5) são iguais (ou seja, a direção das dimensões é importante)? Esse tipo de problema pode ser difícil de aplicar se, através do uso das colunas como parte da chave primária, mas se tornar mais gerenciável ao usar restrições e procedimentos armazenados.
  3. A chave primária (e o índice) de Sheet_size_typedevem usar as duas chaves estrangeiras, começando pela chave de cardinalidade mais baixa (provavelmente sheet_type, como seu exemplo). Você pode querer um índice adicional na outra direção, mas pode não ser necessário.

Essa revisão economizará espaço no banco de dados (como uma proporção do número de tipos de folhas usando o mesmo tamanho) e não deve afetar muito a sobrecarga.


Existem outras preocupações em potencial sobre igualdade / exclusividade se você estiver usando um floattipo de dados, pois a imprecisão pode fazer com que você seja surpreendido inesperadamente. Você deve considerar se um tipo de ponto fixo, com certa precisão, seria ou não mais apropriado.

Musa Mecânica
fonte
Eu estava planejando limitar o Comprimento e a Largura a um (dois possíveis) pontos decimais, e a espessura (no máximo) se estenderia a três. Além disso, estamos ficando muito finitos (e o estoque em si nunca chega aos números descritos). Além disso, gosto da ideia de dividir os tamanhos das folhas, mas o problema que estou enfrentando são as outras colunas envolvidas (que eu excluí). (precisar de mais espaço, ver o próximo post)
Brad Christie
Como esta é uma lista de estoque inventariado, tenho que incluir outras informações, como Densidade e Custo / lb (que são fortemente baseadas no tipo (e espessura). Por exemplo, "Aço" / "1018" pode ser de US $ 0,55 / lb com 0,018-0,125 "de espessura, mas passa a US $ 0,65 / lb quando a espessura ultrapassa 0,125". (E isso também pode diferir entre um tamanho de folha de 48 "x96" x0,250 "de 1018 versus 5052-H32). No seu exemplo, Eu só tem uma entrada para um x0.125" 48 "x96" (embora eu suponho tabela de relacionamento poderia ter essas métricas adicionais)
Brad Christie
Se você precisar apenas de um pequeno número de casas decimais, use sim uma precisão fixa. Sim, é aí que (nesse caso) você coloca informações assim (o custo é uma dependência do tipo e tamanho da folha, por exemplo), embora você queira gerar tabelas adicionais que possam ser referenciadas. Você também pode considerar criar tipos de dados personalizados (como densidade) para que as pessoas não tentem consultar seus dados de maneiras inesperadas.
Clockwork-Muse
6

Parece uma decisão-chave natural versus substituta , cuja opinião varia de considerada e prática a acadêmica , na fronteira com o dogma. Dependendo do RDBMS, há considerações para o modelo físico que podem ter implicações significativas no desempenho, por exemplo, escolha de chave em cluster no SQL Server.

Pessoalmente, se eu tenho uma chave candidata de atributo único e estreita, fico tentada a fazer uso dela. Teclas largas e / ou compostas, por padrão, estou adicionando um substituto ao modelo. No seu caso, eu votaria na coluna de identidade em Sheet_Size como chave de cluster primária e uma restrição exclusiva no tipo / comprimento / largura / espessura.

Mark Storey-Smith
fonte
Mas, como agora você tem uma chave "arbitrária" atribuída à linha, como o exclusivo impõe que as colunas (quando combinadas) não possam ter valores duplicados? Entendo que o atributo exclusivo esteja relacionado à chave. Você está dizendo Sheet_Size INT PRIMARY KEYe Length UNIQUE, Width UNIQUE, Thickness UNIQUE? Ainda não entendo como isso evita duplicatas na tabela (sem aplicar lógica à interface de inserção). (Talvez eu estou faltando alguma coisa?)
Brad Christie
Uma restrição único em três colunas: ALTER TABLE dbo.Sheet_Size ADICIONAR RESTRIÇÃO UC_LengthWidthThickness ORIGINAL ([Corpo], [largura], [Espessura])
Mark Storey-Smith
Obrigado pelo feedback. Concordo que uma restrição única nas colunas seria uma ótima solução, mas também gosto da recomendação da X-Zero de dividir os tamanhos em uma nova tabela (vinculada a uma nova tabela). Portanto, para combinar idéias, aplicarei a restrição exclusiva à tabela de tamanho "Despojado", removendo as informações de densidade e custo / lb e colocando-as na tabela de relacionamento.
Brad Christie
4

Eu o redirecionarei um pouco para esta resposta de uma pergunta anterior .

Citação: "Em relação à maneira de projetar essa chave primária, existem duas escolas de pensamento:

  • aquele que faz o PK como uma coluna separada, geralmente gerada automaticamente, como um GUID ou INT de incremento automático (no seu caso, uma coluna identificador exclusivo separada);
  • aquele que torna a PK como uma coluna (ou conjunto de colunas) interna da tabela (no seu caso, seria um nome de usuário ou email ou SSN, o que torna esse usuário único) que identifica exclusivamente um registro.

Para que linha você adere, é apenas uma questão de gosto ".

Os efeitos colaterais de qualquer solução escolhida podem ser:

  • o uso de chaves compostas em todos os lugares provavelmente:

    • aumentar o armazenamento para todas as tabelas envolvidas;
    • aumentar / complicar índices em FKs frequentemente usados;
    • complicar um pouco a escrita de todas as suas declarações de junção
    • faça o Sr. Joe Celko feliz :-) (referências sobre suas opiniões sobre chaves naturais ou artificiais podem ser encontradas aqui e aqui , e principalmente em todos os lugares onde ele é perguntado sobre o assunto)
  • usando chaves geradas provavelmente:

    • simplifique os 3 passos anteriores
    • complicar a situação de replicar uma tabela com identidade PK (referências aqui , aqui ou aqui )

Pessoalmente, sou a favor de chaves INT IDENTITY geradas, mas o que combina com você deve ficar bem.

Marian
fonte
2

A chave composta faz todo o sentido. A implementação dessa chave garante que os atributos de negócios não possam ser duplicados. Isso é bom porque gravar os mesmos dados várias vezes causaria ambiguidade, dependências indesejáveis ​​e aumentaria a probabilidade de erros do usuário e dados incorretos.

Somente a chave de incremento automático não protegerá a integridade dos dados da sua empresa. Se a chave de incremento automático não tiver fins específicos (por exemplo, como o destino de uma referência de chave estrangeira em outra tabela), ela poderá ser descartada com segurança.

nvogel
fonte
... Exceto a eliminação do incremento automático, pois a chave estrangeira exigiria o uso de todas as colunas de dimensão como parte da chave estrangeira (ou seja, todas as quatro colunas , ao incluir o tipo). Não é algo que eu quero como minha chave estrangeira, ponto final - apenas colunas únicas, por favor. Concordo que é uma boa ideia colocar uma chave exclusiva (e / ou verificar restrição) nas dimensões (e tipo, dependendo do design da tabela).
Clockwork-Muse
@ X-Zero, eu falei sobre referências de chave estrangeira no meu segundo parágrafo. A questão que eu li é se deve implementar a chave composta, não se também deve haver um incremento automático.
Nvogel