Frage

Ich habe die folgenden Tabellen in meiner Datenbank, die eine Viele-zu-Viele-Beziehung haben, die durch eine Verbindungstabelle ausgedrückt wird, die Fremdschlüssel zu den Primärschlüsseln jeder der Haupttabellen enthält:

  • Widget:WidgetID (PK), Titel, Preis
  • Benutzer:Benutzer-ID (PK), Vorname, Nachname

Gehen Sie davon aus, dass jede Benutzer-Widget-Kombination einzigartig ist.Ich sehe zwei Optionen für die Strukturierung der Verbindungstabelle, die die Datenbeziehung definiert:

  1. UserWidgets1:UserWidgetID (PK), WidgetID (FK), UserID (FK)
  2. UserWidgets2:WidgetID (PK, FK), BenutzerID (PK, FK)

Option 1 verfügt über eine einzelne Spalte für den Primärschlüssel.Dies erscheint jedoch unnötig, da die einzigen in der Tabelle gespeicherten Daten die Beziehung zwischen den beiden Primärtabellen sind und diese Beziehung selbst einen eindeutigen Schlüssel bilden kann.Dies führt zu Option 2, die einen zweispaltigen Primärschlüssel hat, aber die einspaltige eindeutige Kennung von Option 1 verliert.Optional könnte ich der ersten Tabelle auch einen zweispaltigen eindeutigen Index (WidgetID, UserID) hinzufügen.

Gibt es einen wirklichen Leistungsunterschied zwischen den beiden oder gibt es einen Grund, einen Ansatz dem anderen für die Strukturierung der UserWidgets-Many-to-Many-Tabelle vorzuziehen?

War es hilfreich?

Lösung

In beiden Fällen haben Sie nur einen Primärschlüssel.Der zweite ist ein sogenannter zusammengesetzter Schlüssel.Es gibt keinen guten Grund für die Einführung einer neuen Kolumne.In der Praxis müssen Sie einen eindeutigen Index für alle Kandidatenschlüssel führen.Durch das Hinzufügen einer neuen Spalte entsteht lediglich Wartungsaufwand.

Gehen Sie zu Option 2.

Andere Tipps

Ich persönlich würde haben die Spalte „Synthetischer/Ersatzschlüssel“ in Viele-zu-Viele-Tabellen aus folgenden Gründen:

  • Wenn Sie in Ihren Entitätstabellen numerische synthetische Schlüssel verwendet haben, gewährleistet die Verwendung derselben in den Beziehungstabellen die Konsistenz im Design und in der Namenskonvention.
  • In Zukunft kann es vorkommen, dass die Many-to-Many-Tabelle selbst zur übergeordneten Entität einer untergeordneten Entität wird, die einen eindeutigen Verweis auf eine einzelne Zeile benötigt.
  • Es wird nicht wirklich so viel zusätzlichen Speicherplatz beanspruchen.

Der synthetische Schlüssel ist kein Ersatz für den natürlichen/zusammengesetzten Schlüssel und wird auch nicht zu diesem PRIMARY KEY für diese Tabelle, nur weil es die erste Spalte in der Tabelle ist, daher stimme ich dem Artikel von Josh Berkus teilweise zu.Allerdings bin ich nicht der Meinung, dass natürliche Schlüssel immer gute Kandidaten dafür sind PRIMARY KEY's und sollten auf keinen Fall verwendet werden, wenn sie als Fremdschlüssel in anderen Tabellen verwendet werden sollen.

Option 2 verwendet einen einfachen zusammengesetzten Schlüssel, Option 1 verwendet a Ersatzschlüssel.Option 2 wird in den meisten Szenarien bevorzugt und kommt dem realistischen Modell nahe, da es sich um einen guten Kandidatenschlüssel handelt.

Es gibt Situationen, in denen Sie möglicherweise einen Ersatzschlüssel verwenden möchten (Option 1).

  1. Sie glauben nicht, dass der zusammengesetzte Schlüssel im Laufe der Zeit ein guter Kandidat für den Schlüssel ist.Insbesondere bei zeitlichen Daten (Daten, die sich im Laufe der Zeit ändern).Was wäre, wenn Sie der UserWidget-Tabelle eine weitere Zeile mit derselben UserId und WidgetId hinzufügen möchten?Denken Sie an Employment(EmployeeId,EmployeeId) – es würde in den meisten Fällen funktionieren, es sei denn, jemand würde zu einem späteren Zeitpunkt wieder für denselben Arbeitgeber arbeiten
  2. Wenn Sie Nachrichten/Geschäftstransaktionen oder ähnliches erstellen, die einen einfacheren Schlüssel für die Integration erfordern.Replikation vielleicht?
  3. Wenn Sie Ihre eigenen Überwachungsmechanismen (oder ähnliches) erstellen möchten und nicht möchten, dass die Schlüssel zu lang werden.

Als Faustregel gilt: Bei der Modellierung von Daten werden Sie feststellen, dass die meisten assoziativen Entitäten (viele zu viele) das Ergebnis eines Ereignisses sind.Person nimmt Beschäftigung auf, Artikel wird in den Warenkorb gelegt usw.Die meisten Ereignisse haben eine zeitliche Abhängigkeit vom Ereignis, wobei das Datum oder die Uhrzeit relevant sind. In diesem Fall ist ein Ersatzschlüssel möglicherweise die beste Alternative.

