Chaves compostas nunca devem ser consideradas em aplicativos "novos". Eles foram usados no passado, por pessoas que costumavam pensar que "chaves de negócios" são melhores do que "chaves substitutas".
Edit:Conforme perguntado por Chris, estou expandindo minha resposta.
Deixe-me começar afirmando que entendo essa questão como "Chaves primárias compostas" versus "Chaves substitutas".
Além disso, admito que há um caso de uso em que uma chave composta faz sentido:em tabelas de referência cruzada, também chamadas de "tabelas de link". Eles são usados em tabelas muitos-para-muitos e consistem em apenas dois campos, ambos chaves estrangeiras que formam uma chave primária para a tabela refex. Por exemplo,
UserRole
tabela conteria user_id
e role_id
, nada mais. Não há representação de classe em Java, por exemplo, para uma tabela como esta. Geralmente é um @ManyToMany
, com uma Collection
em ambos os lados. Compartilhei minhas opiniões sobre chaves naturais versus chaves substitutas em outra resposta ( Hibernate:Opiniões em Composite PK vs Surrogate PK ), e acredito que as chaves compostas compartilham algumas das desvantagens da chave natural, sem trazer nenhum benefício real.
O problema com as chaves compostas é que você precisará de duas valores para identificar exclusivamente um registro. Isso se torna um problema quando você começa a ter tabelas que referenciam registros nesta primeira tabela. A segunda tabela precisa de dois colunas para poder referenciar um registro. E se esta segunda tabela usa uma chave composta composta por um único valor + a chave estrangeira, agora você tem três colunas para identificar exclusivamente um registro. E uma terceira mesa precisaria desses três colunas extras apenas para referenciar uma registro na segunda tabela. Realmente, isso é uma bola de neve.
Outra desvantagem é que os requisitos não mudança. O tempo todo. Assim, o que parece ser uma boa chave composta hoje não será amanhã. É por isso que temos chaves substitutas:para ser à prova de futuro.
As chaves compostas são usadas principalmente para que os registros em uma tabela sejam exclusivos com base em um conjunto de colunas. Por exemplo, se você tiver um
Customers
tabela, você pode ter um NationalId
+Country
como um valor único, o que significa que dois usuários não podem compartilhar o mesmo SSN se seu país for os EUA. Mas é possível ter o mesmo número para dois registros, se eles não estiverem no mesmo país. Se você gosta de chaves compostas, este seria um bom candidato para isso. Mas, como sugeri anteriormente, você pode usar uma chave substituta e aplicar um unique
restrição. Você terá os benefícios de uma chave composta mais a segurança de uma chave substituta.