Hintergrund
Ich habe diese Tische
+-------------------------+ +------------------------+
|Airport | |Country |
|-------------------------| |------------------------|
|airport_code string (PK) | |country_code string (PK)|
|address string | |name string |
|name string | +------------------------+
+-------------------------+
+-------------------------+
|Currency |
|-------------------------|
|currency_code string (PK)|
|name string |
+-------------------------+
AIRPORT_CODE ist der IATA (International Air Transport Association) Flughafen - Code , können Sie sie in Ihrem Gepäck - Tags sehen , wenn Sie mit dem Flugzeug reisen.
country_code ist der ISO 3166-1 A3-Standard-Ländercode , den Sie bei den Olympischen Spielen sehen können.
currency_code ist der IS0 417-Standardwährungscode (3 Zeichen) , der auf Anzeigetafeln für internationale Wechselkurse angezeigt wird.
Fragen
Sind diese natürlichen PKs gut genug?
Ist die Verwendung von weltweit anerkannten Standards, die von der gesamten Branche akzeptiert werden, gut genug für PKs?
Benötigen diese Tabellen Ersatz, egal was passiert?
quelle
Ich denke, Need ist ein sehr starkes Wort, und im engeren Sinne benötigen die Tabellen wahrscheinlich keine Ersatzschlüssel .
Wenn es jedoch meine Datenbank wäre, würde ich wahrscheinlich sowieso Ersatzschlüssel hinzufügen. Ich möchte nicht unbedingt, dass mein Datenbankdesign von einer Reihe von Drittanbietern (IATA, ISO) abhängt, unabhängig davon, wie stabil ihre Standards sind. Oder ich möchte mich überhaupt nicht auf einen bestimmten Standard verlassen (gibt es andere Währungscode-Standards? Ich weiß nicht). Ich würde wahrscheinlich meine Tabellen mit Ersatzschlüsseln wie folgt modellieren:
Mit anderen Worten, wenn diese Industriestandardcodes für meine Anwendung nicht von Natur aus wichtig sind, würde ich sie nicht als PK meiner Tabellen verwenden. Sie sind nur Etiketten. Die meisten meiner anderen Tabellen werden wahrscheinlich sowieso Ersatzschlüssel haben, und dieses Setup würde meinem Datenmodell mehr Konsistenz verleihen. Die Kosten für das Hinzufügen der Ersatzschlüssel sind minimal.
Update basierend auf einigen Kommentaren:
Ohne den Kontext der Beispieltabellen zu kennen, ist es unmöglich zu wissen, wie wichtig Dinge wie IATA-Flughafencodes für die Anwendung sind, die die Datenbank verwendet. Wenn IATA-Codes für die gesamte Anwendung von zentraler Bedeutung sind und überall in der Anwendung verwendet werden, ist es möglicherweise die richtige Entscheidung, die Codes nach ordnungsgemäßer Analyse als PK der Tabelle zu verwenden.
Wenn es sich bei der Tabelle jedoch nur um eine Lookup-Tabelle handelt, die in einigen Ecken der App verwendet wird, rechtfertigt die relative Bedeutung der IATA-Codes möglicherweise keinen so wichtigen Punkt in der Datenbankinfrastruktur. Sicher, Sie müssen hier und da ein paar Abfragen zusätzlich mitmachen, aber dieser Aufwand ist möglicherweise trivial im Vergleich zu dem Aufwand, der erforderlich ist, um sicherzustellen, dass Sie die Auswirkungen der IATA-Codes vollständig verstehen Primärschlüsselfeld. In einigen Fällen ist es mir nicht nur egal, sondern ich möchte mich auch nicht um die IATA-Codes kümmern müssen . Der folgende Kommentar von @James Snell ist ein perfektes Beispiel für etwas, über das ich mir keine Sorgen machen möchte, wenn es um die Beeinflussung der PK meiner Tabellen geht.
Auch die Konsistenz im Design ist wichtig. Wenn Sie eine Datenbank mit Dutzenden von Tabellen haben, die alle konsistent Ersatzschlüssel entworfen haben, und dann ein paar Nachschlagetabellen, die Codes von Drittanbietern als PK verwenden, führt dies zu einer Inkonsistenz. Das ist nicht ganz schlecht, erfordert aber zusätzliche Aufmerksamkeit bei der Dokumentation und solche, die möglicherweise nicht gerechtfertigt sind. Es handelt sich um Nachschlagetabellen , nur einen Ersatzschlüssel für die Konsistenz zu verwenden, ist vollkommen in Ordnung.
Update basierend auf weiteren Recherchen:
Ok, die Neugier hat mich gebissen und ich habe mich aus Spaß dazu entschlossen, nach IATA-Flughafencodes zu suchen, beginnend mit den in der Frage angegebenen Links.
Wie sich herausstellt, sind die IATA-Codes nicht so universell und maßgeblich, wie es die Frage vermuten lässt. Nach dieser Seite :
Darüber hinaus unterscheiden sich IATA- und ICAO-Codes von FAA-Identifizierungscodes , die eine weitere Möglichkeit zur Identifizierung von Flugplätzen darstellen.
Ich möchte damit nicht eine Debatte darüber beginnen, welche Codes besser oder universeller oder autorisierender oder umfassender sind, sondern genau zeigen, warum das Entwerfen Ihrer Datenbankstruktur anhand einer willkürlichen Drittanbieter-ID nicht meine Absicht ist , es sei denn, es gab einen bestimmten geschäftlichen Grund dafür .
In diesem Fall fühle ich meine Datenbank besser strukturiert, stabiler werden würde, und flexibler zu gestalten, indem sie die IATA - Codes zu verzichten (oder eine dritte Partei, potentiell veränderbare Code) als Primärschlüssel Kandidaten und verwenden Sie einen Ersatzschlüssel. Auf diese Weise kann ich auf potenzielle Fallstricke verzichten, die durch die Auswahl des Primärschlüssels entstehen könnten.
quelle
select * from baggage where airport_code = 'LHR'
bedeutet, dass die Datenbank nur über die Anwendung verwendet werden kann, die sehr eng und proprietär ist Ansatz, insbesondere wenn der Geschäftsinhaber derjenige ist, der für die Datenbank bezahlt hat und sie daher besitzt. Außerdem müssen Sie Code schreiben, um alltägliche Dinge wie das Importieren von Daten aus einer Datenbank in eine andere zu erledigen, um PK-Kollisionen zu vermeiden.Während es in Ordnung ist, Ersatzschlüssel in den Feldern zu haben, ist daran nichts auszusetzen, was zu berücksichtigen ist, könnte die Größe der Indexseite selbst sein.
Da es sich um eine relationale Datenbank handelt, werden Sie eine Menge Verknüpfungen durchführen. Wenn Sie einen Ersatzschlüssel eines numerischen Typs verwenden, ist die Datenbank möglicherweise einfacher zu handhaben, dh die Indexseitengröße ist kleiner und die Suche kann schneller durchgeführt werden. Wenn es sich um ein kleines Projekt handelt, spielt es keine Rolle und Sie kommen problemlos zurecht. Je größer die Anwendung, desto mehr möchten Sie Engpässe reduzieren.
Wenn Sie einen BIGINT-, INT-, SMALLINT-, TINYINT- oder einen ganzzahligen Datentyp haben, können Sie sich später Probleme ersparen.
Nur meine 2 Cent
AKTUALISIEREN:
Kleines Projekt - von ein paar, vielleicht sogar ein paar Dutzend Leuten genutzt. Kleines Demoprojekt, Projekt für den persönlichen Gebrauch, etwas, das einem Portfolio hinzugefügt werden kann, wenn Sie Ihre Fähigkeiten ohne Erfahrung präsentieren, und dergleichen.
Großes Projekt - wird täglich von Tausenden, Zehntausenden und Millionen Benutzern verwendet. Etwas, das Sie für ein nationales / internationales Unternehmen mit einer riesigen Anwenderbasis aufbauen würden.
In der Regel werden nur einige wenige Datensätze häufig ausgewählt, und der Server speichert die Ergebnisse für einen schnellen Zugriff im Cache. Von Zeit zu Zeit müssen Sie jedoch auf einige weniger genutzte Datensätze zugreifen. Zu diesem Zeitpunkt müsste der Server in den Index eintauchen Seite. (im obigen Beispiel mit den Flughafennamen fliegen die Leute oft inländische Fluggesellschaften, sagen wir Chichago -> Los Angeles, aber wie oft fliegen die Leute von Boston -> Simbabwe)
Wenn VARCHAR verwendet wird, bedeutet dies, dass der Abstand nicht einheitlich ist, es sei denn, die Daten sind immer gleich lang (an diesem Punkt ist ein CHAR-Wert effektiver). Dadurch wird das Durchsuchen des Index langsamer, und da der Server bereits mit Tausenden und Abertausenden von Abfragen pro Sekunde beschäftigt ist, muss er Zeit für das Durchsuchen eines nicht einheitlichen Index verschwenden und das Gleiche bei den Verknüpfungen wiederholen (was langsamer ist als reguläre Auswahlen in einer nicht optimierten Tabelle, z. B. DW, wo es so wenig Verknüpfungen wie möglich gibt, um das Abrufen von Daten zu beschleunigen). Auch wenn Sie UTF verwenden, kann das ebenfalls mit dem Datenbankmodul zu Problemen führen (ich habe einige Fälle gesehen).
Persönlich kann ein ordnungsgemäß organisierter Index meiner Erfahrung nach die Geschwindigkeit eines Joins um ~ 70% erhöhen, und das Durchführen eines Joins für eine Ganzzahlspalte kann den Join um bis zu ~ 25% beschleunigen (abhängig von den Daten). . Wenn die Haupttabellen zu wachsen beginnen und diese Tabellen verwendet werden, sollten Sie lieber einen Integer-Datentyp in der Spalte mit ein paar Bytes verwenden, als ein VARCHAR / CHAR-Feld, das mehr Platz einnimmt. Es geht darum, Speicherplatz zu sparen, die Leistung zu steigern und die Gesamtstruktur einer relationalen Datenbank zu verbessern.
Auch, wie James Snell erwähnte:
Wenn Sie dies berücksichtigen, müssen Sie eher 1 Datensatz aktualisieren, der an eine Zahl gebunden ist, als dass Sie diesen einen Datensatz plus alle Datensätze in der Tabelle, zu der Sie beitreten, aktualisieren müssen.
quelle
small project
undbigger
aktualisieren Sie bitte zu klären , warum die Materie würde.Wenn Sie den Ansatz "Ich verwende ständig Ersatzschlüssel" wählen, können Sie diese Art von Bedenken umgehen. Das mag nicht gut sein, da es wichtig ist, über Ihre Daten nachzudenken, aber es spart sicherlich viel Zeit, Energie und Mühe. Wenn irgendjemand diese Regel akzeptieren würde, wären die aufgelisteten Beispiele mit Sicherheit geeignet, da die Änderung nur in einem "Akt des Kongresses" durchgeführt werden kann.
Ad-hoc-Abfragen einer Datenbank mit diesen natürlichen Schlüsseln sind sicherlich hilfreich. Das Erstellen von Ansichten, die dasselbe tun, indem sie die Nachschlagetabellen einschließen, kann genauso gut funktionieren. Moderne Datenbanken machen mit solchen Dingen einen viel besseren Job, bis es wahrscheinlich egal ist.
Es gibt einige spezifische Fälle in den USA, in denen die Standards drastisch geändert wurden: Die Postleitzahl wurde von 5 bis 9 Ziffern erweitert, die Abkürzungen der Bundesstaaten wurden zu konsistenten 2 Buchstaben Die Welt muss sich mit Y2K auseinandersetzen. Wenn Sie eine Echtzeit-App mit Daten haben, die auf der ganzen Welt verteilt sind und Milliarden von Datensätzen enthalten, sind kaskadierende Aktualisierungen nicht die beste Idee. Sollten wir nicht alle an Orten arbeiten, an denen solche Herausforderungen auftreten? Mit diesem Datensatz können Sie es selbst testen und eine differenziertere Antwort finden.
quelle