Pergunta

Eu tenho as seguintes tabelas na base de dados que têm uma relação muitos-para-muitos de relacionamento, que é expressa através de uma conexão de tabela que tem as chaves estrangeiras para as chaves primárias de cada uma das tabelas principais:

  • Widget:WidgetID (PK), Título, Preço
  • Usuário:UserID (PK), Nome, Apelido

Suponha que cada Usuário Widget combinação é única.Eu posso ver duas opções para a forma como a estrutura de ligação tabela que define os dados de relacionamento:

  1. UserWidgets1:UserWidgetID (PK), WidgetID (FK), id de utilizador (FK)
  2. UserWidgets2:WidgetID (PK, FK), id de utilizador (PK, FK)

Opção 1 tem uma única coluna para a Chave Primária.No entanto, isso parece desnecessária, já que os únicos dados que estão sendo armazenados na tabela é a relação entre as duas tabelas primárias, e esta relação em si pode formar uma chave exclusiva.Assim, levando a opção 2, que tem uma de duas colunas de chave primária, mas perde-a de uma coluna de identificador exclusivo que a opção 1.Eu poderia também, opcionalmente, adicionar duas colunas de índice exclusivo (WidgetID, UserID) para a primeira tabela.

Existe alguma diferença real entre os dois performance, ou qualquer motivo para preferir uma abordagem sobre a outra para a estruturação da UserWidgets muitos-para-muitos mesa?

Foi útil?

Solução

Você só tem uma chave primária em ambos os casos.O segundo é o que é chamado de uma chave composta.Não há nenhuma boa razão para a introdução de uma nova coluna.Na prática, você terá que manter um índice exclusivo em todas as chaves de candidatos.Adicionar uma nova coluna compra nada, mas a sobrecarga de manutenção.

Ir com a opção 2.

Outras dicas

Pessoalmente, Eu gostaria de tem a sola do sintéticas/aluguel de coluna de chave em muitos-para-muitos tabelas, pelas seguintes razões:

  • Se você já usou numérico sintético chaves em seu tabelas de entidade, em seguida, ter o mesmo em relação tabelas mantém a consistência no design e convenção de nomenclatura.
  • Pode ser o caso de, no futuro, que a muitos-para-muitos mesa em si se torna uma entidade-mãe para um subordinado entidade que precisa de uma referência exclusiva para uma linha individual.
  • É realmente não vai usar muito espaço em disco adicional.

O sintético chave não é um substituto para o natural/chave composta, nem se torna o PRIMARY KEY para que a tabela só porque é a primeira coluna na tabela, então eu concordo parcialmente com o Josh Berkus artigo.No entanto, eu não concordo que as chaves são sempre bons candidatos para PRIMARY KEY's e, certamente, não devem ser usados se estiverem a ser usadas como chaves estrangeiras em outras tabelas.

Opção 2 usa um simples compund chave, opção 1 usa uma chave de substituição.A opção 2 é preferido na maior parte de cenários e está perto de lreational modelo em que ele é um bom candidato-chave.

Existem situações onde você pode querer usar uma chave substituta (Opção 1)

  1. Você não está que a chave composta é um bom candidato-chave ao longo do tempo.Particularmente temporais de dados (dados que se alteram ao longo do tempo).O que se queria para adicionar outra linha para o UserWidget tabela com o mesmo id de utilizador e WidgetId?Pensar de Emprego(EmployeeId,EmployeeId) - que iria funcionar na maioria dos casos, exceto se alguém voltou a trabalhar para o mesmo empregador, em uma data posterior
  2. Se você estiver criando mensagens/transações de negócios ou algo semelhante, que exigem uma mais fácil a tecla a utilizar para a integração.Replicação talvez?
  3. Se você quer criar seus próprios mecanismos de auditoria (ou similar) e não quer chaves de ficar muito longo.

