Должна ли каждая таблица иметь суррогатный/искусственный первичный ключ с одним полем?

dba.stackexchange https://dba.stackexchange.com/questions/6108

Вопрос

Я понимаю одно преимущество суррогатных/искусственных ключей в целом — они не меняются и это может быть очень удобно.Это верно независимо от того, являются ли они одним или несколькими полями, при условии, что они являются «искусственными».

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

Чтобы внести ясность, этот вопрос не об искусственных и естественных ключах, а о том, должны ли все искусственные ключи быть однополе

Это было полезно?

Решение 2

Нет.

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

Я попытаюсь проиллюстрировать свою точку зрения в следующих примерах, в которых:

  • brand Автомобильный марка, например, Ford, Toyota и т. Д.
  • dealer это физический дилерский центр, привязанный к бренду (например, дилерский центр Ford продает только Fords)
  • model тип автомобиля, например, Ford Focus, Ford Fiesta и т. Д.
  • stock Современное количество автомобилей для каждого дилерского центра

Если мы создадим суррогатный ключ для одного поля для dealer а также model следующим образом:

create table brand( brand_id integer primary key );

create table dealer( dealer_id integer primary key, 
                     brand_id integer references brand )

create table model( model_id integer primary key, 
                    brand_id integer references brand )

create table stock( model_id integer references model, 
                    dealer_id integer references dealer, 
                    quantity integer,
                      primary key(model_id, dealer_id) )

тогда можно вставить ряд в stock это связывает Ford dealer к модели «Toyota». Добавление brand_id references brand к stock только усугубляет проблему. С другой стороны, если мы сохраним внешний ключ как часть первичного ключа следующим образом:

create table brand( brand_id integer primary key );

create table dealer( brand_id integer references brand, 
                     dealer_id integer, 
                       primary key(brand_id, dealer_id) )

create table model( brand_id integer references brand, 
                    model_id integer, 
                      primary key(brand_id, model_id) )

create table stock( brand_id integer, 
                    model_id integer, 
                    dealer_id integer, 
                    quantity integer,
                      primary key(brand_id, model_id, dealer_id),
                      foreign key(brand_id, model_id) references model,
                      foreign key(brand_id, dealer_id) references dealer )

Теперь правило, которое дилеры «Ford» могут оставить только автомобили Ford «Ford», естественно применяется моделью.

Обратите внимание, что в примере «композитных клавиш», dealer_id Может или не может быть уникальным, согласно предпочтению. Это не должно быть уникальным (то есть альтернативный ключ), но очень мало теряется, делая это так (возможно, немного места для хранения), и это может быть очень удобно, так что я обычно его настроил, например:

create table dealer( brand_id integer references brand, 
                     dealer_id serial unique, 
                       primary key(brand_id, dealer_id) )

Другие советы

Я собираюсь сказать нет, не всегда, но в большинстве случаев да..

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

  • Таблицы чистых пересечений.Если есть нет Риск пересечения является целью иностранного ключа, и, если риск перекрестки привлечет независимых атрибутов практически нет или нет (т.е.Что -то другое, кроме FK, до двух родительских таблиц), тогда вы можете уйти с рук, используя комбинацию FK в качестве PK с достоверной уверенностью.
  • Таблицы поиска со статическими бизнес-ключами.Если у вас есть поиск
    таблица с уникальным бизнес-ключом, который привязан к вашему внешнему
    бизнес и который имеет нулевой шанс когда-либо измениться для любого
    практической цели, то использование бизнес-ключа напрямую может сделать
    дела обстоят проще.Примером может быть список штатов или провинций.
    коды или список номеров стандарта ANSI и т. д.
  • Таблицы, содержащие данные, консолидированные из нескольких независимых источников.Если в вашей системе есть много источников данных, которые должны быть объединены в одну таблицу, скажем, в Head Office, то иногда вам нужен составной ключ, который включает значение клавиши Source System и код, указывающий, что была исходная система.

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

  • Ситуации, когда вам необходимо объединить данные из нескольких, независимых источников.Чтобы избежать ключевых столкновений, вы можете использовать гииды вместо ключей идентификации.
  • Ситуации, когда вы вынуждены использовать нечетные ключевые представления.Допустим, у вас есть база данных номерных знаков.Вашим ключом может быть буквенно-цифровое значение, а не чистое число.
  • Ситуации, когда некоторые внешние требования заставляют вас применить сжатие к значению ключа.Вместо использования 10 цифр для Int32 вы можете использовать шесть базовых 36 цифр.

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

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

"это зависит"

Да: Поля суррогатной идентичности/автономного подсчета хороши, когда естественный ключ широкий и не нулечный. ПРИМЕЧАНИЕ. Это предполагает смешение «PK» и кластерного индекса, которое происходит по умолчанию в SQL Server, Sybase и т. Д.

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

Конечно, BrainDead Orm (читай: (n) Спеценат) может превзойти эти правила ...

РЕДАКТИРОВАТЬ: Чтение вопроса еще раз

Многие/много таблицы с двумя суррогатными родительными ключами будут иметь многочисленную колонку PK.
Тем не менее, это не нуждается в другой суррогатной колонке.

Если в таблице есть клавиша суррогата (идентификация и т. Д.), то она не должна быть несколькими столбцами.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с dba.stackexchange
scroll top