Должны ли внешние ключи стать первичным ключом таблицы? - PullRequest
14 голосов
/ 30 марта 2010

У меня есть таблица (session_comments) со следующей структурой полей:

student_id (foreign key to students table)
session_id (foreign key to sessions table)
session_subject_ID (foreign key to session_subjects table)
user_id (foreign key to users table)
comment_date_time
comment

Теперь комбинация student_id, session_id и session_subject_id будет однозначно идентифицировать комментарий об этом ученике по этому предмету сессии.

Учитывая, что они являются уникальными, несмотря на то, что они являются внешними ключами, есть ли для меня преимущество в том, чтобы сделать их объединенным первичным ключом для этой таблицы?

Еще раз спасибо.

Ответы [ 6 ]

14 голосов
/ 30 марта 2010
  1. Если сделать их первичным ключом, это приведет к уникальности (в противоположность этому).
  2. Первичный ключ предположительно будет кластеризован (в зависимости от базы данных), что повысит производительность для некоторых запросов.
  3. Это экономит пространство для добавления уникального ограничения, которое в некоторых СУБД также создает уникальный индекс.

Независимо от того, делаете ли вы эти три первичных ключа или нет, вам все равно понадобится какое-то ограничение уникальности, чтобы гарантировать, что учащийся не может быть связан с одним и тем же сеансом и session_subject_id дважды. Если этот сценарий разрешен, вам необходимо расширить ограничение уникальности, включив в него другой столбец.

Независимо от того, какой выбор вы сделаете, у вас должно быть какое-то ограничение на уникальность таблицы.

Если вы обсуждаете вопрос о том, следует ли создавать суррогатный первичный ключ + уникальное ограничение для трех столбцов, я бы сказал, что это зависит от того, будут ли в этой таблице дочерние таблицы. Если это так, то ссылка на суррогатный ключ будет проще и меньше. Если этого не произойдет, то IMO, суррогатный ключ на самом деле не дает вам много, и вы можете также использовать три столбца, как PK.

6 голосов
/ 30 марта 2010

Зависит от остальной части приложения.
Если у вас не будет внешних ключей для таблицы комментариев (что представляется вероятным), это нормально.
Если вам нужно будет сослаться на комментарии из другой таблицы, вам лучше создать уникальный индекс с 3 полями плюс первичный ключ AutoNumber , который будет использоваться в других таблицах как внешний ключ проще и дешевле чем 3 поля).

3 голосов
/ 30 марта 2010

Дебаты о естественных и искусственных ключах так же стары, как и любая реализация базы данных. Читайте о плюсах и минусах в википедии .

Аргументы в пользу суррогатных ключей легко оспариваются на теоретическом уровне (например, аргумент о том, что с естественными ключами вы рискуете, что ваш PK станет неуникальным, может быть опровергнут ответом - хорошо! Если я столкнусь с такой ситуацией, хорошо, что все сломалось бы вместо наличия искусственно уникальных первичных ключей с дублирующимися записями для фактических данных).

Другим хорошим аргументом является то, что искусственные ключи либо избыточны (в таблице есть еще один уникальный ключ), либо они позволяют вам хранить по существу неуникальные записи.

Тем не менее, найти хорошие естественные ключи иногда бывает так сложно, что вы должны выбрать что-то искусственное и учесть ситуацию, когда у вас будет человек с таким же именем, рожденный в ту же дату (или с неизвестной датой), с другими свойствами xy, которые одинаковы по стоимости.

Кроме того, не очень понятно, что искусственно, а что естественно. Например, вы можете сказать, что SSN естественен для ваших данных. Хотя это действительно составленное число.

Что касается производительности многоключевых отношений - они не так плохи, как вы могли бы подумать, более того - они сегментируют индексы естественным образом, и с такими ключами вы обычно получаете базу данных, которая действительно хорошо работает с общими запросы без каких-либо дополнительных индексов.

Если вы серьезно относитесь к этим проблемам и если вы пытаетесь построить сложную систему, прочитайте хорошую литературу ( C.J.Date Введение в системы баз данных, в настоящее время в 8-м выпуске приходит на ум)

2 голосов
/ 30 марта 2010

Единственная причина для превращения их в составной первичный ключ заключается в применении одного комментария к ученику / сеансу / предмету. Если вы не хотите этого делать, я бы не стал создавать другой ключ.

2 голосов
/ 30 марта 2010

Я бы порекомендовал вам использовать первичный ключ, сгенерированный для вас выбранной вами базой данных. Главным образом потому, что если вы измените структуру этой таблицы во время какого-либо обслуживания, вы рискуете стать уникальным ключом. Что может быть действительно сложной проблемой, чтобы разобраться. Кроме того, наличие уникального первичного ключа значительно упрощает запросы к таблице.

Уникальные идентификаторы для postgres: http://www.postgresql.org/docs/8.1/interactive/datatype.html#DATATYPE-SERIAL

Уникальные идентификаторы для Mysql: http://dev.mysql.com/doc/refman/5.0/en/example-auto-increment.html

1 голос
/ 30 марта 2010

Нет. Ключи FOREIGN могут содержать значения NULL, которые не допускаются в первичных ключах. Лучшее, что вы можете сделать, - это создать УНИКАЛЬНЫЙ индекс из столбцов.

Создайте ПЕРВИЧНЫЙ ключ на столе.

Ответ: Мой следующий вопрос: Есть ли вероятность совпадения клавиш 4 таблиц?

Эти два создадут один и тот же составной ключ 101010101: студент: 1010, занятие: 10, предмет: 10, пользователь: 1 студент: 10, занятие: 1010, предмет: 10, пользователь: 1

Я просто указываю, что четыре столбца должны иметь явно разные домены, чтобы перекрытие могло уменьшиться.

Вероятно, лучше всего использовать истинный первичный ключ.

...