guter Datenbankentwurf: Enum-Werte: Ints oder Strings?

9

Ich habe eine Spalte in einer Tabelle, die einen Enum-Wert speichert. Z.B. Groß, Mittel, Klein oder die Tage der Woche. Dies entspricht dem angezeigten Text auf einer Webseite oder der Benutzerauswahl aus einer Dropdown-Liste. Was ist das beste Design?

Speichern Sie die Werte als int und haben Sie dann vielleicht eine Tabelle, in der die enums / int-Zeichenkette enthalten ist.

Speichern Sie einfach die Werte in der Spalte als eine Zeichenfolge, um Abfragen etwas selbsterklärender zu machen.

An welcher Stelle / Anzahl von Werten ist es am besten, Ints oder Strings zu verwenden.

Danke.

    
tim 04.08.2010, 21:43
quelle

4 Antworten

2

Angenommen, Ihr RDBMS Ihrer Wahl hat keinen ENUM-Typ (der das für Sie behandelt), denke ich am besten, IDs anstelle von Strings direkt zu verwenden, wenn sich die Werte ändern können (entweder im Wert oder in der Menge).

Sie könnten denken, dass sich die Wochentage nicht ändern werden, aber was ist, wenn Ihre Anwendung Internationalisierungsunterstützung hinzufügen muss? (oder ein böser multinationaler Konzern beschließt, sie umzubenennen, nachdem er die Kontrolle über die Welt übernommen hat?)

Auch die Kategorisierung Large, Medium und Small ändert sich wahrscheinlich nach einiger Zeit. Die meisten Werte, die Sie nicht ändern können, können sich nach einer Weile ändern.

Also, hauptsächlich, um Änderungsgründe vorwegzunehmen, denke ich, dass es am besten ist, IDs zu verwenden, Sie müssen nur die Übersetzungstabelle ändern und alles funktioniert schmerzlos. Für i18n können Sie einfach die Übersetzungstabelle erweitern und die richtigen Datensätze automatisch abrufen.

Am wahrscheinlichsten (es hängt von verschiedenen Faktoren ab) werden die Leistungen besser, zumindest in der Menge des erforderlichen Speichers. Aber aus Performancegründen würde ich keine Ints machen, aus Gründen der Flexibilität würde ich Ints machen.

    
Vinko Vrsalovic 04.08.2010 21:52
quelle
1

Das ist eine interessante Frage. Auf jeden Fall müssen Sie hier Leistungsziele berücksichtigen. Wenn Sie Geschwindigkeit anstreben, ist Int ein Muss. Eine Datenbank kann ganze Zahlen ein wenig besser indizieren als Strings, obwohl ich sagen muss, dass sie gar keinen schlechten Performanceverlust haben.

Ein Beispiel ist die Oracle-Datenbank selbst, wo sie den Luxus haben, Large Caps als String auf ihren Systemtabellen zu verwenden. Dinge wie USER_ALLOCATION_TYPE oder solche Dinge sind die Norm. Wie du sagst, Strings können "erweiterbarer" und lesbarer sein, aber auf jeden Fall im Code wirst du enden:

Statische letzte Zeichenfolge USER_ALLOCATION_TYPE="USER_ALLOCATION_TYPE";

anstelle von

Statisch final int USER_ALLOCATION_TYPE = 5;

Weil Sie das entweder tun, werden Sie mit all diesen Zeichenfolgenliteralen enden, die nur darauf brennen, dass jemand dorthin geht und einen Buchstaben falsch platziert! :)

In meiner Firma benutzen wir Tabellen mit ganzen Zahlen; Alle Tische haben einen seriellen Primärschlüssel, denn selbst wenn Sie nicht glauben, dass Sie einen brauchen, werden Sie das früher oder später bereuen.

Wenn Sie beschreiben, was wir tun, haben wir eine Tabelle mit (PK Int, Description String) und dann machen wir Views über die Master-Tabellen mit Joins, um die Beschreibungen zu erhalten, auf diese Weise sehen wir den Joined Felder Beschreibungen, wenn wir müssen und wir halten die Leistung hoch.

Außerdem können Sie mit einer separaten Beschreibungstabelle EXTRA Informationen über diese IDs haben, an die Sie niemals denken würden. Nehmen wir beispielsweise an, ein Benutzer kann nur dann auf einige Felder im Kombinationsfeld zugreifen, wenn sie diese Eigenschaft haben. Sie können zusätzliche Felder in der Beschreibungstabelle verwenden, um diese anstelle von Ad-hoc-Code zu speichern.

Meine zwei Cent.

    
Rui 04.08.2010 21:53
quelle
0

Gehen Sie mit Ihrem ersten Beispiel. Sagen wir, Sie erstellen eine Nachschlagetabelle: Größen. Es hat die folgenden Spalten: Id - Primärschlüssel + Identität Name - varchar / nvarchar

Sie hätten drei Zeilen in der Tabelle, Small, Medium und Large mit den Werten 1, 2, 3, wenn Sie sie in dieser Reihenfolge eingefügt haben.

Wenn Sie eine andere Tabelle haben, die diese Werte verwendet, können Sie den Identity-Wert als Fremdschlüssel verwenden ... oder Sie können eine dritte Spalte erstellen, bei der es sich um einen Short-Hand-Wert für die drei Werte handelt. Es hätte die Werte S, M & amp; L. Sie könnten das stattdessen als Fremdschlüssel verwenden. Sie müssten eine eindeutige Einschränkung für die Spalte erstellen.

Was das Dropdown-Menü betrifft, können Sie eins als Wert hinter den Szenen verwenden.

Sie könnten auch einen S / M / L-Wert als Primärschlüssel erstellen.

Für Ihre andere Frage, wann es am besten ist, die Ints vs Strings zu verwenden. Über dieses Thema wird wahrscheinlich viel diskutiert. Viele Leute verwenden nur gerne Identitätswerte als primäre Schlüssel. Andere Leute sagen, dass es besser ist, einen natürlichen Schlüssel zu verwenden. Wenn Sie keine Identität als Primärschlüssel verwenden, ist es wichtig sicherzustellen, dass Sie einen guten Kandidaten für den Primärschlüssel haben (stellen Sie sicher, dass dieser immer eindeutig ist und der Wert sich nicht ändert).

    
Dismissile 04.08.2010 21:52
quelle
0

Ich würde mich auch für das Denken der Leute interessieren, ich bin immer den Weg gegangen, die Enumeration in einer Nachschlagetabelle zu speichern und dann in allen Datentabellen, die auf die Enumeration verweisen, würde ich die ID speichern und die FK-Beziehung verwenden. In gewisser Weise mag ich diesen Ansatz immer noch, aber es gibt etwas Einfaches und Einfaches, den String-Wert direkt in die Tabelle zu setzen.

Geht man rein von der Größe aus, so ist ein int 4 Bytes, wobei die Zeichenkette n btyes ist (wobei n die Anzahl der Zeichen ist). Der kürzeste Wert in Ihrer Suche ist 5 Zeichen, am längsten ist 6, also würde das Speichern des tatsächlichen Werts mehr Speicherplatz verbrauchen (wenn das ein Problem war).

Was die Performance angeht, bin ich nicht sicher, ob ein Index für ein int oder für ein varchar einen Unterschied in der Geschwindigkeit / Optimierung / Indexgröße zurückgeben würde?

    
Paul Hadfield 04.08.2010 21:55
quelle