Normalmente, quando você tem uma tabela com uma chave primária de várias colunas, é o resultado de uma tabela de junção (muitos para muitos) que se elevou para ser sua própria entidade (e, portanto, merece sua própria chave primária). Há muitos que argumentam que qualquer tabela de junção DEVE ser uma entidade por padrão, mas essa é uma discussão para outro dia.
Vejamos um relacionamento hipotético de muitos para muitos:
Aluno * --- * Classe
(um aluno pode estar em várias turmas, uma turma pode ter vários alunos).
Entre essas duas tabelas, haverá uma tabela de junção chamada StudentClass (ou ClassStudent, dependendo de como você a escreve). Às vezes, você deseja acompanhar coisas como quando o aluno estava na sala de aula. Então você o adicionará à tabela StudentClass. Neste ponto, StudentClass se tornou uma entidade única ... e deve receber um nome para reconhecê-lo como tal, por exemplo, Inscrição.
Aluno 1 --- * Inscrição * --- 1 Classe
(um aluno pode ter muitas matrículas, cada matrícula é para uma turma (ou seguindo o caminho oposto que uma turma pode ter muitas matrículas, cada matrícula é para um aluno).
Agora você pode consultar questões como, quantos alunos estavam matriculados na aula de Química 101 no ano passado? Ou em quais aulas o aluno que John Doe se matriculou enquanto cursava a Universidade Acme? Isso foi possível sem a chave primária separada, mas depois que você tiver uma chave primária para inscrição, uma consulta mais fácil será sobre essas inscrições (por ID), quantos alunos receberam uma nota de aprovação?
A determinação de se uma entidade merece uma PK se resume a quantas consultas (ou manipulação) você fará por essa entidade. Digamos, por exemplo, que você deseja anexar as tarefas concluídas para um aluno em uma classe. O local lógico para anexar esta entidade (atribuição) seria na entidade de inscrição. Dar à inscrição sua própria chave primária tornaria as consultas de atribuição mais simples.