Beim Entwerfen von Tabellen habe ich mir angewöhnt, eine Spalte zu haben, die eindeutig ist und die ich als Primärschlüssel verwende. Dies wird je nach Anforderung auf drei Arten erreicht:
- Ganzzahlige Identitätsspalte, die automatisch inkrementiert wird.
- Eindeutige Kennung (GUID)
- Eine kurze Spalte (x) oder eine Ganzzahl (oder eine andere relativ kleine numerische Spalte), die als Zeilenbezeichnungsspalte dienen kann
Nummer 3 wird für eine relativ kleine Suche verwendet, meistens für gelesene Tabellen, die einen eindeutigen Zeichenfolgencode für die statische Länge oder einen numerischen Wert wie ein Jahr oder eine andere Zahl haben können.
In den meisten Fällen haben alle anderen Tabellen entweder eine automatisch inkrementierende Ganzzahl oder einen Primärschlüssel mit eindeutiger Kennung.
Die Frage :-)
Ich habe kürzlich begonnen, mit Datenbanken zu arbeiten, die keine konsistente Zeilenkennung haben und deren Primärschlüssel derzeit über verschiedene Spalten gruppiert sind. Einige Beispiele:
- Datum / Uhrzeit / Zeichen
- Datum / Uhrzeit / Ganzzahl
- datetime / varchar
- char / nvarchar / nvarchar
Gibt es dafür einen gültigen Fall? Ich hätte für diese Fälle immer eine Identität oder eine eindeutige Bezeichnungsspalte definiert.
Außerdem gibt es viele Tabellen ohne Primärschlüssel. Was sind die gültigen Gründe dafür, wenn überhaupt?
Ich versuche zu verstehen, warum Tische so gestaltet wurden, wie sie waren, und es scheint mir ein großes Durcheinander zu sein, aber vielleicht gab es gute Gründe dafür.
Eine dritte Frage, die mir helfen soll, die Antworten zu entschlüsseln: Gibt es in Fällen, in denen mehrere Spalten verwendet werden, um den zusammengesetzten Primärschlüssel zu bilden, einen besonderen Vorteil gegenüber dieser Methode gegenüber einem Ersatzschlüssel / künstlichen Schlüssel? Ich denke hauptsächlich in Bezug auf Leistung, Wartung, Verwaltung usw.?
quelle
Antworten:
Ich befolge einige Regeln:
Bei Ersatz gegen natürlichen Schlüssel beziehe ich mich auf die obigen Regeln. Wenn der natürliche Schlüssel klein ist und sich nie ändert, kann er als Primärschlüssel verwendet werden. Wenn der natürliche Schlüssel groß ist oder sich wahrscheinlich ändert, verwende ich Ersatzschlüssel. Wenn es keinen Primärschlüssel gibt, erstelle ich immer noch einen Ersatzschlüssel, da die Erfahrung zeigt, dass Sie Ihrem Schema immer Tabellen hinzufügen und wünschen, Sie würden einen Primärschlüssel einrichten.
quelle
Int
sNatürliche Verse Künstliche Schlüssel sind eine Art religiöse Debatte in der Datenbankgemeinschaft - siehe diesen Artikel und andere, auf die er verweist. Ich bin weder dafür, immer künstliche Schlüssel zu haben, noch dafür, sie nie zu haben. Ich würde von Fall zu Fall entscheiden, zum Beispiel:
Überall dort, wo künstliche Schlüssel verwendet werden, sollten Sie immer auch eindeutige Einschränkungen für die natürlichen Schlüssel deklarieren. Verwenden Sie beispielsweise state_id, wenn Sie müssen, aber dann sollten Sie eine eindeutige Einschränkung für state_code deklarieren, da Sie sonst sicher Folgendes erhalten:
quelle
Nur ein zusätzlicher Kommentar zu etwas, das oft übersehen wird. Manchmal hat die Nichtverwendung eines Ersatzschlüssels Vorteile in den untergeordneten Tabellen. Angenommen, wir haben ein Design, mit dem Sie mehrere Unternehmen in einer Datenbank ausführen können (möglicherweise handelt es sich um eine gehostete Lösung oder was auch immer).
Angenommen, wir haben diese Tabellen und Spalten:
Falls das letzte Bit keinen Sinn
Invoice.CompanyId
ergibt , ist es Teil von zwei Fremdschlüsseln, einer für die CostCentre- Tabelle und einer für die CostElement- Tabelle. Der Primärschlüssel ist ( InvoiceId , CompanyId ).In diesem Modell ist es nicht möglich, ein CostElement eines Unternehmens und ein CostCentre eines anderen Unternehmens zu vermasseln und zu referenzieren . Wenn ein Ersatzschlüssel für die Tabellen CostElement und CostCentre verwendet würde , wäre dies der Fall.
Je weniger Chancen es gibt, desto besser.
quelle
Ich vermeide die Verwendung natürlicher Schlüssel aus einem einfachen Grund - menschlichem Versagen. Obwohl häufig natürliche eindeutige Kennungen verfügbar sind (SSN, VIN, Kontonummer usw.), muss sie von einem Menschen korrekt eingegeben werden. Wenn Sie SSNs als Primärschlüssel verwenden, jemand während der Dateneingabe einige Zahlen transponiert und der Fehler nicht sofort erkannt wird, müssen Sie Ihren Primärschlüssel ändern.
Meine Primärschlüssel werden alle vom Datenbankprogramm im Hintergrund verarbeitet, und der Benutzer weiß nichts davon.
quelle
Es ist kein Problem, Ihren Primärschlüssel aus verschiedenen Bereichen zu erstellen, das ist ein natürlicher Schlüssel .
Sie können eine Identitätsspalte (die einem eindeutigen Index für die Kandidatenfelder zugeordnet ist) verwenden, um einen Ersatzschlüssel zu erstellen .
Das ist eine alte Diskussion. In den meisten Situationen bevorzuge ich Ersatzschlüssel.
Aber es gibt keine Entschuldigung für das Fehlen eines Schlüssels.
RE: EDIT
Ja, darüber gibt es viele Kontroversen: D.
Ich sehe keinen offensichtlichen Vorteil bei natürlichen Schlüsseln, abgesehen von der Tatsache, dass sie die natürliche Wahl sind. Sie werden immer in Name, SocialNumber - oder so ähnlich - anstelle von idPerson denken .
Ersatzschlüssel sind die Antwort auf einige der Probleme, die natürliche Schlüssel haben (z. B. die Weitergabe von Änderungen).
Wenn Sie sich an Leihmütter gewöhnen, wirkt es sauberer und überschaubarer.
Aber am Ende werden Sie feststellen, dass es nur um Geschmack - oder Denkweise - geht. Menschen "denken besser" mit natürlichen Schlüsseln, andere nicht.
quelle
Tabellen sollten immer einen Primärschlüssel haben. Wenn dies nicht der Fall ist, sollte es sich um ein AutoIncrement-Feld handeln.
Manchmal lassen Benutzer den Primärschlüssel weg, weil sie viele Daten übertragen und dies den Prozess verlangsamen kann (abhängig von der Datenbank). ABER es sollte danach hinzugefügt werden.
Ein Kommentar zur Link-Tabelle , das ist richtig, es ist eine Ausnahme, ABER Felder sollten FK sein, um die Integrität zu erhalten, und in einigen Fällen können diese Felder auch Primärschlüssel sein, wenn das Duplizieren in Links nicht autorisiert ist ... aber um in a zu bleiben einfache Form, da bei der Programmierung häufig Ausnahmen auftreten, sollte ein Primärschlüssel vorhanden sein, um die Integrität Ihrer Daten zu gewährleisten.
quelle
Neben all diesen guten Antworten möchte ich nur einen guten Artikel teilen, den ich gerade gelesen habe: Die große Debatte über den Primärschlüssel .
Um nur einige Punkte zu zitieren:
Der Entwickler muss bei der Auswahl eines Primärschlüssels für jede Tabelle einige Regeln anwenden:
Natürliche Schlüssel (neigen dazu) gegen die Regeln zu verstoßen. Ersatzschlüssel entsprechen den Regeln. (Lesen Sie diesen Artikel besser durch, es ist Ihre Zeit wert!)
quelle
Was ist das Besondere am Primärschlüssel?
Was ist der Zweck einer Tabelle in einem Schema? Was ist der Zweck eines Schlüssels einer Tabelle? Was ist das Besondere am Primärschlüssel? Die Diskussionen um Primärschlüssel scheinen den Punkt zu verfehlen, dass der Primärschlüssel Teil einer Tabelle und diese Tabelle Teil eines Schemas ist. Was für die Tabelle und die Tabellenbeziehungen am besten ist, sollte den verwendeten Schlüssel steuern.
Tabellen (und Tabellenbeziehungen) enthalten Fakten zu Informationen, die Sie aufzeichnen möchten. Diese Tatsachen sollten in sich geschlossen, aussagekräftig, leicht verständlich und nicht widersprüchlich sein. Aus Entwurfssicht sollten andere Tabellen, die einem Schema hinzugefügt oder daraus entfernt werden, keine Auswirkungen auf die betreffende Tabelle haben. Es muss einen Zweck zum Speichern der Daten geben, die sich nur auf die Informationen selbst beziehen. Um zu verstehen, was in einer Tabelle gespeichert ist, sollte kein wissenschaftliches Forschungsprojekt erforderlich sein. Keine für denselben Zweck gespeicherte Tatsache sollte mehr als einmal gespeichert werden. Schlüssel sind ein Ganzes oder ein Teil der aufgezeichneten Informationen, die eindeutig sind, und der Primärschlüssel ist der speziell festgelegte Schlüssel, der der primäre Zugriffspunkt auf die Tabelle sein soll (dh er sollte aus Gründen der Datenkonsistenz und -verwendung ausgewählt und nicht nur eingefügt werden Performance).
Es wurde gesagt, dass Primärschlüssel so klein wie nötig sein sollten. Ich würde sagen, dass Schlüssel nur so groß wie nötig sein sollten. Das zufällige Hinzufügen bedeutungsloser Felder zu einer Tabelle sollte vermieden werden. Es ist noch schlimmer, einen Schlüssel aus einem zufällig hinzugefügten bedeutungslosen Feld zu machen, insbesondere wenn dadurch die Verknüpfungsabhängigkeit von einer anderen Tabelle zum Nicht-Primärschlüssel zerstört wird. Dies ist nur dann sinnvoll, wenn die Tabelle keine guten Kandidatenschlüssel enthält. Dieses Vorkommen ist jedoch sicherlich ein Zeichen für ein schlechtes Schemadesign, wenn es für alle Tabellen verwendet wird.
Es wurde auch gesagt, dass sich Primärschlüssel niemals ändern sollten, da das Aktualisieren eines Primärschlüssels immer nicht in Frage kommen sollte. Das Update entspricht jedoch dem Löschen und dem Einfügen. Nach dieser Logik sollten Sie niemals einen Datensatz mit einem Schlüssel aus einer Tabelle löschen und dann einen weiteren Datensatz mit einem zweiten Schlüssel hinzufügen. Durch Hinzufügen des Ersatzprimärschlüssels wird nicht die Tatsache entfernt, dass der andere Schlüssel in der Tabelle vorhanden ist. Das Aktualisieren eines Nicht-Primärschlüssels einer Tabelle kann die Bedeutung der Daten zerstören, wenn andere Tabellen durch einen Ersatzschlüssel von dieser Bedeutung abhängig sind (z. B. eine Statustabelle mit einem Ersatzschlüssel, dessen Statusbeschreibung von "Verarbeitet" in "Abgebrochen" geändert wurde 'würde definitiv die Daten beschädigen). Was immer nicht in Frage kommen sollte, ist die Zerstörung der Datenbedeutung.
Trotzdem bin ich dankbar für die vielen schlecht gestalteten Datenbanken, die heutzutage in Unternehmen existieren (bedeutungslose 1NF-Giganten mit Ersatzschlüsseldaten), denn das bedeutet, dass Menschen, die das richtige Datenbankdesign verstehen, unendlich viel Arbeit haben . Aber auf der traurigen Seite fühle ich mich manchmal wie Sisyphus, aber ich wette, er hatte einen verdammten 401k (vor dem Absturz). Halten Sie sich bei wichtigen Fragen zum Datenbankdesign von Blogs und Websites fern. Wenn Sie Datenbanken entwerfen, suchen Sie nach CJ Date. Sie können auch auf Celko für SQL Server verweisen, jedoch nur, wenn Sie zuerst die Nase halten. Beziehen Sie sich auf der Oracle-Seite auf Tom Kyte.
quelle
Ein natürlicher Schlüssel, falls verfügbar, ist normalerweise am besten. Wenn also datetime / char die Zeile eindeutig identifiziert und beide Teile für die Zeile von Bedeutung sind, ist das großartig.
Wenn nur die Datums- und Uhrzeitangabe von Bedeutung ist und das Zeichen nur angeheftet wird, um es eindeutig zu machen, können Sie auch einfach ein Identifikationsfeld verwenden.
quelle
Hier ist meine eigene Faustregel, auf die ich mich nach mehr als 25 Jahren Entwicklungserfahrung festgelegt habe.
Der Primärschlüssel wird von der Datenbank zu Optimierungszwecken verwendet und sollte von Ihrer Anwendung nur für die Identifizierung einer bestimmten Entität oder für eine bestimmte Entität verwendet werden.
Wenn Sie immer einen Primärschlüssel mit einem Wert haben, ist die Durchführung von UPSERTs sehr einfach.
Verwenden Sie zusätzliche Indizes, um mehrspaltige Schlüssel zu unterstützen, die in Ihrer Anwendung eine Bedeutung haben.
quelle
Natürliche oder künstliche Schlüssel hängen für mich davon ab, wie viel von der Geschäftslogik Sie in Ihrer Datenbank haben möchten. Die Sozialversicherungsnummer (SSN) ist ein gutes Beispiel.
"Jeder Client in meiner Datenbank wird und muss eine SSN haben." Bam, fertig, mach es zum Primärschlüssel und sei fertig damit. Denken Sie daran, wenn sich Ihre Geschäftsregel ändert, werden Sie verbrannt.
Ich mag natürliche Schlüssel selbst nicht, weil ich Erfahrung mit der Änderung von Geschäftsregeln habe. Wenn Sie sich jedoch sicher sind, dass sich dies nicht ändert, werden möglicherweise einige kritische Verknüpfungen verhindert.
quelle
Ich vermute, dass Steven A. Lowes aufgerollte Zeitungstherapie für den Designer der ursprünglichen Datenstruktur erforderlich ist.
Abgesehen davon können GUIDs als Primärschlüssel ein Leistungsproblem sein. Ich würde es nicht empfehlen.
quelle
Sie sollten einen zusammengesetzten oder zusammengesetzten Primärschlüssel verwenden, der aus mehreren Feldern besteht.
Dies ist eine durchaus akzeptable Lösung, geht hier für weitere Informationen :)
quelle
Auch ich verwende immer eine numerische ID-Spalte. In Orakel verwende ich die Nummer (18,0) ohne wirklichen Grund über der Nummer (12,0) (oder was auch immer ein Int statt eines Long ist), vielleicht möchte ich mir nie Sorgen machen, ein paar Milliarden Zeilen einzubringen die db!
Ich füge auch eine erstellte und geänderte Spalte (Typ Zeitstempel) für die grundlegende Nachverfolgung hinzu, wo dies nützlich erscheint.
Es macht mir nichts aus, eindeutige Einschränkungen für andere Spaltenkombinationen festzulegen, aber ich mag meine ID, die erstellten, geänderten Basisanforderungen wirklich.
quelle
Ich suche nach natürlichen Primärschlüsseln und benutze sie, wo ich kann.
Wenn keine natürlichen Schlüssel gefunden werden können, bevorzuge ich eine GUID gegenüber einer INT ++, da SQL Server Bäume verwendet und es schlecht ist, immer Schlüssel am Ende in Bäumen hinzuzufügen.
Für Tabellen mit vielen zu vielen Kopplungen verwende ich einen zusammengesetzten Primärschlüssel der Fremdschlüssel.
Da ich das Glück habe, SQL Server zu verwenden, kann ich mit dem Profiler und dem Abfrageanalysator Ausführungspläne und Statistiken studieren und herausfinden, wie einfach meine Schlüssel sind.
quelle
Ich benutze immer eine Autonummer oder ein Identitätsfeld.
Ich habe für einen Client gearbeitet, der SSN als Primärschlüssel verwendet hatte und dann aufgrund der HIPAA-Bestimmungen gezwungen war, auf eine "MemberID" umzusteigen. Dies verursachte eine Menge Probleme beim Aktualisieren der Fremdschlüssel in verwandten Tabellen. Das Festhalten an einem einheitlichen Standard einer Identitätsspalte hat mir geholfen, ein ähnliches Problem in allen meinen Projekten zu vermeiden.
quelle
Alle Tabellen sollten einen Primärschlüssel haben. Andernfalls haben Sie einen HEAP - dies kann in einigen Situationen das sein, was Sie möchten (hohe Einfügungslast, wenn die Daten dann beispielsweise über einen Service Broker in eine andere Datenbank oder Tabelle repliziert werden).
Für Nachschlagetabellen mit geringem Zeilenvolumen können Sie einen 3-CHAR-Code als Primärschlüssel verwenden, da dies weniger Platz als ein INT beansprucht, der Leistungsunterschied jedoch vernachlässigbar ist. Abgesehen davon würde ich immer eine INT verwenden, es sei denn, Sie haben eine Referenztabelle, die möglicherweise einen zusammengesetzten Primärschlüssel enthält, der aus Fremdschlüsseln aus zugeordneten Tabellen besteht.
quelle
Wenn Sie wirklich das ganze Hin und Her dieser uralten Debatte durchlesen möchten, suchen Sie nach "natürlichem Schlüssel" für "Stapelüberlauf". Sie sollten Seiten mit Ergebnissen zurückerhalten.
quelle
GUIDs können als Primärschlüssel verwendet werden, Sie müssen jedoch den richtigen GUID-Typ erstellen, damit er eine gute Leistung erbringt.
Sie müssen COMB-GUIDs generieren. Ein guter Artikel darüber und Leistungsstatistiken sind Die Kosten von GUIDs als Primärschlüssel .
Ein Teil des Codes zum Erstellen von COMB-GUIDs in SQL befindet sich auch in Uniqueidentifier vs identity ( Archiv ) .
quelle
Wir machen viele Verknüpfungen und zusammengesetzte Primärschlüssel sind gerade zu einem Leistungsproblem geworden. Ein einfaches int oder long kümmert sich um viele Probleme, obwohl Sie einen zweiten Kandidatenschlüssel einführen, aber es ist viel einfacher und verständlicher, sich einem Feld gegenüber drei anzuschließen.
quelle
Ich werde mich ganz klar mit meiner Präferenz für natürliche Schlüssel befassen - verwenden Sie sie, wo immer dies möglich ist, da sie Ihnen das Leben in der Datenbankverwaltung erheblich erleichtern. Ich habe in unserem Unternehmen einen Standard festgelegt, dass alle Tabellen die folgenden Spalten haben:
SUSER_SNAME()
in T-SQL))Die Zeilen-ID verfügt über einen eindeutigen Schlüssel pro Tabelle und wird in jedem Fall automatisch pro Zeile generiert (und Berechtigungen verhindern, dass jemand sie bearbeitet). Es ist vernünftigerweise garantiert, dass sie in allen Tabellen und Datenbanken eindeutig ist. Wenn ORM-Systeme einen einzelnen ID-Schlüssel benötigen, muss dieser verwendet werden.
In der Zwischenzeit ist die eigentliche PK, wenn möglich, ein natürlicher Schlüssel. Meine internen Regeln sind ungefähr so:
EventId, AttendeeId
)Idealerweise erhalten Sie eine natürliche, für Menschen lesbare und einprägsame PK sowie eine ORM-freundliche GUID mit einer ID pro Tabelle.
Vorsichtsmaßnahme: Die Datenbanken, die ich pflege, tendieren eher zu 100.000 als zu Millionen oder Milliarden von Datensätzen. Wenn Sie also Erfahrung mit größeren Systemen haben, die meinen Rat kontraindizieren, können Sie mich gerne ignorieren!
quelle
GUID
als auchINT
SKs für Tabellen ohne starken natürlichen Schlüssel zu erstellen ?