2015-02-27 6 views
2

Я знаю, что его просили много раз, но я хотел объяснить свой сценарий и посмотреть, есть ли какие-либо преимущества использования столбца Identity в качестве первичного ключа вместо использования составного первичного ключа.Композитный первичный ключ или первичный суррогатный ключ со следующим сценарием?

Я сейчас читаю два текстовых файла: File1 имеет Make & Модель автомобиля, в то время как File2 имеет Make, Model, Year of car. Make, Model в File2 всегда будет в File1.

Итак, я создал таблицу [Car], состоящую из столбцов MakeId (identity), Make и Model. Данные для таблицы [Car] выглядят так. Данные, приведенные в [Автомобиль] является точной копией File1:

[MakeId]  [Make]  [Model] 
1    HONDA  ACCORD 
2    HONDA  CIVIC 
3    FORD  FOCUS 
4    FORD  ESCORT 

Для Файл2, я создал таблицу [CarYear] с колоннами CarYearId (идентичности), Make, Model, Year. Данные в [CarYear] является точной копией Файл2:

[CarYearId] [Make]  [Model]  [Year] 
1   HONDA  ACCORD  2002 
2   HONDA  ACCORD  2001 
3   HONDA  ACCORD  2004 
4   HONDA  CIVIC  1998 
5   FORD  FOCUS  1998 
6   FORD  ESCORT  2001 
7   FORD  ESCORT  2002 

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

+0

Об этом было задано много (http://stackoverflow.com/questions/1383062/composite-primary-key и http://stackoverflow.com/questions/337503/whats-the-best-practice-for- первичные клавиши-в-таблицы). Честно говоря, я бы рекомендовал сделать это, как он лучше всего подходит для вашей ситуации. Возможно, вам стоит подумать о нормализации данных. В случае необходимости модели и модели могут быть в их собственной таблице с таблицей отношений. – sgeddes

+0

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

ответ

2

Файл1 сделал & Модель автомобиля. , ,

Таким образом, представляющие интерес данные выглядят так.

 
make  model 
-- 
HONDA  ACCORD 
HONDA  CIVIC 
FORD  FOCUS 
FORD  ESCORT 

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

Является ли ключ-кандидат здесь {make, model} или {model}, эта таблица находится в 6NF. Если мы предположим, что единственным ключом-кандидатом является {make, model}, я мог бы реализовать его, как это, в стандартном SQL.

create table car_models (
    make varchar(15) not null, 
    model varchar(15) not null, 
    primary key (make, model) 
); 

File2 имеет Марка, модель, год автомобиля.

Таким образом, представляющие интерес данные выглядят так.

 
make  model  year 
-- 
HONDA  ACCORD  2002 
HONDA  ACCORD  2001 
HONDA  ACCORD  2004 
HONDA  CIVIC  1998 
FORD  FOCUS  1998 
FORD  ESCORT  2001 
FORD  ESCORT  2002 

После предположений о ключе в предыдущей таблице, эта таблица имеет только один потенциальный ключ, и он имеет только один дополнительный атрибут. Он тоже находится в 6NF. Версия SQL может выглядеть так.

create table car_model_years (
    make varchar(15) not null, 
    model varchar(15) not null, 
    model_year integer not null 
    check (model_year between 1886 and 2099), 
    primary key (make, model, model_year), 
    foreign key (make, model) references car_models (make, model) 
); 

Эти таблицы не имеют не избыточных данных. Вы не можете удалить любые столбцы, не нарушая семантики или не подрывая целостность данных. Внешние ключи повторяются по строкам «car_model_years», но это не избыточно - это точно, какие внешние ключи для.

Есть ли причина, по которой я не должен использовать Make, Model для составного первичного ключа?

В качестве теоретического (реляционного) вопроса нет, нет. Если вы начинаете с 6NF, добавление суррогатного идентификационного номера денормализовывает этот стол. (6NF требует одного кандидата ключ.) Даже если вы сделать добавить суррогатной идентификационный номер, вы еще должны объявить {марке, модели}, как not null unique. Невозможность объявить, что ограничение приводит к тому, что таблица может выглядеть так.

 
model_id make model 
-- 
1   Honda Accord 
2   Honda Accord 
3   Honda Accord 

С практической точки зрения, а не теоретической (реляционной) материи, эти 6NF таблицы, вероятно, лучше, чем denormalizations из них с использованием суррогатных идентификационных номеров. Например, запросы на «car_model_years», которые основаны на make и модели, обычно используют сканирование только для индекса - им вообще не придется читать базовую таблицу.

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


1. «...« регулярный »relvar находится в 6NF тогда и только тогда, когда он состоит из одного ключа, плюс максимум один дополнительный атрибут». Дата, CJ, База данных по глубине: реляционная теория для практиков, стр. 147. Регулярный реввар является невременным рельефом.

+0

Спасибо за информацию. Две причины отказа от использования суррогатного ключа заключались в следующем: 1) мне нужно было бы искать основную таблицу для каждой вставки для получения идентификатора PK, 2) я имею тенденцию делать много специальных запросов, поэтому удаление ненужных объединений делает моя работа проще. Я понимаю, что есть избыточные данные, но плюсы перевешивают минусы. – rbhat

+0

@rbhatup: там нет избыточных данных. Найдите эту страницу для «нет избыточных данных». –

Смежные вопросы