Anleitung zur Verwendung von zusammengesetzten Schlüsseln zum Identifizieren von Zeilen

8

Ist es eine gute Praxis (oder hätte dies nachteilige Auswirkungen), einen Satz von 4 Spalten zu verwenden, um eine Zeile als eindeutig zu identifizieren (eine ist ein Foriegn-Schlüssel, die anderen drei sind Float-Datentypen)? Ich versuche, eine Tabelle zu erstellen, die (mit 4 verknüpften Schlüsseln) einen eindeutigen Eintrag in der Tabelle beschreibt. Ich bin gespannt, ob dies ein guter Angriffsplan ist oder ob es einen besseren Weg gibt.

Stellen Sie sich zu visuellen Zwecken die folgende Tabelle vor. Wir haben Inventargegenstände, die wie in der folgenden Tabelle organisiert sind: ( [K]ist ein Symbol für den Primärschlüssel, die Zeilen sind Beziehungen)

    Sheet_Class        Sheet_Type         Sheet_Size
    ===========        ==========         ==========
[K] Sheet_Class-.  [K] Sheet_Type--.  [K] Sheet_Size
                 '---- Sheet_Class  '---- Sheet_Type
                                          Length
                                          Width
                                          Thickness

Die Daten können sich folgendermaßen darstellen, aber der Kürze halber habe ich ausgeschlossen, die verknüpften Spalten zu übernehmen:

 Sheet_Class    Sheet_Type    Sheet_Size                        (Tables)
[Sheet_Class]  [Sheet_Type]  [Length], [Width], [Thickness]     (Column Values)
=============  ============  ==============================

Aluminum
               5052-H32
                             48, 96, 0.032
                             48, 96, 0.040
                             48, 96, 0.063

               6061-T6
                             60, 120,0.032
                             60, 120,0.040
                             60, 120,0.063

Steel
               1018-CRS
                             48, 96, 0.018
                             48, 96, 0.023
                             48, 96, 0.031

So wie es aussieht (und ich habe es in meinem "Schema" oben gezeigt), verwende ich einen einfachen (automatisch inkrementierten) ganzzahligen Primärschlüssel für Einträge in der Sheet_Size- Tabelle. Ich möchte jedoch wissen, ob es besser ist, stattdessen eine Kombination der Spalten Sheet_Type , Length , Width und Thickness zu verwenden. Angesichts der Tatsache, dass jeder Eintrag in Sheet_Size all diese einzigartigen Eigenschaften aufweisen sollte und dass ein automatisch inkrementierendes Feld dies nicht gut genug demonstrieren würde, ist dies der beste Weg?

Wenn ich die Situation nicht gut genug erkläre, lassen Sie es mich bitte wissen. Ich muss diese Teile (Klasse vs. Typ vs. tatsächliche Lagergröße) eines inventarisierten Materials für andere logische Zwecke aufteilen, bin aber für jede andere Art von Feedback bereit.

Jede Anleitung wäre dankbar.

Update (08-12-2011)

Nachdem die Antworten veröffentlicht wurden, habe ich beschlossen, eine Kombination aus Marks Antwort und X-Zeros Antwort zu erstellen . Ich entschied, dass es eine gute Idee ist, die Spalten Länge, Breite und Dicke eindeutig zu beschränken, aber ich mag auch die Idee, Materialgrößen in eindeutige Zeilen aufzuteilen und sie mit einer Beziehung zu verknüpfen.

Leider kann ich nicht beide Antworten akzeptieren, daher werde ich X-Zeros akzeptieren, um (was ich fühle) das Problem kritischer zu betrachten und eine Schemaanpassung anzubieten.

Vielen Dank an alle für Ihre Antworten.

Brad Christie
quelle

Antworten:

6

Nachdem ich darüber nachgedacht habe, würde ich Ihre Tabellenstruktur nur geringfügig überarbeiten.
Überarbeiten Sie zunächst Ihre Tabelle mit Blattgröße:

Sheet_size
===========
Id
Length
Width
Thickness

Zweitens erstellen Sie eine Beziehungstabelle für Blattgröße / Typ:

Sheet_size_type
================
Sheet_Type_Id
Sheet_Size_Id

