Warum sollte ein int als Primärschlüssel einer Nachschlagetabelle verwendet werden?

30

Ich möchte wissen, warum ich einen int als Primärschlüssel einer Nachschlagetabelle verwenden sollte, anstatt nur den Nachschlagewert als Primärschlüssel zu verwenden (was in den meisten Fällen eine Zeichenfolge wäre).

Ich verstehe, dass die Verwendung eines nvarchar (50) anstelle eines int viel mehr Platz beansprucht, wenn es mit einer Tabelle mit vielen Datensätzen verknüpft ist.

Wenn Sie den Nachschlagewert jedoch direkt verwenden, sparen Sie sich im Grunde genommen das Ausführen eines Joins. Ich kann mir vorstellen, dass dies eine große Einsparung wäre, wenn der Join immer benötigt wird (wir arbeiten an einer Web-App, das zählt also ziemlich viel).

Was sind die Vorteile der Verwendung eines int-Primärschlüssels (speziell für eine Nachschlagetabelle), außer dass dies "der Standard" ist?

Jaco Briers
quelle
4
In diesen beiden vorherigen Fragen finden Sie gute Informationen und möglicherweise sogar die Antwort, die Sie benötigen: Gibt es einen Vorteil eines Primärschlüssels, der alle Spalten der Tabelle umfasst? und Character vs Integer Primärschlüssel .
Marian

Antworten:

23

Die Antwort auf Ihre Frage ist logisch und nicht physisch. Der Wert, den Sie nachschlagen, kann sich aus geschäftlichen Gründen ändern. Was passiert beispielsweise, wenn Sie Ihre Kunden nach E-Mail-Adresse indizieren, wenn sich eine E-Mail-Adresse ändert? Dies gilt natürlich nicht für alle Ihre Nachschlagetabellen, aber der Vorteil der gleichen Vorgehensweise in der gesamten Anwendung besteht darin, dass der Code einfacher wird. Wenn intern alles Integer → Integer-Relationen ist, sind Sie abgesichert.

Lies Sandy einfach deinen Kommentar vor - in diesem Fall ist das, was du wirklich willst, eine Check-Einschränkung , keine Fremdschlüssel- / Nachschlagetabelle, zB:

create table icecream (flavour varchar(10))
go
alter table icecream add constraint ck_flavour check (flavour in ('Orange', 'Pista', 'Mango'))
go
insert into icecream (flavour) values ('Orange')
go
insert into icecream (flavour) values ('Vanilla')
go

Führen Sie dies aus und Sie erhalten:

(1 row(s) affected)
Msg 547, Level 16, State 0, Line 1
The INSERT statement conflicted with the CHECK constraint "ck_flavour". The conflict occurred in database "GAIUSDB", table "dbo.icecream", column 'flavour'.
The statement has been terminated.

Dies ist eine effiziente und leistungsstarke Methode, aber der Nachteil ist natürlich, dass das Hinzufügen einer neuen Version eine Codeänderung bedeutet. Ich würde davon abraten, dies in der Anwendung zu tun - da Sie dies dann in jeder App tun müssen, die eine Verbindung zu dieser Datenbank herstellt, ist dies das sauberste Design, da es nur einen einzigen Codepfad für die Validierung gibt.

Gaius
quelle
@ Gaius- Gutes Beispiel ... Ich bevorzuge es, Check Constraint für diese Art von Szenario nicht zu verwenden. Hauptgrund dafür, dass es nicht gewartet werden kann (Sie haben es als Nachteil herausgestellt).
CoderHawk
1
@Sandy Es hängt wirklich von den Daten ab, wie oft sie sich ändern und wo sie sonst verwendet werden. Wenn die Einschränkung beispielsweise von der Datenbank erzwungen werden muss, die Werte jedoch auch zum Auffüllen eines Dropdown-Menüs oder eines Berichts verwendet werden können, ist ein Fremdschlüssel geeigneter. In beiden Fällen würde ich davon abraten, dies in der Anwendung zu tun.
Gaius
7

"Nachschlagewert direkt verwenden" - ist etwas widersprüchlich zum eigentlichen Zweck der Nachschlagetabelle. Warum halten Sie so einen Tisch? Wenn es kein Nachschlagen ist.
Vielleicht habe ich deine Frage falsch verstanden. Hier ist eine Nachschlagetabellendefinition von msdn

