Подтвердить что ты не робот

Почему единственный первичный ключ лучше составных?

Почему отказ от составных ключей в пользу всех таблиц с использованием одного первичного ключа с именем id? Потому что обычно все ORM следуют этому.

ИЗМЕНИТЬ

Я только начал изучать рубин на рельсах, а в книге гибкого развития прагматичным была линия: --- Рельсы действительно не работают слишком хорошо, если в каждой таблице нет числового первичного ключа. Менее суетливое название столбца. Тот же тип строки, который я читал, когда учил Учение.

EDIT2 Также проверьте эту ссылку. Я все больше и больше путаюсь в этом: --- Составляющие первичные ключи в сравнении с уникальным полем идентификатора объекта

Из приведенной выше ссылки: -

* первичный ключ должен быть постоянным и бессмысленным; не суррогатные ключи обычно терпят одно или оба требования, в конечном итоге

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

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

EDIT: есть дополнительная проблема, более практичная, чем философская. Во многих случаях вы каким-то образом найдете определенную строку, затем позже обновите ее или снова найдете (или и то, и другое). С составными ключами есть больше данных, чтобы отслеживать и больше ограничений в предложении WHERE для повторного поиска или обновления (или удаления). Также возможно, что один из ключевых сегментов может измениться за это время!. С суррогатным ключом всегда сохраняется только одно значение (суррогатный идентификатор) и по определению оно не может меняться, что значительно упрощает ситуацию. *

4b9b3361

Ответ 1

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

Большинство людей используют суррогатный первичный ключ в качестве автоматического генерации int, поскольку он изолирует первичный ключ от когда-либо нуждающегося в изменении, например, если вы сделаете PK именем пользователя, а позже изменили свое юридическое имя. Вам нужно будет обновить PK и все столбцы FK, чтобы отобразить новое имя. если вы использовали суррогатный первичный ключ, вы просто обновляете имя пользователя в одном месте (потому что таблицы соединяются в int не с именем).

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

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

Ответ 2

Единственное реальное ограничение, с которым я столкнулся с использованием составных ключей, использует выражение IN с подзапросом. Это проблема, потому что подзапрос в выражении IN должен возвращать один столбец (по крайней мере, в T-SQL).

SELECT
    emp.Name,
    emp.UserDomain,
    emp.UserID
FROM
    employee emp
WHERE
    ???? IN (SELECT e.UserDomain, e.UserID FROM ... /* some complex 
                                                       non-correlated subquery 
                                                       or CTE */
            )

Конечно, всегда есть проблемы, но иногда это может быть неприятно.

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

Ответ 3

Вы можете использовать оба. В некоторых случаях при создании связи между сущностью вы можете использовать обе сущности в качестве составного ключа.

Как правило, я использую созданные идентификаторы для сущностей и составных ключей для отношений.

Ответ 4

Ну, это в основном о том, чтобы держать JOINs просто - что проще понять:

SELECT
   p.ID, p.Name, p.City,
   c.ID, c.Country, c.ISOCode
FROM
   dbo.Parent p
INNER JOIN
   dbo.Child c on c.ParentID = p.ID

или

SELECT
   p.ID, p.Name, p.City,
   c.ID, c.Country, c.ISOCode
FROM
   dbo.Parent p
INNER JOIN
   dbo.Child c ON c.ParentName = p.Name
     AND c.ParentCity = p.City
     AND c.ParentCountry = p.Country

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

Ответ 5

Я работал над приложением с первичным ключом из 11 столбцов. Всегда было весело переписывать список много раз, каждый раз, когда я хотел гарантировать, что я обновляю одну строку. Это был драйвер ошибок, MS-Access не смог справиться с более чем 10 столбцами в ПК и т.д.

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

Ответ 6

  • Для ORM единичная идентификация столбец с постоянным именем table_id проще, чем составной ключ. Но каждая хорошая поддержка ORM составные клавиши.

  • Простой PK может быть легко "автоинкремент" по базе данных. Это не выполняется для составного ключ.

  • Простую PK также проще использовать в запросы. Когда вам нужно присоединиться, вы нужно использовать только один столбец отношения.

Это не означает, что простые PK лучше, чем композитные.

Ответ 7

Объекты программирования OO имеют личность независимо от их содержимого. Строки (кортежи) в реляционных базах данных определяются только их содержимым. Поэтому, когда вы действительно делаете ORM, то есть отображаете объекты с объектно-ориентированного языка программирования в реляционную базу данных, должен быть предоставлен дополнительный идентификатор, отличный от полей и/или свойств, которые объект имеет в программе, - если только один или несколько из них как-то известно, идентифицировать объекты однозначно.

Ответ 8

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

Традиционная теория реляционных баз данных в основном касалась "естественных" ключей (те, которые имеют смысл с точки зрения бизнес-точки), и в этом случае составные ключи часто встречаются... естественно.

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

Ответ 9

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

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

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