Должна ли каждая таблица иметь суррогатный/искусственный первичный ключ с одним полем?
-
16-10-2019 - |
Вопрос
Я понимаю одно преимущество суррогатных/искусственных ключей в целом — они не меняются и это может быть очень удобно.Это верно независимо от того, являются ли они одним или несколькими полями, при условии, что они являются «искусственными».
Однако иногда кажется, что использование автоинкрементного целочисленного поля в качестве первичного ключа каждой таблицы является вопросом политики.Всегда ли это лучшая идея иметь такую однополе ключ и почему (или почему бы и нет)?
Чтобы внести ясность, этот вопрос не об искусственных и естественных ключах, а о том, должны ли все искусственные ключи быть однополе
Решение 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.
Тем не менее, это не нуждается в другой суррогатной колонке.
Если в таблице есть клавиша суррогата (идентификация и т. Д.), то она не должна быть несколькими столбцами.
Вы можете иметь супер -ключ, который включает в себя суррогат, но это было бы для обеспечения соблюдения других правил (например, подтипы)