Eine Nachschlagetabelle wird verwendet, um Informationen aus einer Tabelle basierend auf dem Wert eines Fremdschlüsselfelds in einer anderen Tabelle anzuzeigen. Betrachten Sie beispielsweise eine Auftragstabelle in einer Verkaufsdatenbank. Jeder Datensatz in der Tabelle "Bestellungen" enthält eine Kunden-ID, die angibt, welcher Kunde die Bestellung aufgegeben hat. Die CustomerID ist ein Fremdschlüssel, der auf einen Kundendatensatz in der Customers-Tabelle verweist. Wenn Sie eine Liste mit Bestellungen (aus der Tabelle "Bestellungen") anzeigen, möchten Sie möglicherweise den tatsächlichen Kundennamen anstelle der Kunden-ID anzeigen. Da sich der Kundenname in der Kundentabelle befindet und Sie Daten aus der Tabelle "Bestellungen" anzeigen, müssen Sie eine Nachschlagetabelle erstellen, die den CustomerID-Wert im Bestelldatensatz verwendet und diesen Wert zum Navigieren in der Beziehung und zum Zurückgeben von mehr verwendet lesbar, Kundenname.

Können Sie den Zweck Ihrer Nachschlagetabelle erläutern? Wird es verwendet, um einige statische Daten wie die folgenden zu speichern, und diese Datensätze sind keine Eingabe anderer Tabellendatensätze?

Flavor Tisch

Orange  
Pista  
Mango

Wenn oben Ihre Situation ist, würde ich empfehlen, keine Nachschlagetabelle zu verwenden. Diese Listenwerte werden wahrscheinlich in Ihrer Webanwendung fest codiert. Auf diese Weise können Sie unnötige Datenbankabfragen vermeiden.

CoderHawk
quelle
1
Der Sinn meiner Nachschlagetabelle besteht im Grunde nur darin, die verschiedenen Werte zu erzwingen, die eine Spalte über eine Fremdschlüsseleinschränkung haben kann. Ich bin damit einverstanden, dass das Hardcodieren in die Anwendung eine andere Möglichkeit ist, dies zu handhaben.
Jaco Briers
@ Jaco Briers - Siehe Gaius Antwort ... Check Constraint verwenden ...
CoderHawk
7

Da Sie Ihre Frage mit "speziell für eine Nachschlagetabelle" qualifiziert haben, wird die Antwort wahrscheinlich auf "platzsparend" vereinfacht.

Ich denke, wenn Sie dieses Qualifikationsmerkmal entfernen, lautet Ihre Frage "Warum Ersatzschlüssel anstelle von natürlichen Schlüsseln verwenden?". Ich habe Folgendes zur Unterstützung von Ersatzschlüsseln geschrieben:

"Die Migration eines ganzzahligen Werts anstelle eines breiteren zusammengesetzten Schlüssels bietet zahlreiche Vorteile. Sie bietet eine gute Konsistenz im gesamten physischen Modell und spart im Vergleich zur Migration von zusammengesetzten Schlüsseln mehr Platz als Kosten und verringert die E / A-Kosten. "Normalisiertes Modell. Darüber hinaus vereinfachen sie das Verständnis eines Modells und der Abfrageverknüpfungen."

Dies ist größtenteils der Grund, warum es "zum Standard geworden ist". Das unglückliche Nebenprodukt ist, dass die Leute einen Ersatzschlüssel aufsetzen und nicht darüber nachdenken, was die Kandidatenschlüssel sind ... Aber jetzt kommen wir außerhalb Ihrer Frage :)

dba4life
quelle
3

Einer der Gründe, die ich immer benutze, ist, dass es sehr einfach ist, den Wert in der Nachschlagetabelle zu ändern, wenn jemand einen Wert in der Nachschlagetabelle falsch geschrieben hat, z. B. Oraneg anstelle von Orange.

Für die Nachschlagetabelle mit einem Nummernprimärschlüssel muss nur der Wert in der Nachschlagetabelle geändert werden.

Die Nachschlagetabelle, die die Werte als Primärschlüssel verwendet, muss in der Nachschlagetabelle und in jedem Datensatz in der Haupttabelle, in der sie verwendet wurde, geändert werden.

Susan Kennedy
quelle
2

Wenn Sie eine ID definieren, können Sie auch die Eindeutigkeit garantieren. Wenn Sie jedoch beispielsweise E-Mails als eindeutige Kennung verwenden, verlagern Sie die Verantwortung für die Eindeutigkeit auf die nicht vertrauenswürdige dritte Seite.

Vojta Rylko
quelle