У меня две таблицы:
- Пользователь (логин, пароль)
- Профиль (profileId, пол, дата рождения, ...)
В настоящее время я использую этот подход: каждая запись профиля имеет поле с именем «userId» в качестве внешнего ключа, которое ссылается на таблицу User. Когда пользователь регистрируется, его запись профиля создается автоматически.
Меня смущает предложение моего друга: иметь поле «userId» в качестве внешнего и первичного ключа и удалить поле «profileId». Какой подход лучше?
database
foreign-keys
primary-key
Duc Tran
источник
источник
Ответы:
Внешние ключи почти всегда являются «Разрешенными дубликатами», что делает их непригодными в качестве первичных ключей.
Вместо этого найдите поле, которое однозначно идентифицирует каждую запись в таблице, или добавьте новое поле (либо автоматически увеличивающееся целое число, либо GUID), которое будет выступать в качестве первичного ключа.
Единственным исключением из этого правила являются таблицы с взаимно-однозначным отношением, в которых внешний ключ и первичный ключ связанной таблицы являются одним и тем же.
источник
Первичные ключи всегда должны быть уникальными, внешние ключи должны допускать неуникальные значения, если таблица является отношением «один ко многим». Совершенно нормально использовать внешний ключ в качестве первичного ключа, если таблица связана отношениями «один к одному», а не отношениями «один ко многим». Если вы хотите, чтобы одна и та же запись пользователя имела возможность иметь более одной связанной записи профиля, используйте отдельный первичный ключ, в противном случае придерживайтесь того, что у вас есть.
источник
Да, разрешено, чтобы первичный ключ был внешним ключом. Это редкая конструкция, но она применима для:
соотношение 1: 1. Две таблицы нельзя объединить в одну, потому что разные разрешения и привилегии применяются только на уровне таблицы (по состоянию на 2017 год такая база данных была бы нечетной).
соотношение 1: 0..1. Профиль может существовать или не существовать, в зависимости от типа пользователя.
Производительность является проблемой, и конструкция действует как раздел: к таблице профиля редко обращаются, она размещается на отдельном диске или имеет другую политику сегментирования по сравнению с таблицей пользователей. Не имело бы смысла, если бы хранилище с подчеркиванием было столбцовым.
источник
Обычно считается плохой практикой иметь отношения один на один. Это потому, что вы можете просто представить данные в одной таблице и достичь того же результата.
Однако в некоторых случаях вы не сможете внести эти изменения в таблицу, на которую вы ссылаетесь. В этом случае нет проблем с использованием внешнего ключа в качестве первичного ключа. Было бы полезно иметь составной ключ, состоящий из автоматически увеличивающегося уникального первичного ключа и внешнего ключа.
В настоящее время я работаю над системой, в которой пользователи могут войти в систему и сгенерировать регистрационный код для использования с приложением. По причинам, в которые я не буду вдаваться, я не могу просто добавить необходимые столбцы в таблицу пользователей. Итак, я иду по маршруту один к одному с таблицей кодов.
источник
Да, внешний ключ может быть первичным ключом в случае отношения один к одному между этими таблицами.
источник
Я бы не стал этого делать. Я бы сохранил
profileID
первичный ключ таблицыProfile
Внешний ключ - это просто ссылочное ограничение между двумя таблицами
Можно утверждать, что первичный ключ необходим в качестве цели любых внешних ключей, которые ссылаются на него из других таблиц. Внешний ключ - это набор из одного или нескольких столбцов в любой таблице (не обязательно ключ-кандидат, не говоря уже о первичном ключе этой таблицы), который может содержать значение (я), найденное в столбце (ах) первичного ключа некоторых другая таблица. Итак, у нас должен быть первичный ключ, соответствующий внешнему ключу. Или должны? Единственная цель первичного ключа в паре первичный ключ / внешний ключ - обеспечить однозначное соединение - поддержание ссылочной целостности по отношению к «внешней» таблице, которая содержит ссылочный первичный ключ. Это гарантирует, что значение, на которое ссылается внешний ключ, всегда будет действительным (или нулевым, если разрешено).
http://www.aisintl.com/case/primary_and_foreign_key.html
источник
Это зависит от бизнеса и системы.
Если ваш userId уникален и будет уникальным все время, вы можете использовать userId в качестве первичного ключа. Но если вы когда-нибудь захотите расширить свою систему, это усложнит задачу. Я советую вам добавить внешний ключ в таблицу пользователя, чтобы установить связь с профилем таблицы, вместо добавления внешнего ключа в профиль таблицы.
источник
Краткий ответ: ЗАВИСИТ .... В данном конкретном случае все может быть хорошо. Однако эксперты рекомендуют не делать этого практически каждый раз; включая ваш случай.
Зачем?
Ключи редко бывают уникальными в таблицах, если они являются чужими (происходят из другой таблицы) по отношению к рассматриваемой таблице. Например, идентификатор элемента может быть уникальным в таблице ITEMS, но не в таблице ORDERS, поскольку такой же тип элемента, скорее всего, будет существовать в другом порядке. Аналогичным образом, идентификаторы заказов могут быть уникальными (могут) в таблице ORDERS, но не в какой-либо другой таблице, такой как ORDER_DETAILS, где может существовать заказ с несколькими позициями, и для запроса определенного элемента в определенном порядке вам необходимо объединение двух FK (order_id и item_id) как PK для этой таблицы.
Я не эксперт по БД, но если вы можете логически обосновать наличие автоматически сгенерированного значения в качестве вашего ПК, я бы это сделал. Если это нецелесообразно, то объединение двух (или может быть больше) FK может служить вашим ПК. НО, я не могу представить ни одного случая, когда одно значение FK может быть оправдано как PK.
источник