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

Почему составные первичные ключи все еще существуют?

Мне поручено перенести базу данных в ERP среднего класса. Новая система использует составные первичные ключи здесь и там и с прагматической точки зрения, почему?

По сравнению с автогенерированными идентификаторами я могу видеть только негативные аспекты;

  • Внешние ключи становятся размытыми.
  • Более сложная миграция или db-редизайн
  • Негибкий, как изменение бизнеса. (У моего автомобиля нет reg.plate..)
  • Такая же целостность достигается с ограничениями.

Это возврат к концепции дизайна ключей конфет, которые я тоже не вижу.

Является ли это привычкой/артефактом из флоппи-дней (сводя к минимуму пространство/индексы), или я чего-то не хватает?

//редактировать// Просто нашел хороший SO-post: Составные первичные ключи в сравнении с уникальным полем идентификатора объекта //

4b9b3361

Ответ 1

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

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

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

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

Ответ 2

Композитные клавиши требуются, если ваши первичные ключи не являются суррогатными и неотъемлемо um, составными, то есть разбиваются на несколько несвязанных частей.

Некоторые примеры в реальном мире:

  • Таблицы ссылок "многие ко многим", в которых первичные ключи состоят из ключей связанных объектов.

  • Приложения с несколькими арендаторами, когда tenant_id является частью первичного ключа для каждого объекта, и сущности могут быть связаны только внутри одного и того же арендатора (с ограничениями внешнего ключа).

  • Приложения, обрабатывающие сторонние данные (с уже предоставленными первичными ключами)

Обратите внимание, что логически все это может быть достигнуто с помощью ограничения UNIQUE (дополнительно к суррогату PRIMARY KEY).

Однако существуют некоторые специфические для реализации вещи:

  • Некоторые системы не позволят a FOREIGN KEY ссылаться на все, что не является PRIMARY KEY.

  • Некоторые системы будут кластеризовать таблицу только на PRIMARY KEY, поэтому создание PRIMARY KEY приведет к повышению производительности запросов, связанных с композитом.

Ответ 3

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

Например (чистый пример - так что мы здесь не говорим о дизайне БД), скажем, что у вас есть таблица ORDER и ORDER_ITEM. Если вы используете ProductId и LineNumber ( UPDATE: и как Педро упомянул OrderId или даже лучше OrderNumber) в качестве составного первичного ключа в ORDER_ITEM, тогда в таблице перекрестных ссылок для SHIPPING, вы могли бы иметь ProductId в SHIPPING_ORDERITEM. Это может значительно повысить производительность, если, например, вы исчерпали этот продукт и вам нужно узнать все продукты этого ProductId, которые необходимо отправить без необходимости вступать.

С другой стороны, если вы используете суррогатный ключ, вам нужно присоединиться к нему, и в итоге вы получите очень неэффективный план выполнения SQL, где нужно выполнить поиск по закладкам по нескольким индексам.

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

Ответ 4

Природные первичные ключи хрупкие.

Предположим, что мы построили систему вокруг естественного PK (CountryCode, PhoneNumber), и через несколько лет нам нужно добавить расширение или изменить PK на один столбец: Электронная почта. Если эти столбцы PK распространяются на все дочерние таблицы, это становится очень дорогостоящим.

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

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

Ответ 5

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

Ответ 6

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

Ex. У вас есть список частей, которые вы покупаете у поставщиков. Вы могли бы создать таблицу поставщиков и частей, например:

SUPPLIER
SupplierId
SupplierName

PART
PartId
PartName
SupplierId

О, о. Таблица деталей позволяет дублировать данные. Поскольку вы использовали суррогатный ключ, который был автогенерирован, вы не применяете тот факт, что часть от поставщика должна вводиться только один раз. Вместо этого вы должны создать таблицу PART следующим образом:

PART
SupplierId
SupplierPartId
PartName

В этом примере ваши детали поступают от конкретных поставщиков, и вы хотите применить правило: "Один поставщик может поставлять только одну деталь один раз" в таблице PARTS. Следовательно, составной ключ. Комбинированный ключ предотвращает случайный дубликат элемента.

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

Ответ 7

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

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

Пример: система для организации сторон LAN

Система поддерживает несколько партий LAN с теми же людьми и организаторами, которые участвуют в этом:

CREATE TABLE users ( users_id serial PRIMARY KEY, ... );

И есть несколько сторон:

CREATE TABLE parties ( parties_id serial PRIMARY KEY, ... );

Но большая часть другого материала должна нести информацию о том, с какой стороной она связана:

CREATE TABLE ticket_types (
    ticket_types_id serial,
    parties_id integer REFERENCES parties,
    name text,
    ....
    PRIMARY KEY(ticket_types_id, parties_id)
);

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

CREATE TABLE attendances (
    attendances_id serial,
    parties_id integer REFERENCES parties,
    ticket_types_id integer,
    PRIMARY KEY (attendances_id, parties_id),
    FOREIGN KEY (ticket_types_id, parties_id) REFERENCES parties
);

Ответ 8

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

Если, например, у вас есть таблица, содержащая данные о транспортных средствах, применяя суррогатную версию VehicleId, то, что означает быть транспортным средством с точки зрения данных. Когда вы указываете VehicleId = 1, вы, безусловно, говорите о каком-то транспортном средстве, но знаем ли мы, что это Chevy Impala 2008 года или Ford F-150 1991 года? Нет. Можно ли в любой момент изменить базовые данные любого транспортного средства №1? Да.

Ответ 9

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

  • Многие из многих присоединяются к таблицам. В любом случае, как правило, для пары ключей требуется уникальный ключ. В некоторых случаях в ключ могут быть включены дополнительные столбцы.
  • Слабые дочерние таблицы. Такие вещи, как строки заказов, не выдерживают самостоятельно. В этом случае я использую первичный ключ таблицы parent (orders) в составной таблице.

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