Сразу скажу, что разные решения понимаю и могу обосновать, но хочется услышать мнения других.
Распространенная ситуация: есть три таблицы — две сущности и перекрестная таблица, реализующая связь многие-ко-многим между этими двумя сущностями. Пример: специалисты (Expert) и технологии (Technology), которыми они владеют связаны многие-ко-многим (ExpertTechnology). Задача — как организовать ключи в перекрестной таблице.
Решение 1: Перекрестная таблица должна иметь два поля, ExpertId и TechnologyId, по каждому полю FOREIGN KEY и делаем еще PRIMARY KEY по паре полей (ExpertId, TechnologyId).
Решение 2: Перекрестная таблица должна иметь три поля, ExpertTechnologyId, ExpertId и TechnologyId, по ExpertId и TechnologyId делаем FOREIGN KEY и делаем PRIMARY KEY по полю ExpertTechnologyId и еще альтернативный уникальный ключ по паре полей (ExpertId, TechnologyId).
Первый вариант вполне оптимизирован, и вроде как более ничего не нужно, но второй вариант хорош тем, что на это ExpertTechnologyId всегда можно ссылаться, вместо того, чтобы ссылаться на пару (ExpertId, TechnologyId), ну и некоторое ПО имеет внутреннее ограничение на работу только с таблицами, в которых должен быть первым полем уникальный идентификатор.
я использую оба варианта но в разных ситуациях.
1- вариант — если связь не обладает характеристиками, например контент и теги
2 — вариант — при наличии у связи характеристик — т.е. например если нужно ограничить доступное количество подобъектов из контекста первой сущности для второй, то этот лимит хранится в таблице со связью, им нужно манипулировать, для этого и вводится персональный идентификатор
Ну вот я так же поступаю, 2 вариант — если есть еще дополнительные атрибуты у связи или еще таблицы, которые ссылаются не на сущность, а на саму связь. Но вот вопрос в том, что частенько первый случай перетекает (расширяется) до второго, и не лучше ли всегда делать оп второму варианту, чтобы не менять структуру базы потом, когда добавятся атрибуты и ссылающиеся на связь таблицы? Чего-то я стал склоняться ко второму, но пока смущает.
Я не вижу больших проблем перехода между первым и вторым вариантом, мне кажется связи останутся, нужно будет только primary переназначить, хотя не знаю что будет в конкретной db, которой вы пользуетесь.
PRIMARY KEY по полю ExpertTechnologyId можно и не делать(в некоторых случаях это может снизить производительность и не всегда действительно востребованно), но само поле ExpertTechnologyId как мне кажется необходимо. Оно удобно для отладки запросов, пригождается в программе. И как вы сами написали, часто первый вариант апгрейдят до второго.
Я никогда не применял второй вариант — не было необходимости. В вебе, например, если нужно удалить группу у пользователя, то легче взять уже передаваемый user_id и передавать group_id, который, как правило, все равно нужен хотя бы для ссылки, чем вводить дополнительный id для связи.
На мой взгляд тут все зависит от вас, если вам удобнее работать с дополнительным ключом, то он нужен, если нет — то нет. По производительности — практически равнозначно, только нужно не забыть расставить индексы.
Я считаю, что оба варианта корректные, делайте как вам удобно.