Preciso de uma coluna de ID separada para esta tabela de "mapeamento"?

10

Eu tenho uma tabela de Producerse uma tabela de Products, ambas com a forma:

  • Id - int, chave primária
  • Name - nvarchar

Um produtor pode transportar vários produtos, então eu criaria uma tabela chamada ProducerDetailsque teria:

  • ProducerId - int, chave estrangeira para Producers.Id
  • ProductId - int, chave estrangeira para Products.Id

Então comecei a me questionar, então pensei em perguntar aos especialistas. Seria melhor design de banco de dados ter uma Idcoluna adicional (int, chave primária) na minha ProducerDetailstabela? Ou isso é desnecessário?

Estou usando o SQL-Server 2008 R2, se isso fizer alguma diferença.

EDIT - O relacionamento entre essas tabelas seria muitos para muitos, creio, desculpe por não ter deixado isso claro. Um produtor pode transportar vários tipos de produtos e o mesmo produto pode ser produzido por vários produtores diferentes.

Peço desculpas se essa pergunta é muito simples, a integridade referencial / o design do banco de dados não é o meu ponto forte (embora eu esteja tentando melhorar isso).

Josh Darnell
fonte

Respostas:

6

Se você tiver um relacionamento um-para-muitos entre Produtores e Produtos (em outras palavras, um produto pode pertencer apenas a um produtor), faria sentido colocar apenas uma referência de chave estrangeira diretamente em sua Productstabela:

Um para muitos

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

Mas se houver uma chance de que esse seja um relacionamento de muitos para muitos, sua melhor aposta será usar uma tabela de junção.

Muitos para muitos

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

Se você decidir ir com a tabela Ingressar, não precisará ter uma chave adicional, pois a combinação de ProductId/ProducerIdelas será única. Você poderia usá-los como uma chave composta, para não precisar desse Idcampo adicional ProductProducer.

Thomas Stringer
fonte
11
Você não responde à pergunta real - ele está perguntando: existe algum valor em ter um idcampo em sua tabela de relações?
JNK
@JNK Eu editei minha pergunta. Se ProductId, ProducerIdfor uma combinação única, não vejo a necessidade de adicionar outra chave artificial à tabela Join. Acordado? E acho que, a menos que esteja entendendo mal a pergunta, o OP nem precisa usar uma tabela Join para esse caso de uso.
Thomas Stringer
@ jadarnel27 Ok, obrigado pelo esclarecimento. Eu riscou essa parte da minha resposta (embora eu ache prudente ter alguma pegada para referência adicional).
Thomas Stringer
7

Não, não há valor em adicionar uma "chave primária" adicional a esta tabela. Suas junções sempre se referem a ProducerIDe ProductID, portanto, é apenas peso morto. NA MINHA HUMILDE OPINIÃO.

Embora eu concorde com o @Shark que a tabela de junção nem parece ser necessária aqui, a menos que você esteja se esforçando para não alterar o esquema das tabelas existentes de forma alguma.

Como um aparte, também acho que vale a pena nomear seu identificador principal por completo (por exemplo, em Products.ProductIDvez de Products.ID) para que o identificador seja denominado de forma consistente em todo o esquema.

Aaron Bertrand
fonte
@ jadarnel27: Para todas as outras colunas, sim, é considerado uma prática ruim. Para a coluna PK, muitos preferem usar esse estilo ( ProductID). Uma vantagem é que, quando você vê um SometableID, sabe imediatamente a qual tabela se refere. Outra é que você pode usar a Product JOIN ProducerDetail USING(ProductID)sintaxe, em vez do maisProduct JOIN ProducerDetail ON Product.ID = ProducerDetail.ProductID
ypercubeᵀᴹ
Desculpe, acho que o USING(ProductID)não está disponível no SQL-Server, portanto esse ponto não se aplica.
ypercubeᵀᴹ