Wählen Sie also Option 2, stellen Sie jedoch sicher, dass Sie über das vollständige Modell verfügen.

Ich stimme mit den vorherigen Antworten überein, möchte aber noch eine Bemerkung hinzufügen.Wenn Sie der Beziehung weitere Informationen hinzufügen und mehr Beziehungen zwischen denselben beiden Entitäten zulassen möchten, benötigen Sie Option eins.

Wenn Sie beispielsweise nachverfolgen möchten, wie oft Benutzer 1 das Widget 664 in der Userwidget-Tabelle verwendet hat, sind Benutzer-ID und Widget-ID nicht mehr eindeutig.

Welchen Nutzen hat ein Primärschlüssel in diesem Szenario?Ziehen Sie die Option ohne Primärschlüssel in Betracht:UserWidgets3:WidgetID (FK), BenutzerID (FK)

Wenn Sie Eindeutigkeit wünschen, verwenden Sie entweder den zusammengesetzten Schlüssel (UserWidgets2) oder eine Eindeutigkeitsbeschränkung.

Der übliche Leistungsvorteil eines Primärschlüssels besteht darin, dass Sie die Tabelle häufig anhand des Primärschlüssels abfragen, was schnell ist.Bei Viele-zu-Viele-Tabellen erfolgt die Abfrage normalerweise nicht nach dem Primärschlüssel, sodass sich kein Leistungsvorteil ergibt.Viele-zu-viele-Tabellen werden anhand ihrer Fremdschlüssel abgefragt. Daher sollten Sie das Hinzufügen von Indizes für WidgetID und UserID in Betracht ziehen.

Option 2 ist die richtige Antwort, es sei denn, Sie haben einen wirklich guten Grund, einen Ersatz-Zahlenschlüssel hinzuzufügen (was Sie in Option 1 getan haben).

Spalten mit numerischen Ersatzschlüsseln sind keine „Primärschlüssel“.Primärschlüssel sind technisch gesehen eine Kombination von Spalten, die einen Datensatz innerhalb einer Tabelle eindeutig identifizieren.

Jeder, der eine Datenbank erstellt, sollte diesen Artikel lesen http://it.toolbox.com/blogs/database-soup/primary-keyvil-part-i-7327 von Josh Berkus, um den Unterschied zwischen numerischen Ersatzschlüsselspalten und Primärschlüsseln zu verstehen.

Meiner Erfahrung nach besteht der einzige wirkliche Grund für das Hinzufügen eines numerischen Ersatzschlüssels zu Ihrer Tabelle darin, dass Ihr Primärschlüssel ein zusammengesetzter Schlüssel ist und als Fremdschlüsselreferenz in einer anderen Tabelle verwendet werden muss.Erst dann sollten Sie überhaupt daran denken, der Tabelle eine zusätzliche Spalte hinzuzufügen.

Immer wenn ich eine Datenbankstruktur sehe, in der jede Tabelle eine „id“-Spalte hat, besteht die Möglichkeit, dass sie von jemandem entworfen wurde, der sich mit dem relationalen Modell nicht auskennt, und sie zeigt unweigerlich eines oder mehrere der in Joshs Artikel genannten Probleme an.

Ich würde mit beiden gehen.

Lass mich ausreden:

Der zusammengesetzte Schlüssel ist offensichtlich der nette und richtige Weg, wenn es darum geht, die Bedeutung Ihrer Daten widerzuspiegeln.Keine Frage.

Jedoch:Ich hatte alle möglichen Probleme damit, dass der Ruhezustand ordnungsgemäß funktioniert, es sei denn, Sie verwenden einen einzigen generierten Primärschlüssel – einen Ersatzschlüssel.

Ich würde also logische und physische Daten verwenden Modell.Der logische hat den zusammengesetzten Schlüssel.Das physische Modell – das das logische Modell implementiert – verfügt über den Ersatzschlüssel und Fremdschlüssel.

Da jede Benutzer-Widget-Kombination einzigartig ist, sollten Sie dies in Ihrer Tabelle darstellen, indem Sie die Kombination eindeutig machen.Mit anderen Worten, entscheiden Sie sich für Option 2.Andernfalls haben Sie möglicherweise zwei Einträge mit denselben Widget- und Benutzer-IDs, aber unterschiedlichen Benutzer-Widget-IDs.

Die Benutzerwidget-ID in der ersten Tabelle wird nicht benötigt, da die Einzigartigkeit, wie Sie sagten, aus der Kombination der Widget-ID und der Benutzer-ID resultiert.

Ich würde die zweite Tabelle verwenden, die Fremdschlüssel behalten und einen eindeutigen Index für Widget-ID und Benutzer-ID hinzufügen.

Also:

userwidgets( widgetid(fk), userid(fk),
             unique_index(widgetid, userid)
)

Der Verzicht auf den zusätzlichen Primärschlüssel bringt einen gewissen Leistungsgewinn mit sich, da die Datenbank den Index für den Schlüssel nicht berechnen müsste.Im obigen Modell wird dieser Index (über den unique_index) zwar immer noch berechnet, aber ich glaube, dass dies einfacher zu verstehen ist.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top