Составные первичные ключи против уникального поля идентификатора объекта - PullRequest
71 голосов
/ 01 октября 2008

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

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

Может кто-нибудь высказать свое мнение или добавить большую глубину к этой теме?

Ответы [ 15 ]

2 голосов
/ 02 октября 2008

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

Это почти наверняка бессмыслица, но, возможно, она связана с проблемой конкуренции за индексные блоки при назначении приращенных номеров ПК с высокой скоростью из разных сеансов. Если это так, то поможет индекс REVERSE KEY, хотя и за счет увеличения размера индекса из-за изменения алгоритма разделения на блоки. http://download.oracle.com/docs/cd/B19306_01/server.102/b14220/schema.htm#sthref998

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

2 голосов
/ 01 октября 2008

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

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

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

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

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

1 голос
/ 24 октября 2008

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

В эти дни я обычно добавляю свойство «RowID» к каждой таблице - это поле является GUID и уникально для каждой строки. Это НЕ первичный ключ - это естественный ключ (если это возможно). Однако любые слои ORM, работающие поверх этой базы данных, могут использовать RowID для идентификации своих производных объектов.

Таким образом, вы можете иметь:

CREATE TABLE dbo.Invoice (
  CustomerId varchar(10),
  CustomerOrderNo varchar(10),
  InvoiceAmount money not null,
  Comments nvarchar(4000),
  RowId uniqueidentifier not null default(newid()),

  primary key(CustomerId, CustomerOrderNo)
)

Итак, ваш администратор баз данных счастлив, ваш архитектор ORM счастлив, а целостность вашей базы данных сохраняется!

1 голос
/ 02 октября 2008

@ JeremyDWill

Спасибо за то, что вы предоставили столь необходимый баланс в дискуссии. В частности, спасибо за информацию о DOMAIN s.

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

0 голосов
/ 08 июня 2014

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

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

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

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

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

...