Erstellen Sie dann die folgenden Einschränkungen:

  1. Der Primärschlüssel (und Index) von Sheet_sizesollte die ID-Spalte sein
  2. Es sollte eine Art eindeutiger Schlüssel (und Index) für die Dimensionen in erzwungen werden Sheet_size. Betrachten Sie, sind zwei Blätter mit den Abmessungen (48, 96, .5) und (96, 48, .5) gleich (dh spielt die Richtung der Abmessungen eine Rolle)? Diese Art von Problem kann schwierig zu erzwingen sein, wenn die Spalten als Teil des Primärschlüssels verwendet werden, wird jedoch bei Verwendung von Einschränkungen und gespeicherten Prozeduren leichter zu handhaben.
  3. Der Primärschlüssel (und der Index) von Sheet_size_typesollten beide Fremdschlüssel verwenden, beginnend mit dem Schlüssel mit der niedrigeren Kardinalität (wahrscheinlich sheet_typeanhand Ihres Beispiels). Möglicherweise möchten Sie einen zusätzlichen Index in die andere Richtung, der jedoch möglicherweise nicht erforderlich ist.

Diese Überarbeitung spart Ihnen Datenbankspeicherplatz (im Verhältnis zur Anzahl der Blatttypen mit derselben Größe) und sollte den Overhead nicht zu stark beeinträchtigen.


Wenn Sie einen floatDatentyp verwenden, gibt es andere potenzielle Bedenken hinsichtlich Gleichheit / Eindeutigkeit , da die Ungenauigkeit Sie unerwartet stören kann. Sie sollten überlegen, ob ein Festkommatyp mit einer bestimmten Genauigkeit besser geeignet ist.

Uhrwerk-Muse
quelle
Ich hatte vor, die Länge und Breite auf einen einzigen (möglichen zwei) Dezimalpunkt zu beschränken, und die Dicke würde sich (höchstens) auf drei erstrecken. Darüber hinaus werden wir zu endlich (und die Aktie selbst kommt sowieso nie mit den beschriebenen Zahlen an). Abgesehen davon mag ich den Gedanken, die Blattgrößen aufzubrechen, aber das Problem, mit dem ich konfrontiert bin, sind die anderen beteiligten Spalten (die ich ausgeschlossen habe). (brauche mehr Platz, siehe nächster Beitrag)
Brad Christie
Da es sich um eine Liste inventarisierter Bestände handelt, muss ich andere Informationen wie Dichte und Kosten / lb (die stark vom Typ abhängen (und sogar die Dicke) angeben. Zum Beispiel könnte "Stahl" / "1018" 0,55 $ / lb betragen bei einer Dicke von 0,018 bis 0,125 Zoll, wird jedoch zu 0,65 USD / lb, sobald die Dicke über 0,125 Zoll hinausgeht (und dies kann sich auch zwischen einer Blattgröße von 48 Zoll x 96 Zoll x 0,250 Zoll von 1018 gegenüber 5052-H32 unterscheiden). In Ihrem Beispiel Ich hätte nur einen Eintrag für ein 48 "x96" x0.125 "(obwohl ich nehme an, dass die Beziehungstabelle diese zusätzlichen Metriken haben könnte)
Brad Christie
Wenn Sie nur eine kleine Anzahl von Dezimalstellen benötigen, verwenden Sie eine feste Genauigkeit. Ja, hier würden Sie (in diesem Fall) solche Informationen einfügen (Kosten sind beispielsweise eine Abhängigkeit von Blatttyp und -größe), obwohl Sie möglicherweise zusätzliche Tabellen generieren möchten, auf die verwiesen werden kann. Möglicherweise möchten Sie auch benutzerdefinierte Datentypen (z. B. Dichte) erstellen, damit die Benutzer nicht versuchen, Ihre Daten auf unerwartete Weise abzufragen.
Uhrwerk-Muse
6

Sieht aus wie ein natürliche vs Surrogatschlüssel Entscheidung, Meinung , auf dem von Bereich betrachtet und praktisch zu akademisch , auf Dogma der Grenze. Abhängig vom RDBMS gibt es Überlegungen für das physische Modell, die erhebliche Auswirkungen auf die Leistung haben können, z. B. die Auswahl von Clusterschlüsseln in SQL Server.

Wenn ich persönlich einen engen Kandidatenschlüssel mit einem einzelnen Attribut habe, bin ich versucht, ihn zu verwenden. Breite und / oder zusammengesetzte Schlüssel, standardmäßig füge ich dem Modell einen Ersatz hinzu. In Ihrem Fall würde ich für die Identitätsspalte in Sheet_Size als primären Clusterschlüssel und eine eindeutige Einschränkung für Typ / Länge / Breite / Dicke stimmen.

Mark Storey-Smith
quelle
Wie erzwingt Unique, dass die Spalten (wenn sie kombiniert werden) keine doppelten Werte haben können, da der Zeile jetzt ein "beliebiger" Schlüssel zugewiesen wurde? Nach meinem Verständnis bezieht sich das eindeutige Attribut auf den Schlüssel. Du sagst , Sheet_Size INT PRIMARY KEYund Length UNIQUE, Width UNIQUE, Thickness UNIQUE? Ich verstehe immer noch nicht, wie dies Duplikate in der Tabelle verhindert (ohne Logik auf die Einfüge-Schnittstelle anzuwenden). (Vielleicht fehlt mir etwas?)
Brad Christie
Eine eindeutige Einschränkung für die drei Spalten: ALTER TABLE dbo.Sheet_Size ADD CONSTRAINT UC_LengthWidthThickness UNIQUE ([Länge], [Breite], [Dicke])
Mark Storey-Smith
Danke für die Bewertung. Ich bin damit einverstanden, dass eine eindeutige Einschränkung der Spalten eine großartige Lösung wäre, aber ich mag auch die Empfehlung von X-Zero, die Größen in eine neue Tabelle (verknüpft mit einer neuen Tabelle) aufzuteilen. Um Ideen zu kombinieren, werde ich die eindeutige Einschränkung auf die "abgespeckte" Größentabelle anwenden, während ich die Informationen zu Dichte und Kosten / Pfund entferne und sie in die Beziehungstabelle einfüge.
Brad Christie
4

Ich werde Sie ein wenig auf diese Antwort aus einer früheren Frage umleiten .

Zitat: "In Bezug auf die Art und Weise, wie dieser Primärschlüssel entworfen wird, gibt es zwei Denkrichtungen:

  • eine, die die PK als separate Spalte erstellt, die normalerweise selbst generiert wird, wie z. B. eine GUID oder eine automatische Inkrementierung von INT (in Ihrem Fall eine separate Spalte mit eindeutiger Kennung);
  • Eine, die die PK als eine Tabelle (oder einen Satz von Spalten) innerhalb der Tabelle macht (in Ihrem Fall wäre dies ein Benutzername oder eine E-Mail oder eine SSN, was auch immer diesen Benutzer eindeutig macht), die einen Datensatz eindeutig identifiziert.

An welcher Linie Sie festhalten, ist nur Geschmackssache. "

Nebenwirkungen einer beliebigen Lösung können sein:

  • Die Verwendung von zusammengesetzten Schlüsseln überall wird wahrscheinlich:

    • Erhöhen Sie den Speicher für alle beteiligten Tabellen.
    • Erhöhen / Komplizieren der Indizes für häufig verwendete FKs;
    • erschweren das Schreiben all Ihrer Join-Anweisungen ein wenig
    • mache Herrn Joe Celko glücklich :-) (Hinweise auf seine Meinung zu natürlichen oder künstlichen Schlüsseln finden Sie hier und hier und meistens überall, wo er nach dem Thema gefragt wird)
  • Die Verwendung generierter Schlüssel wird wahrscheinlich:

    • Vereinfachen Sie die vorherigen 3 Schritte
    • erschweren die Replikation einer Tabelle mit der Identitäts-PK (Verweise hier , hier oder hier )

