INT oder CHAR für ein Typfeld

19

Was ist das beste Design für einen Tisch, ein TypeFeld, das aus intoder besteht char(1)? Mit anderen Worten, angesichts dieses Schemas:

create table Car
(
    Name varchar(100) not null,
    Description varchar(100) not null,
    VehType .... not null
)

Ist es effizienter (leistungsmäßig) VehType, ein intoder ein zu sein char(1)? Angenommen, Sie haben fünf Autotypen. Sollten Sie die inkrementierenden Werte 0 -> 4 oder Zeichen für die Typen verwenden (z. B. 'v', 's', 'c', 't', 'm')?

Wenn es mehr ist, würde ich eine separate Typentabelle verwenden und eine Fremdschlüsselbeziehung haben, aber ich sehe keine Notwendigkeit dafür.

Ich stelle fest, dass die sys.objectsKatalogansicht ein Zeichen für das typeFeld verwendet. Gibt es einen Grund dafür? Greife ich hier nur nach Luft, und ist es das, womit ich mich wohler fühle?

Thomas Stringer
quelle

Antworten:

20

Normalerweise verwenden Sie tinyint (1 Byte)

  • char (1) ist etwas langsamer, da beim Vergleichen die Sortierung verwendet wird

  • Verwirrung: Was ist S: SUV oder Limousine oder Sport?

  • Durch die Verwendung eines Buchstabens werden Sie beim Hinzufügen weiterer Typen eingeschränkt. Siehe letzter Punkt.

  • Jedes System, das ich gesehen habe, hat mehr als einen Client, zB Reporting. Die Logik, V, S in "Van", "SUV" usw. zu ändern, muss wiederholt werden. Die Verwendung einer Nachschlagetabelle bedeutet, dass es sich um einen einfachen JOIN handelt

  • Erweiterbarkeit: Fügen Sie einen weiteren Typ hinzu ("F" für " Fliegendes Auto "), und fügen Sie einer Nachschlagetabelle eine Zeile hinzu oder ändern Sie viele Codes und Einschränkungen. Und Ihr Client-Code auch, weil dieser wissen muss, was V, S, F usw. sind

  • Wartung: Logik besteht aus 3 Stellen: Datenbankeinschränkung, Datenbankcode und Clientcode. Mit einer Suche und einem Fremdschlüssel kann es sich an einer Stelle befinden

Ein Vorteil bei der Verwendung eines einzelnen Buchstabens: Sehen Sie keinen

Hinweis: Es gibt eine verwandte MySQL-Frage zu Enums . Es wird empfohlen, auch dort eine Nachschlagetabelle zu verwenden.

gbn
quelle
2
tolle punkte. Ich frage mich, warum andere char (1) verwenden (wie sys.objects).
Thomas Stringer
2
sys.objects hat ein Vermächtnis zu Sybase und frühen Versionen von SQL Server zurück en.wikipedia.org/wiki/Microsoft_SQL_Server#Genesis Wenn Sie das System suchen Objekte , die Sie Codes nicht IDs überall sehen können: aber weniger in den neuen DMVs. Wie für andere Leute außer MS? Denken Sie an RDBMS und nicht an OO / Enums, und es ist sinnvoll, Lookups zu verwenden.
20.
1
Ok, ich stimme zu. Danke, dass du das klargestellt hast. Ist es also eine ziemlich genaue Aussage, dass es kein echtes Over-Engineering mit relationaler Integrität und Nachschlagetabellen gibt? Ich meine, in diesem Fall, wenn eine Handvoll Datensätze in einer Nachschlagetabelle gespeichert und in einer Verbrauchertabelle referenziert werden, wäre die vorherige Aussage korrekt?
Thomas Stringer
1
@onedaywhen: Es macht einen Unterschied, ob Sie die verschiedenen Typen als Daten oder als statische Menge von Werten betrachten, die sich nie ändern werden. Wenn Sie eine Typentabelle verwenden, können Sie der Tabelle einfach einen anderen Typ hinzufügen, ohne die Geschäftsregeln in der Datenbank und in der Anwendung ändern zu müssen.
Guffa
1
@ MichaelKjörling: Richtig, wenn es nur ein Schlüssel wäre. Aber OP meint damit so etwas wie "v" oder "s". Beachten Sie, dass wir uns nicht mit selbstbeschreibenden und vollständigen natürlichen Schlüsseln wie Währungscodes (EUR, USD, GBP, CHF usw.) befassen.
20.
3

Nur als Ergänzung zur Antwort von gbn .

Vielleicht könntest du so etwas schaffen:

create table dbo.VehicleType
(
    VehicleTypeId int not null primary key,
    Name varchar(50) not null,
    Code char(3) null
) 
go 

create table Car
(
    Name varchar(100) not null,
    Description varchar(100) not null,
    VehTypeId int not null ,
    foreign key FKTypeOfCar(VehTypeId) referenctes dbo.VehicleType (VehicleTypeId) 
)
go 

Sie können also mit Ihrer Enumeration beliebig vorgehen und gleichzeitig die relationale Integrität (mithilfe eines Fremdschlüssels) gewährleisten. Mit der codeSpalte können Sie Ihre Zeichencodes nach Belieben verwenden, sodass sie in der Datenbank dokumentiert werden (und Sie können die Codeinformationen direkt aus der Datenbank extrahieren, ohne dass eine komplizierte Transformation des Anwendungscodes für eine Systemintegration erforderlich ist).

Fabricio Araujo
quelle
Wollen Sie einen nullCode zulassen ?
Jack Douglas
Ja, Code ist optional, um einen Fahrzeugtyp darzustellen, der noch nicht codiert ist.
Fabricio Araujo
Warum bleiben Leute gerne beim Löschen von Kommentaren? Ist ziemlich nervig.
Fabricio Araujo
@FabricioAraujo - Wenn ein Kommentar veraltet ist (z. B. "Ich bearbeite das in meiner Antwort" und Sie dies dann tatsächlich), ist es gut, die nicht mehr zutreffenden Kommentare zu bereinigen.
Nick Chammas
1
Ich würde vorschlagen, einen "Nicht klassifizierten" Typ zu Ihrer Typentabelle hinzuzufügen und den Standardwert Ihres VehTypeId-Felds zu diesem nicht klassifizierten Wert zu machen, anstatt einen Nullwert im Fremdschlüsselfeld zuzulassen. Es ist im Allgemeinen eine schlechte Praxis, wenn "null" eine gültige geschäftliche Bedeutung hat.
Michael Blackburn