Нет.
Я бы сказал, что, безусловно, есть случаи, когда ключи с одним полем уступают составным ключам, по крайней мере, для внешних ключей . Это не означает, что вы не должны иметь суррогатный ключ с одним полем, если вы предпочитаете, но я лично предпочитаю, чтобы ключ, который чаще всего используется в качестве цели внешнего ключа, назывался первичным ключом.
Я попытаюсь проиллюстрировать мою точку зрения в следующих примерах, в которых:
brand
автомобиль марки, например, Ford, Toyota и т. д.
dealer
является физическим дилером, привязанным к бренду (например, дилерский центр Ford, продающий только Форды)
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
, связывающую «Форд dealer
» с моделью «Тойота». Добавление 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 )
Теперь правило о том, что дилеры «Форда» могут покупать только автомобили «Форда», естественным образом обеспечивается моделью.
Обратите внимание, что в примере «составные ключи» dealer_id
могут быть или не быть уникальными в соответствии с предпочтениями. Он не обязательно должен быть уникальным (то есть альтернативным ключом), но очень мало теряется при его создании (возможно, немного места для хранения), и это может быть очень удобно, так я обычно его настраиваю, например:
create table dealer( brand_id integer references brand,
dealer_id serial unique,
primary key(brand_id, dealer_id) )