Ai-je besoin d'une colonne d'ID distincte pour cette table de «mappage»?

10

J'ai un tableau de Producerset un tableau de Products, qui sont tous les deux de la forme:

  • Id - int, clé primaire
  • Name - nvarchar

Un producteur peut transporter plusieurs produits, donc j'allais créer une table appelée ProducerDetailsqui aurait:

  • ProducerId - int, clé étrangère vers Producers.Id
  • ProductId - int, clé étrangère vers Products.Id

Puis j'ai commencé à me poser des questions, alors j'ai pensé demander aux experts. Serait-il préférable de concevoir une base de données pour avoir une Idcolonne supplémentaire (int, clé primaire) dans ma ProducerDetailstable? Ou est-ce inutile?

J'utilise SQL-Server 2008 R2 si cela fait une différence.

EDIT - La relation entre ces tables serait plusieurs à plusieurs je crois, désolé de ne pas l'avoir précisé. Un producteur peut transporter plusieurs types de produits et le même produit peut être fabriqué par plusieurs producteurs différents.

Je m'excuse si cette question est trop simple, l'intégrité référentielle / la conception de base de données n'est pas mon point fort (bien que j'essaie d'améliorer cela).

Josh Darnell
la source

Réponses:

6

Si vous avez une relation un-à-plusieurs entre les producteurs et les produits (en d'autres termes, un produit ne peut appartenir qu'à un seul producteur), il serait logique de simplement mettre une référence de clé étrangère directement dans votre Productstableau:

Un à plusieurs

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

Mais s'il y a une chance que ce soit une relation plusieurs-à-plusieurs, alors votre meilleur pari serait d'utiliser une table Join.

Plusieurs à plusieurs

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

Si vous décidez d'utiliser la table Join, vous n'auriez pas besoin d'avoir une clé supplémentaire, car la combinaison de ProductId/ProducerIdserait finalement unique. Vous pouvez les utiliser comme clé composite, vous n'avez donc pas besoin de ce Idchamp supplémentaire ProductProducer.

Thomas Stringer
la source
1
Vous ne répondez pas à la question réelle - il demande s'il y a une valeur à avoir un idchamp dans sa table de relation?
JNK
@JNK J'ai modifié ma question. S'il ProductId, ProducerIds'agit d'une combinaison unique, je ne vois pas la nécessité d'ajouter une autre clé artificielle à la table Join. D'accord? Et je pense qu'à moins que je ne comprenne mal la question, l'OP n'a même pas besoin d'utiliser une table Join pour ce cas d'utilisation.
Thomas Stringer
@ jadarnel27 Ok, merci pour la clarification. J'ai barré cette partie de ma réponse (bien que je pense qu'il est prudent d'avoir une certaine empreinte pour plus de référence).
Thomas Stringer
7

Non, il n'y a aucune valeur à ajouter une "clé primaire" supplémentaire à ce tableau. Votre jointures ne sont jamais à se référer à ProducerIDet ProductID, donc il est juste poids mort. A MON HUMBLE AVIS.

Bien que je convienne avec @Shark que la table de jointure ne semble même pas nécessaire ici, à moins que vous ne fassiez tout votre possible pour ne pas modifier le schéma des tables existantes de quelque manière que ce soit.

En passant, je pense également qu'il vaut la peine de nommer votre identifiant principal en entier (par exemple Products.ProductIDau lieu de Products.ID) afin que l'identifiant soit nommé de manière cohérente dans tout le schéma.

Aaron Bertrand
la source
@ jadarnel27: Pour toutes les autres colonnes, oui, c'est considéré comme une mauvaise pratique. Pour la colonne PK, beaucoup préfèrent utiliser ce style ( ProductID). Un avantage est que lorsque vous voyez un SometableID, vous savez immédiatement à quel tableau il se réfère. Un autre est que vous pouvez utiliser la Product JOIN ProducerDetail USING(ProductID)syntaxe, au lieu de la plus longueProduct JOIN ProducerDetail ON Product.ID = ProducerDetail.ProductID
ypercubeᵀᴹ
Désolé, je pense que le USING(ProductID)n'est pas disponible dans SQL-Server, donc ce point ne s'applique pas.
ypercubeᵀᴹ