Ich persönlich bevorzuge generierte INT IDENTITY-Schlüssel, aber was zu Ihnen passt, sollte in Ordnung sein.

Marian
quelle
2

Der zusammengesetzte Schlüssel ist absolut sinnvoll. Durch die Implementierung dieses Schlüssels wird sichergestellt, dass die Geschäftsattribute nicht dupliziert werden können. Dies ist eine gute Sache, da die mehrfache Aufzeichnung derselben Daten zu Mehrdeutigkeiten und unerwünschten Abhängigkeiten führen und Benutzerfehler und falsche Daten wahrscheinlicher machen würde.

Der automatisch inkrementierende Schlüssel allein schützt die Integrität Ihrer Geschäftsdaten nicht. Wenn der automatisch inkrementierende Schlüssel keinen bestimmten Zwecken dient (z. B. als Ziel einer Fremdschlüsselreferenz in einer anderen Tabelle), kann er sicher gelöscht werden.

nvogel
quelle
... Außer das automatische Inkrementieren als Fremdschlüssel zu löschen, würde die Verwendung aller Dimensionsspalten als Teil des Fremdschlüssels erfordern (dh alle vier Spalten , wenn Typ eingeschlossen). Nicht etwas, das ich als Fremdschlüssel haben möchte, Punkt - bitte nur einzelne Spalten. Ich bin damit einverstanden, dass es eine gute Idee ist, den Abmessungen (und / oder dem Typ, abhängig vom Tabellendesign) einen eindeutigen Schlüssel (und / oder eine Kontrollbeschränkung) zuzuweisen.
Clockwork-Muse
@ X-Zero, ich habe in meinem zweiten Absatz auf Fremdschlüsselreferenzen hingewiesen. Die Frage beim Lesen ist, ob der zusammengesetzte Schlüssel implementiert werden soll, nicht, ob auch ein automatisches Inkrementieren erfolgen soll.
Nvogel