2010-11-21 31 views
1

Mon enseignement a dit que je devrais combiner deux clés étrangères en une seule clé primaire. Mais mon processus de pensée est que cela ne permettrait qu'une seule combinaison de chaque clé étrangère. Imaginez que je possède un produit, un achat, un PurchaseDetail.Quand dois-je combiner deux clés étrangères en tant que clé étrangère unique?

Dans PurchaseDetail, j'ai deux clés étrangères, une pour le produit et une pour l'achat. Mon professeur a dit que je devrais combiner ces deux clés étrangères en une seule. Mais un produit ne peut-il pas faire l'objet de nombreux achats différents? Et de nombreux achats ont de nombreux produits?

Je suis confus.

Merci! Edit: C'est le SQL que mon professeur a vu et a ensuite donné son avis. Merci pour les conseils les gars. (J'ai changé l'essentiel en anglais)

create table Purchase 
(
    ID int primary key identity(1,1), 
    IDCliente int foreign key references Cliente(ID), 
    IDEmpleado int foreign key references Empleado(ID), 
    Fecha datetime not null, 
    Hora datetime not null, 
    Amount float not null, 
) 

create table PurchaseDetail 
(
    ID int primary key identity(1,1), 
    IDPurchase int foreign key references Purchase(ID), 
    IDProductOffering int foreign key references ProductOffering(ID), 
    Quantity int not null 
) 

create table Product 
(
    ID int primary key identity(1,1), 
    IDProveedor int foreign key references Proveedor(ID), 
    Nombre nvarchar(256) not null, 
    IDSubcategoria int foreign key references Subcategoria(ID), 
    IDMarca int foreign key references Marca(ID), 
    Fotografia nvarchar(1024) not null 
) 

create table ProductOffering 
(
    ID int primary key identity(1,1), 
    IDProduct int foreign key references Product(ID), 
    Price float not null, 
    OfferDate datetime not null, 
) 

Peut-être que je suis confus au sujet de la bonne conception de schéma de base de données. Merci encore!

+0

Pourquoi voudriez-vous faire cela dans le scénario que vous avez mentionné? Un exemple ou une raison? –

+2

Soit vous avez mal compris votre professeur, ou il est incorrect. –

+0

Oui je suis d'accord avec Mitch –

Répondre

1

j'imagine qu'il propose:

  • produit - une clé primaire (identifiant du produit), ce qui implique un identifiant de produit unique
  • Achat - une clé primaire (id d'achat), ce qui implique un identifiant d'achat unique
  • PurchaseDetail - deux clés étrangères (id produit), (id d'achat), plus une contrainte unique (id produit + id achat)

plus certains affirment que toutes les tables devraient avoir leur propre clé primaire qui ne dépend de rien d'autre (identifiant de détail d'achat). Certains SGBD rendent cela obligatoire. Cela signifie que vous ne pouvez pas avoir deux lignes dans PurchaseDetail qui ont le même produit et le même achat. C'est logique, en supposant qu'il y ait aussi une colonne quantité sur PurchaseDetail, de sorte qu'un achat peut avoir plus d'un de chaque produit.

Notez qu'il ya une différence entre une contrainte unique et une clé étrangère . Une clé étrangère indique simplement qu'il doit y avoir un élément avec cet identifiant dans la table parent - il vous permettra de créer autant de références à cet élément que vous le souhaitez dans la table enfant. Vous devez spécifier que la colonne ou la combinaison de colonnes est unique si vous souhaitez éviter les doublons. D'autre part, une clé primaire implique une contrainte unique.

La syntaxe exacte pour définir tout cela varie selon la langue, mais ce sont les principes.

+0

J'étais sous l'impression qu'une clé Foriegn ne référence qu'une seule table .... –

+0

Je ne me réfère pas à un langage/implémentation particulier, plutôt à la théorie de l'ensemble ... –

+0

@Mitch Wheat: Non nécéssairement, mais dans ce cas, ils sont définitivement deux clés étrangères distinctes. Les ne sont pas utilisés combinés pour référencer n'importe quelle table. – Guffa

0

Je ne suis pas d'accord avec la clé unique, mais il pourrait s'agir d'une clé composée (que j'ai tendance à ne pas aimer). Ils peuvent être deux champs différents chacun limité à l'ID dans les tables correspondantes.

Vous ne savez pas pourquoi le même produit iD devrait être listé plus d'une fois pour un achat unique? N'est-ce pas pourquoi vous indiquez la quantité? Peut-être le besoin de faire un article distinct pour un achat et un rabais?

0

Je crois que leur réponse a été correcte. Mais il y a une autre option.Vous pouvez ajouter une nouvelle colonne de clé primaire à la table des détails, il ressemble à ceci:

detail_id int (PK) 
product_id int (FK) 
purchsae_id int (FK) 

Ce n'est pas vraiment nécessaire, mais il pourrait être utile si vous devez jamais besoin de faire référence à la table des détails comme clé étrangère - ayant un seul champ de clé primaire fait pour les index plus petits et la référence de clé étrangère (et ils sont un peu plus faciles à taper).

0

Peut-être qu'il propose un grand nombre à plusieurs table où il est la clé primaire est composé des clés étrangères aux tables mappées:

PurchaseDetail: 

ProductId   int (FK) 
PurchaseId   int (FK) 
PK(ProductId, PurchaseId) 

Cela peut aussi être modélisé comme

PurchaseDetail: 

PurchaseDetailId int (PK, Identity) 
ProductId   int (FK) 
PurchaseId   int (FK) 

La deuxième forme est utile si vous voulez faire référence aux détails d'achat ailleurs dans votre modèle, et aussi dans certains SGBDR il est avantageux d'avoir un PK sur un nombre croissant montoniquement croissant.

+0

C'est ce que j'ai fait, et il a donné la rétroaction (la base de cette question). S'il vous plaît voir mon edit. : P J'ai fait ce que vous suggérez, mais il semblait ne pas l'aimer. –

0

Cela dépend des données que vous devez représenter.

Si vous utilisez les deux clés étrangères comme clé primaire pour les détails d'achat, un produit ne peut apparaître qu'une fois dans chaque achat. Un achat peut toutefois contenir de nombreux produits et un produit peut encore apparaître dans de nombreux achats.

Si le détail de l'achat contient plus d'informations, vous devrez peut-être être en mesure d'utiliser un produit plusieurs fois dans un achat. Par exemple si le détail d'achat contient la taille et la couleur, et vous voulez par un T-shirt rouge taille XL et un T-shirt bleu taille S.