Моя текущая структура базы данных использует первичный ключ из нескольких столбцов для использования существующих данных (которые в любом случае будут уникальными) вместо создания дополнительного столбца, присваивающего каждой записи произвольный ключ. Я знаю, что это разрешено, но мне было интересно, если это практика, которую я, возможно, захочу использовать осторожно и, возможно, избегать (так же, как goto в C).
Итак, какие недостатки я могу видеть в этом подходе или причины, по которым мне может потребоваться один столбец?
database-design
COVAR
источник
источник
Ответы:
Обычно, когда у вас есть таблица с первичным ключом, состоящим из нескольких столбцов, это результат соединения таблицы (многие-ко-многим), которая была повышена до своей собственной сущности (и, следовательно, заслуживает своего собственного первичного ключа). Многие утверждают, что любая таблица соединений ДОЛЖНА быть сущностью по умолчанию, но это обсуждение другого дня.
Давайте посмотрим на гипотетические отношения многих ко многим:
Студент * --- * Класс
(Студент может быть в нескольких классах, класс может иметь несколько студентов).
Между этими двумя таблицами будет таблица соединений с именем StudentClass (или ClassStudent в зависимости от того, как вы ее напишите). Иногда вы хотите отслеживать такие вещи, как когда ученик был в классе. Таким образом, вы добавите его в таблицу StudentClass. На этом этапе StudentClass стал уникальным объектом ... и ему должно быть присвоено имя для распознавания, например, Enrollment.
Студент 1 --- * Зачисление * --- 1 класс
(у студента может быть много Зачислений, каждая Зачисление предназначена для одного класса (или наоборот, класс может иметь много Записей, каждая Зачисление предназначена для одного Студента).
Теперь вы можете задавать вопросы о том, сколько студентов было зачислено в класс химии 101 в прошлом году? Или в какие классы был зачислен студент Джон Доу, когда учился в университете Акме? Это было возможно без отдельного первичного ключа, но если у вас есть первичный ключ для зачисления, то будет проще запросить эти зачисления (по идентификатору), сколько учеников получили проходной балл?
Определение того, заслуживает ли объект ПК, сводится к тому, сколько запросов (или манипуляций) вы сделаете для этого объекта. Скажем, например, вы хотели прикрепить выполненные задания для ученика в классе. Логическое место для прикрепления этого объекта (Назначение) - объект регистрации. Предоставление регистрации своим собственным первичным ключом упростит запросы назначения.
источник
Имеет смысл иметь отдельный столбец id. Когда вы хотите получить что-то из таблицы базы данных, это проще сделать:
чем выбрать любую из таблицы, где col1 = 'val1' и col2 = 'val2' и col3 = 'val3'
Например, в веб-приложении это выглядит как URL:
или вот так:
источник
SELECT
запросам. И, B) , я не имею ни малейшего представления, как это на самом деле вызывает какие-либо требования к URL (если вы не работаете с плохой платформой). Мои URL не содержат строк запроса?id=13
, не говоря уже о?col1=val1&col2=val2&col3=val3
.В основном вы спрашиваете, должны ли вы использовать суррогатные или натуральные ключи (в вашем случае это звучит как составные натуральные ключи). Вот отличная статья: http://www.agiledata.org/essays/keys.html
Я предпочитаю суррогатные ключи, потому что они упрощают администрирование в течение всей жизни БД (вам никогда не придется беспокоиться о последствиях изменения значения ключей, что никогда не должно происходить, но происходит в любой реальной системе, где задействованы люди). Однако , если в БД много таблиц «поиска» (т. Е. Таблиц, которые в основном являются парами ключ: значение), то суррогатные ключи могут стать громоздкими, потому что вам нужно объединить эти таблицы в запрос, чтобы получить значимые результаты.
Например, допустим, у вас есть две сущности: адрес и страна.
select * from Address where CountryCode = 'US'
select Address.* from Address join Country on Address.CountryID = Country.ID where Country.Code = 'US'
Мне удобно использовать естественные ключи для справочных таблиц и суррогатные ключи для всего остального, если я почти уверен, что естественные ключи не будут меняться слишком часто, если вообще когда-либо.
источник
Это зависит от того, как вы получаете доступ к данным. Если вы выполняете много частичных поисков ключей (где вы выбираете записи на основе, скажем, только двух из трех ключей), вам нужно сохранить составные ключи. OTOH, если у вас много связей 1: 1 с другими таблицами, вероятно, имеет смысл иметь суррогатный ключ.
источник
Мне нравится всегда иметь суррогатный первичный ключ для каждой таблицы. Но не так много «веских» причин, чтобы это усилить, что я слышал.
Один раз, когда у меня когда-либо был укус естественного ключа с несколькими столбцами, был с ORM. Иногда у меня возникают проблемы с первичным ключом из нескольких столбцов, использующим Linq To Entities.
источник
Никогда не говори никогда, но объединение в 4 столбца это боль. Чем больше у вас столбцов с интеллектуальными данными, тем больше вероятность того, что эти значения могут измениться. Базы данных могут быть настроены для поддержания ссылочной целостности с помощью каскадных обновлений.
Вы всегда можете создать другой индекс для обработки уникальных значений.
Производительность, вероятно, незначительна в большинстве случаев, но вы можете протестировать свои запросы как с ключом Surragate, так и без него.
источник
Мне трудно найти вескую причину для поручения отдельного ключа, но, как вы сказали, многие люди вставили его.
Я не нахожу это помощи (особенно с хранилищем) при работе с таблицами фактов / подробностей. Канонический пример таблицы фактов продаж с (customer_key, store_key, product_key) с количеством не имеет большого смысла иметь ключ уровня записи.
источник
Наличие PK как автоинкремента int уменьшает хлопоты, если вы обнаружите, что ваш составной ключ в действительности может иметь дубликаты.
источник
В 2002 году была хорошая дискуссия о « Спроси Тома» . Это специфично для Oracle, но более широкое обсуждение относится к любой базе данных, которую вы используете.
источник