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



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



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




  • внешние ключи становятся размытыми

  • более сложная миграция или БД-редизайны

  • негибкий, как изменение бизнеса. (У моей машины нет Рег.тарелка..)

  • такая же целостность лучше достиганная с ограничения.


Он возвращается к концепции дизайна candiate keys, в которой я не вижу смысла.



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



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

849   9  

9 ответов:

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

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

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

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

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

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

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

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

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

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

однако, есть некоторые конкретные вещи реализации:

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

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

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

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

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

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

естественные первичные ключи являются хрупкими.

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

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

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

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

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

SUPPLIER
SupplierId
SupplierName

PART
PartId
PartName
SupplierId

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

PART
SupplierId
SupplierPartId
PartName

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

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

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

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

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

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

пример: система для организации 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
);

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

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

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

Comments

    Ничего не найдено.