Каковы недостатки использования составного / составного первичного ключа?
=========================================================================

 Каковы недостатки использования составного / составного первичного ключа?

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

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



 один простой (с одним столбцом) и один составной (с несколькими столбцами). Ваш вопрос в этом контексте выглядит следующим образом: «Какой недостаток я могу испытать, если я выберу один ключ как первичный и выберу составной ключ?»

 Во-первых, подумайте, нужно ли вам вообще продвигать ключ: «само существование`PRIMARY KEY` в SQL кажется исторической случайностью. Согласно автору Крису Дейту, самые ранние воплощения SQL не имели каких-либо ключевых ограничений и`PRIMARY KEY` только позже был добавлен в стандарты SQL. Разработчики стандарта, очевидно, взяли термин от E.F.Codd, который изобрел его, хотя первоначальное представление Кодда к тому времени было заброшено! (Первоначально Кодд предлагал, чтобы внешние ключи ссылались только на один ключ - первичный ключ, - но эта идея была забыта и проигнорирована, поскольку она широко признана бессмысленным ограничением). "[Source:[лог Дэвида Портаса: долой первичные ключи?](http://blogs.conchango.com/davidportas/archive/2006/09/14/Down-with-Primary-Keys_3F00_.aspx)

 Во-вторых, какие критерии вы бы применили, чтобы выбрать, какой ключ в таблице должен быть «основным»? В SQL выбор ключа`PRIMARY KEY` является произвольным и зависит от продукта. В ACE / Jet (например, MS Access) двумя основными и часто конкурирующими факторами является то, хотите ли вы использовать`PRIMARY KEY` для предпочтения кластеризации на диске или для того, чтобы столбцы, содержащие ключ, отображались жирным шрифтом на рисунке «Отношения» в пользовательском интерфейсе MS Access; Я в меньшинстве, думая, что стратегия индекса превосходит красивую картинку :) В SQL Server вы можете указать кластерный индекс независимо от`PRIMARY KEY` и, по-видимому, нет никаких преимуществ для конкретного продукта. Единственным оставшимся преимуществом является то, что вы можете опустить столбцы`PRIMARY KEY` при создании внешнего ключа в SQL DDL, поведение стандарта SQL-92 и, в любом случае, для меня не так уж важно (возможно, это еще одна вещь, которую они добавили в стандарт, потому что эта функция уже широко распространена в SQL) продукты?) Итак, дело не в том, чтобы искать недостатки, скорее, вы должны посмотреть, что Преимущество, если есть, ваш продукт SQL дает`PRIMARY KEY`. Другими словами, единственный недостаток при выборе неправильного ключа - то, что вы можете упустить данное преимущество.

Third, вы скорее намекаете на использование искусственного / синтетического / суррогатного ключа для реализации в вашей физической модели ключа-кандидата из вашей логической модели, потому что вы обеспокоены тем, что если вы будете использовать естественный ключ в внешних ключах и соединениях таблиц, будут штрафы за производительность ? Это совершенно другой вопрос, и он во многом зависит от вашей «религиозной» позиции по вопросу о естественных ключах в SQL.



когда вы видите его на диаграмме, он менее читабелен; когда вы используете его в соединении запросов, они менее читабельны когда вы используете его для ключа foregein, вы должны добавить проверочное ограничение для всех атрибутов, которые должны быть нулевыми или не нулевыми (если только один равен null, ключ не проверяется)usualy требуется больше памяти при использовании его в качестве внешнего ключа некоторый инструмент не управляет составным ключом

 я то, что вы запутаете чертовски типичные генераторы кода ORM.



Может вызвать больше проблем для нормализации  [2НФ](https://en.wikipedia.org/wiki/2NF), " Обратите внимание, что если в таблице 1NF нет составных ключей-кандидатов (ключей-кандидатов, состоящих из более чем одного атрибута), таблица автоматически получает значение 2NF ") Больше ненужного дублирования данных. Если ваш составной ключ состоит из 3 столбцов, вам необходимо создать 3 одинаковых столбца в каждой таблице, где он используется в качестве внешнего ключа. Обычно можно избежать с помощью суррогатных ключей  [Читайте об их преимуществах и недостатках](https://en.wikipedia.org/wiki/Surrogate_key)) Я могу представить хороший сценарий для составного ключа - в таблице, представляющей отношение N: N, например «Студенты - классы», и ключ в промежуточной таблице будет (StudentID, ClassID). Но если вам нужно хранить больше информации о каждой паре (например, историю всех оценок ученика в классе), вы, вероятно, введете суррогатный ключ.

 кальным ненулевым ограничением на натуральный составной ключ.

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



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

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

 На глубокой схеме ключи могут быть достаточно широкими - я видел один раз 8 столбцов.

 Изменения в значениях первичного ключа могут быть проблематичными в процессах ETL, загружаемых из системы. Примером, который я когда-то видел, было приложение MIS, извлекаемое из системы страхового страхования. В некоторых случаях заказчик может повторно использовать запись политики, изменяя идентификатор политики. Это было частью первичного ключа таблицы. Когда это происходит, нагрузка хранилища не знает, что было старым значением, поэтому она не может сопоставить новые данные с ним. Разработчик должен был искать в журналах аудита, чтобы определить измененное значение.

 Большинство проблем с не синтетическими первичными ключами вращаются вокруг проблем, когда значения PK записей изменяются. Наиболее полезные применения несинтетических значений - это когда схема базы данных предназначена для использования, например, M.I.S. приложение, в котором составители отчетов используют таблицы напрямую. В этом случае короткие значения с фиксированными доменами, такие как коды валют или даты, могут быть разумно размещены непосредственно в таблице для удобства.



 

 Слишком далеко, это может привести к чрезмерному усложнению вставок (каждый ключ ДОЛЖЕН существовать) и документации, а присоединенные чтения могут быть подозрительными, если они не завершены.

 Иногда это может указывать на некорректную модель данных (действительно ли составной ключ ДЕЙСТВИТЕЛЬНО описывает данные?)

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