2009-09-14 8 views
9

Beachten Sie, dass es eine Reihe von Tabellen gibt, die mit Tabellen "Länder" oder "Währungen" verknüpft sind.Verwendet char als Primär/Fremdschlüssel ein Nein Nein?

Um Daten leichter lesbar zu machen, möchte ich ein CHAR-Feld mit Ländercode (zB US, GB, AU) und Währungscode (USD, AUD) als Primärschlüssel in jeder dieser 2 Tabellen und aller anderen Tabellen erstellen Verwenden Sie diesen CHAR als Vorentschlüssel.

Datenbank ist MySQL mit Innodb-Engine.

Wird es Leistungsprobleme verursachen? Ist es etwas, das ich vermeiden sollte?

Antwort

21

Leistung ist nicht wirklich das Hauptproblem, zumindest nicht für mich. Das Problem betrifft eher Surrogate vs natürliche Schlüssel.

Ländercodes sind nicht statisch. Sie können und ändern sich. Länder ändern Namen (z. B. Äthiopien nach Eritrea). Sie entstehen (zB die Auflösung Jugoslawiens oder der Sowjetunion) und sie hören auf zu existieren (zB West- und Ostdeutschland). Wenn dies geschieht, ändert sich der ISO-Standardcode.

Mehr in Name Changes Since 1990: Countries, Cities, and More

Ersatzschlüssel sind in der Regel besser sein, weil, wenn diese Ereignisse die Schlüssel passieren nicht ändern, nur Spalten in der Referenztabelle tun.

Aus diesem Grund wäre ich eher geneigt, Länder- und Währungstabellen stattdessen mit einem int-Primärschlüssel zu erstellen.

Das heißt, Varchar-Schlüsselfelder benötigen mehr Speicherplatz und haben bestimmte Leistungsnachteile, die wahrscheinlich kein Problem darstellen, es sei denn, Sie führen eine große Anzahl von Abfragen durch.

Der Vollständigkeit halber können Sie sich auf Database Development Mistakes Made by AppDevelopers beziehen.

+3

Äthiopien hat seinen Namen geändert?!? – SeanJA

+0

Verdammt das Telefon, machte mich mitten in der Eingabe dieser genauen Antwort. Gut gesagt! – Eric

+0

@SeanJA: Laut diesem Link ja. Es könnte eine vorübergehende Änderung gewesen sein. – cletus

2

James Skidmores Link ist wichtig zu lesen.

Wenn Sie sich auf Länder- und Währungscodes beschränken (2 bzw. 3 Zeichen), können Sie möglicherweise die Spalten char (2) und char (3) deklarieren.

Ich würde vermuten, dass wäre kein No-No. Wenn Sie eine 8-Bit-Zeichencodierung verwenden, betrachten Sie Spalten mit der Größe von Smallint bzw. Mediumint.

0

Meine Antwort ist, dass es keine klare Antwort gibt. Wählen Sie einfach einen Ansatz innerhalb Ihres Projekts und konsistent sein. Beide haben ihre Plus- und Minuspunkte.

@cletus macht einen guten Punkt über die Verwendung von generierten Schlüsseln, aber wenn Sie in eine Situation geraten, in der die Daten relativ statisch sind, wie Ländercodes, erscheint die Einführung eines generierten Schlüssels zu komplex. Trotz der realen Weltpolitik wird das Erscheinen von Ländercodes nicht wirklich ein Problem für die meisten Geschäftsprobleme sein (aber wenn Ihre Daten alle 190-210 Länder aktiv betreffen, folgen Sie diesem Rat).

Die universelle Verwendung von Ersatzschlüsseln ist eine gute und beliebte Strategie. Aber denken Sie daran, es kommt als Antwort auf die Modellierung von Datenbanken mit natürlichen Schlüsseln für alles. Nein! Öffnen Sie ein 15 Jahre altes Datenbankbuch. Die Verwendung von natürlichen Schlüsseln überall bringt Sie definitiv in schwierige Situationen, da das anfängliche Verständnis der Problembereiche sich als falsch erweist. Sie möchten Konsistenz in Ihren Modellierungspraktiken haben, aber die Verwendung verschiedener Techniken für deutlich unterschiedliche Situationen ist in Ordnung.

Ich vermute, dass die Leistung für die meisten modernen Datenbanken auf var (2) Fremdschlüssel die gleichen (oder besser) als Int-Felder sein wird. Datenbanken unterstützen seit Jahren textuelle Fremdschlüssel.

Da wir keine weiteren Informationen über das Projekt haben, wenn Sie die Ländercodes als Fremdschlüssel verwenden möchten, und Sie die Möglichkeit dazu haben, würde ich sagen, dass es in Ordnung ist. Es wird einfacher sein, mit den Daten zu arbeiten. Es ist ein wenig gegen gängige Praktiken, aber - in diesem Fall - wird es dich nicht in irgendeine Ecke zurückversetzen.

+0

-1 Das ist eigentlich ziemlich falsch. Wie in http://forums.mysql.com/read.php?153,243809,243818#msg-243818 von James darauf hingewiesen, gibt es Dinge, die MySQL (die betreffende Datenbank) nicht mit Varchars macht, mit denen es tut int Schlüssel. – cletus

+0

Ich habe nur vermutet, dass seit Datenbanken dies seit Jahren getan hat, es optimiert wurde. Es wäre nicht das erste Mal, dass sich diese Annahme als falsch herausstellte! Aber diese Post ist eine etwas andere Frage ("verwendet VARCHAR (45) eine gute Wahl für einen Primärschlüssel?") Dieses Problem ist CHAR (2) in einer 200 Zeile Tabelle (die Anzahl der Länder). Leider wird in diesem Post nicht allgemein auf die FK-Indexleistung eingegangen und ob CHAR (2) effizienter als VARCHAR (2) ist, und ich konnte es nicht ausgraben. Danke für den Link. – ndp

+0

Ich stimme zu, es diskutiert, wie schlecht ist, 45 Byte char zu haben, da es 4-5 mal größer als normal int ist, aber mit char (2) oder char (3) wird es nicht viel Unterschied Größe weise. –