Ho bisogno di una colonna Id separata per questa tabella di "mapping"?


10

Ho una tabella di Producerse una tabella di Products, entrambi i quali sono nella forma:

  • Id - int, chiave primaria
  • Name - nvarchar

Un produttore può trasportare più prodotti, quindi stavo per creare una tabella chiamata ProducerDetailsche avrebbe:

  • ProducerId - int, chiave esterna per Producers.Id
  • ProductId - int, chiave esterna per Products.Id

Poi ho iniziato a interrogarmi, quindi ho pensato di chiedere agli esperti. Sarebbe meglio progettare un database con una Idcolonna aggiuntiva (int, chiave primaria) nella mia ProducerDetailstabella? O non è necessario?

Sto usando SQL-Server 2008 R2 se questo fa alcuna differenza.

EDIT - Credo che la relazione tra queste tabelle sia molte-a-molte, mi dispiace non averlo chiarito. Un produttore può trasportare più tipi di prodotti e lo stesso prodotto può essere prodotto da più produttori diversi.

Mi scuso se questa domanda è eccessivamente semplice, l'integrità referenziale / il design del database non sono il mio punto di forza (anche se sto cercando di migliorarlo).

Risposte:


6

Se hai una relazione uno-a-molti tra produttori e prodotti (in altre parole, un prodotto può appartenere a un solo produttore), sarebbe logico inserire un riferimento di chiave esterna direttamente nella Productstabella:

Uno-a-molti

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

Ma se c'è una possibilità che questa sia una relazione molti-a-molti, la soluzione migliore sarebbe quella di utilizzare un tavolo Join.

Molti-a-molti

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 decidi di utilizzare la tabella Join, non avrai bisogno di avere una chiave aggiuntiva, in quanto la combinazione di ProductId/ProducerIdalla fine sarebbe unica. Potresti usarli come chiave composita, quindi non avresti bisogno di quel Idcampo aggiuntivo in ProductProducer.


1
Tuttavia, non rispondi alla vera domanda: sta chiedendo che c'è un valore nell'avere un idcampo nella sua tabella delle relazioni?
JNK,

@JNK Ho modificato la mia domanda. Se ProductId, ProducerIdè una combinazione unica, non vedo la necessità di aggiungere un'altra chiave artificiale alla tabella Join. Concordato? E penso che, a meno che non fraintenda la domanda, l'OP non ha nemmeno bisogno di usare una tabella Join per questo caso d'uso.
Thomas Stringer,

@ jadarnel27 Ok, grazie per il chiarimento. Ho barrato quella parte della mia risposta (anche se penso che sia prudente avere qualche impronta per ulteriori riferimenti).
Thomas Stringer,

7

No, non vi è alcun valore nell'aggiunta di una "chiave primaria" aggiuntiva a questa tabella. I tuoi join si riferiranno sempre ProducerIDe solo ProductID, quindi è solo un peso morto. A PARER MIO.

Anche se sono d'accordo con @Shark che la tabella di join non sembra nemmeno essere necessaria qui, a meno che tu non stia facendo di tutto per non modificare in alcun modo lo schema delle tabelle esistenti.

A parte questo, penso anche che valga la pena nominare il tuo identificativo principale per intero (ad es. Products.ProductIDInvece di Products.ID) in modo che l'identificatore sia coerentemente nominato in tutto lo schema.


@ jadarnel27: per tutte le altre colonne, sì, è considerata una cattiva pratica. Per la colonna PK, molti preferiscono usare questo stile ( ProductID). Un vantaggio è che quando vedi un SometableID, sai immediatamente a quale tabella fa riferimento. Un altro è che puoi usare la Product JOIN ProducerDetail USING(ProductID)sintassi, anziché la più lungaProduct JOIN ProducerDetail ON Product.ID = ProducerDetail.ProductID
ypercubeᵀᴹ

Siamo spiacenti, penso che USING(ProductID)non sia disponibile in SQL Server, quindi questo punto non si applica.
ypercubeᵀᴹ
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.