Чи потрібен мені окремий стовпець Id для цієї таблиці «відображення»?


10

У мене є таблиця Producersта таблиця Products, обидві форми:

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

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

  • ProducerId - int, Іноземний ключ до Producers.Id
  • ProductId - int, Іноземний ключ до Products.Id

Тоді я почав розпитувати себе, тому думав, що запитаю експертів. Чи було б краще для дизайну бази даних мати додатковий Idстовпчик (int, первинний ключ) у моїй ProducerDetailsтаблиці? Або це зайве?

Я використовую SQL-Server 2008 R2, якщо це взагалі має значення.

EDIT - Зв'язок між цими таблицями був би багатьом-багатьом, я вважаю, вибачте, що я цього не зрозумів. Виробник може перевозити кілька видів продукції, і той самий товар може вироблятися декількома різними виробниками.

Прошу вибачення, якщо це питання надто просте, референтна цілісність / дизайн бази даних не є моїм сильним костюмом (хоча я намагаюся це вдосконалити).

Відповіді:


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

Якщо ви вирішите перейти до таблиці приєднанняProductId/ProducerId , вам не знадобиться мати додатковий ключ, оскільки комбінація в кінцевому рахунку буде унікальною. Ви можете використовувати їх як складений ключ, тому це додаткове Idполе вам не знадобиться ProductProducer.


1
Ти не відповідаєш на власне запитання - він запитує, чи є значення у наявності idполя у таблиці відношень?
JNK

@JNK Я відредагував своє запитання. Якщо ProductId, ProducerIdце унікальне поєднання, я не бачу необхідності додавати ще один штучний ключ до таблиці приєднання. Згоден? І я думаю, якщо я не розумію питання, ОП навіть не потребує використання таблиці приєднання для цього випадку використання.
Томас Стрінгер

@ 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-сервер недоступний, тому ця точка не застосовується.
ypercubeᵀᴹ
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.