Benötige ich eine separate ID-Spalte für diese Zuordnungstabelle?

9

Ich habe eine Tabelle von Producersund eine Tabelle von Products, die beide die Form haben:

  • Id - int, Primärschlüssel
  • Name - nvarchar

Ein Produzent kann mehrere Produkte führen, daher wollte ich eine Tabelle mit dem Namen erstellen ProducerDetails, die Folgendes hätte:

  • ProducerId - int, Fremdschlüssel zu Producers.Id
  • ProductId - int, Fremdschlüssel zu Products.Id

Dann fing ich an, mich selbst zu befragen, also dachte ich, ich würde die Experten fragen. Wäre es besser, eine zusätzliche IdSpalte (int, Primärschlüssel) in meiner ProducerDetailsTabelle zu haben? Oder ist das unnötig?

Ich verwende SQL-Server 2008 R2, wenn dies überhaupt einen Unterschied macht.

BEARBEITEN - Die Beziehung zwischen diesen Tabellen wäre viele zu viele, glaube ich. Tut mir leid, dass ich das nicht klargestellt habe. Ein Hersteller kann mehrere Arten von Produkten führen, und dasselbe Produkt kann von mehreren verschiedenen Herstellern hergestellt werden.

Ich entschuldige mich, wenn diese Frage zu einfach ist. Referenzielle Integrität / Datenbankdesign ist nicht meine Stärke (obwohl ich versuche, das zu verbessern).

Josh Darnell
quelle

Antworten:

5

Wenn Sie eine Eins-zu-Viele-Beziehung zwischen Herstellern und Produkten haben (mit anderen Worten, ein Produkt kann nur einem Hersteller gehören), ist es sinnvoll, nur eine Fremdschlüsselreferenz direkt in Ihre ProductsTabelle aufzunehmen:

Eins-zu-viele

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

Wenn es jedoch eine Chance gibt, dass dies eine Viele-zu-Viele-Beziehung ist, ist es am besten, eine Join-Tabelle zu verwenden.

Viel zu viel

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

Wenn Sie sich für die Join-Tabelle entscheiden, benötigen Sie keinen zusätzlichen Schlüssel, da die Kombination von ProductId/ProducerIdletztendlich eindeutig wäre. Sie können sie als zusammengesetzten Schlüssel verwenden, sodass Sie dieses zusätzliche IdFeld nicht benötigen ProductProducer.

Thomas Stringer
quelle
1
Sie beantworten die eigentliche Frage jedoch nicht - er fragt, ob es sinnvoll ist, ein idFeld in seiner Beziehungstabelle zu haben.
JNK
@JNK Ich habe meine Frage bearbeitet. Wenn ProductId, ProducerIdes sich um eine eindeutige Kombination handelt, muss der Join-Tabelle kein weiterer künstlicher Schlüssel hinzugefügt werden. Einverstanden? Und ich denke, wenn ich die Frage nicht falsch verstehe, muss das OP für diesen Anwendungsfall nicht einmal eine Join-Tabelle verwenden.
Thomas Stringer
@ jadarnel27 Ok, danke für die Klarstellung. Ich habe diesen Teil meiner Antwort durchgestrichen (obwohl ich es für ratsam halte, einen Fußabdruck als weitere Referenz zu haben).
Thomas Stringer
7

Nein, das Hinzufügen eines zusätzlichen "Primärschlüssels" zu dieser Tabelle hat keinen Wert. Ihre Joins beziehen sich immer nur auf ProducerIDund ProductID, es ist also nur Eigengewicht. MEINER BESCHEIDENEN MEINUNG NACH.

Obwohl ich @Shark zustimme, dass die Join-Tabelle hier nicht einmal benötigt zu werden scheint, es sei denn, Sie geben sich alle Mühe, das Schema der vorhandenen Tabellen in keiner Weise zu ändern.

Abgesehen davon halte ich es auch für sinnvoll, Ihren primären Bezeichner vollständig zu benennen (z. B. Products.ProductIDanstelle von Products.ID), damit der Bezeichner im gesamten Schema konsistent benannt wird.

Aaron Bertrand
quelle
@ jadarnel27: Für alle anderen Spalten gilt dies als schlechte Praxis. Für die PK-Spalte bevorzugen viele diesen Stil ( ProductID). Ein Vorteil ist, dass Sie, wenn Sie eine sehen SometableID, sofort wissen, auf welche Tabelle sie sich bezieht. Eine andere ist, dass Sie die Product JOIN ProducerDetail USING(ProductID)Syntax anstelle der längeren verwenden könnenProduct JOIN ProducerDetail ON Product.ID = ProducerDetail.ProductID
ypercubeᵀᴹ
Entschuldigung, ich denke, das USING(ProductID)ist in SQL-Server nicht verfügbar, daher gilt dieser Punkt nicht.
Ypercubeᵀᴹ