Como regra geral, quando modelagem de dados, você verá que a maioria das entidades associativas (muitos para muitos) são o resultado de um evento.A pessoa leva até o emprego, o item é adicionado à cesta, etc.A maioria dos eventos tem uma dependência temporal sobre o evento, onde a data ou a hora é relevante no caso de uma chave substituta pode ser a melhor alternativa.

Assim, tomar a opção 2, mas certifique-se de que você tem o modelo completo.

Concordo com as respostas anteriores, mas eu tenho uma observação a acrescentar.Se você desejar adicionar mais informações para a relação e permitir mais as relações entre as mesmas duas entidades que você precisa de uma opção.

Por exemplo, se você quiser acompanhar todas as vezes que o usuário 1 tem widget usado 664 no userwidget tabela a id de utilizador e widgetid não é mais exclusivo.

Qual é a vantagem de uma chave primária neste cenário?Considere a opção de nenhuma chave primária:UserWidgets3:WidgetID (FK), id de utilizador (FK)

Se pretender a exclusividade, em seguida, use a chave composta (UserWidgets2) ou uma restrição de exclusividade.

O desempenho de costume vantagem de ter uma chave primária é que muitas vezes você consulta a tabela de chave primária, que é mais rápido.No caso de muitos-para-muitos tabelas você não costuma consulta pela chave primária, então não há nenhum benefício em termos de desempenho.Muitos-para-muitos tabelas são consultadas por suas chaves estrangeiras, então você deve considerar a adição de índices em WidgetID e id de usuário.

A opção 2 é a resposta correta, a menos que você tenha uma razão muito boa para adicionar um substituto tecla numérica (o que você tem feito na opção 1).

Substituição da chave numérica colunas não são "chaves primárias'.Chaves primárias são tecnicamente uma combinação de colunas que identificam unicamente um registro em uma tabela.

Alguém construção de um banco de dados deve ler este artigo http://it.toolbox.com/blogs/database-soup/primary-keyvil-part-i-7327 Josh Berkus para entender a diferença entre o aluguel numérico colunas de chave primária e chaves.

Na minha experiência, a única razão real para adicionar um substituto tecla numérica para a sua mesa é se a sua chave primária é uma chave composta e precisa ser usado como uma referência de chave estrangeira em outra tabela.Só então você deve mesmo pensar para adicionar uma coluna extra para a mesa.

Sempre que eu ver uma estrutura de banco de dados, onde cada tabela tem um 'id' coluna, as chances são de que ele foi concebido por alguém que não aprecia o modelo relacional e, invariavelmente, apresentar um ou mais dos problemas identificados na Josh artigo.

Eu iria com ambas.

Ouça-me:

A chave composta é, obviamente, o bom, o correto caminho a percorrer, na medida em que, refletindo o significado de seus dados.Nenhuma pergunta.

No entanto:Eu tive todos os tipos de problemas para fazer o hibernate funcionar corretamente, a menos que você use um único gerado de chave primária uma chave substituta.

Então, eu gostaria de usar uma lógica e física de dados modelo.A lógica tem a chave composta.O modelo físico - que implementa o modelo lógico - tem o substituto de chaves e chaves estrangeiras.

Uma vez que cada Usuário-Widget combinação é única, você deve representar o que a sua mesa fazendo a combinação única.Em outras palavras, ir com a opção 2.Caso contrário, você pode ter duas entradas com o mesmo widget e IDs de usuário, mas diferente do usuário-widget Id.

O userwidgetid na primeira tabela não é necessário, já que como você disse, a singularidade vem da combinação de widgetid e o id de utilizador.

Gostaria de usar a segunda tabela, mantenha as chaves estrangeiras e adicionar um índice exclusivo na widgetid e id de usuário.

Assim:

userwidgets( widgetid(fk), userid(fk),
             unique_index(widgetid, userid)
)

Há alguns duvidosa é bem capaz de ganho em não ter o extra chave primária, como o banco de dados não precisa calcular o índice para a chave.No modelo acima, embora este índice (através do unique_index) é calculada ainda, mas eu acredito que isso é mais fácil de entender.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top