Нужен ли отдельный столбец Id для этой таблицы «сопоставления»?

10

У меня есть таблица Producersи таблица Products, которые имеют вид:

  • Id - int, первичный ключ
  • Name - нварчар

Производитель может нести несколько Продуктов, поэтому я собирался создать таблицу под названием ProducerDetails:

  • ProducerId - int, Внешний ключ для Producers.Id
  • ProductId - int, Внешний ключ для Products.Id

Затем я начал задавать себе вопросы, поэтому я решил спросить экспертов. Было бы лучше, если бы в базе данных был дополнительный Idстолбец (int, Primary key) в моей ProducerDetailsтаблице? Или это не нужно?

Я использую SQL-Server 2008 R2, если это вообще что-то меняет.

РЕДАКТИРОВАТЬ - Я полагаю, что отношения между этими таблицами будут многие-многие, извините, я не прояснил это. Производитель может нести несколько типов продуктов, и один и тот же продукт может производиться несколькими разными производителями.

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

Джош Дарнелл
источник

Ответы:

6

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

Один ко многим

create table Producer
(
    id int identity(1, 1) not null primary key clustered,
    Name varchar(100) not null
)
go

create table Product
(
    id int identity(1, 1) not null,
    Name varchar(100) not null,
    ProducerId int not null foreign key references Producer(id)
)
go

Но если есть вероятность, что это будет отношение «многие ко многим», то лучшим вариантом будет использование таблицы «Присоединение».

Многие-ко-многим

create table Producer
(
    id int identity(1, 1) not null primary key clustered,
    Name varchar(100) not null
)
go

create table Product
(
    id int identity(1, 1) not null primary key clustered,
    Name varchar(100) not null
)
go

create table ProductProducer
(
    ProductId int not null foreign key references Product(id),
    ProducerId int not null foreign key references Producer(id)
)
go

-- adding the primary key also ensures uniqueness
alter table ProductProducer
add constraint PK_ProductProducer 
primary key (ProductId, ProducerId)
go

Если вы решите использовать таблицу Join, вам не понадобится дополнительный ключ, поскольку комбинация в ProductId/ProducerIdконечном итоге будет уникальной. Вы можете использовать их в качестве составного ключа, поэтому вам не нужно это дополнительное Idполе в ProductProducer.

Томас Стрингер
источник
1
Вы не отвечаете на фактический вопрос, хотя - он спрашивает, есть ли смысл иметь idполе в его таблице отношений?
JNK
@JNK Я отредактировал свой вопрос. Если ProductId, ProducerIdэто уникальная комбинация, я не вижу необходимости добавлять еще один искусственный ключ в таблицу Join. Согласовано? И я думаю, что, если я не пойму вопрос неправильно, OP даже не нужно использовать таблицу Join для этого варианта использования.
Томас Стрингер
@ jadarnel27 Хорошо, спасибо за разъяснения. Я вычеркнул эту часть моего ответа (хотя я думаю, что было бы разумно иметь некоторый след для дальнейшего использования).
Томас Стрингер
7

Нет, нет смысла добавлять дополнительный «первичный ключ» в эту таблицу. Ваши соединения только когда-либо будут ссылаться ProducerIDи ProductID, так что это просто мертвый вес. ИМХО.

Хотя я согласен с @Shark, что объединяющая таблица здесь даже не нужна, если только вы не стараетесь никоим образом не изменять схему существующих таблиц.

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

Аарон Бертран
источник
@ jadarnel27: Да, для всех остальных столбцов это считается плохой практикой. Для столбца PK многие предпочитают использовать этот стиль ( ProductID). Одним из преимуществ является то, что когда вы видите SometableID, вы сразу знаете, к какой таблице это относится. Другое заключается в том, что вы можете использовать Product JOIN ProducerDetail USING(ProductID)синтаксис вместо более длинногоProduct JOIN ProducerDetail ON Product.ID = ProducerDetail.ProductID
ypercubeᵀᴹ
Извините, я думаю, что USING(ProductID)это не доступно в SQL-Server, поэтому этот пункт не применяется.
ypercubeᵀᴹ