INT ou CHAR pour un champ de type

19

Quelle est la meilleure conception pour une table, un Typechamp qui est de intou char(1)? En d'autres termes, étant donné ce schéma:

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

Est-il plus efficace (en termes de performances) VehTyped'être un intou un char(1)? Supposons que vous ayez cinq types de voitures, devez-vous utiliser les valeurs incrémentales 0 -> 4 ou des caractères pour les types (par exemple, «v», «s», «c», «t», «m»)?

Si c'est plus que cela, j'utiliserais une table Type distincte et j'aurais une relation de clé étrangère, mais je ne vois pas la nécessité de cela.

Je remarque que la sys.objectsvue catalogue utilise un caractère pour le typechamp. Y at-il une raison à cela? Suis-je juste en train de saisir ici, et est-ce avec quoi je suis plus à l'aise?

Thomas Stringer
la source

Réponses:

20

Vous utiliseriez généralement tinyint qui est également de 1 octet

  • char (1) sera légèrement plus lent car la comparaison utilise le classement

  • confusion: qu'est-ce que S: SUV ou Berline ou Berline ou Sports?

  • l'utilisation d'une lettre vous limite lorsque vous ajoutez d'autres types. Voir le dernier point.

  • chaque système que j'ai vu a plus d'un client, par exemple des rapports. La logique de changer V, S en "Van", "SUV" etc. devra être répétée. L'utilisation d'une table de recherche signifie qu'il s'agit d'un simple JOIN

  • extensibilité: ajoutez un type de plus ("F" pour " Flying car "), vous pouvez une ligne dans une table de recherche ou changer beaucoup de code et de contraintes. Et votre code client aussi car cela doit savoir ce que sont V, S, F, etc.

  • maintenance: la logique est à 3 endroits: contrainte de base de données, code de base de données et code client. Avec une recherche et une clé étrangère, il peut être au même endroit

Du côté positif de l'utilisation d'une seule lettre ... euh, je n'en vois pas

Remarque: il y a une question MySQL liée à Enums . La recommandation est également d'utiliser une table de recherche.

gbn
la source
2
grands points. Cela me fait me demander pourquoi d'autres utilisent char (1) (comme sys.objects).
Thomas Stringer
2
sys.objects a un héritage qui remonte à Sybase et aux premières versions de SQL Server en.wikipedia.org/wiki/Microsoft_SQL_Server#Genesis Si vous regardez les objets système, vous pouvez voir des codes et non des ID partout, mais moins dans les nouveaux DMV. Quant aux autres personnes sauf MS? Pensez RDBMS et non OO / Enums et il est logique d'utiliser les recherches.
gbn
1
OK je suis d'accord. Merci d'avoir précisé cela. Est-ce donc une affirmation assez précise qu'il n'y a pas de véritable suringénierie avec l'intégrité relationnelle et les tables de recherche? Je veux dire, dans ce cas, avec le stockage d'une poignée d'enregistrements dans une table de recherche et leur référencement dans une table consommatrice, la déclaration précédente serait-elle exacte?
Thomas Stringer
1
@onedaywhen: Cela fait une différence si vous regardez les différents types comme des données ou comme un ensemble statique de valeurs qui ne changeront jamais. Si vous utilisez une table de types, vous pouvez simplement ajouter un autre type à la table sans avoir à modifier les règles métier dans la base de données et dans l'application.
Guffa
1
@ MichaelKjörling: Exact, si c'était juste une clé. Mais OP entend que cela signifie quelque chose comme "v" ou "s". Remarque, nous ne sommes pas sur l'auto-description et les clés naturelles complètes comme les codes de devise (EUR, USD, GBP, CHF, etc.).
gbn
3

Tout comme un complément à la bonne réponse de gbn .

Vous pourriez peut-être créer quelque chose comme ça:

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 

Vous pouvez donc faire ce que vous voulez avec votre énumération tout en préservant l'intégrité relationnelle (en utilisant une clé étrangère). Avec la codecolonne, vous pouvez utiliser vos codes de caractères à volonté, afin qu'ils soient documentés dans la base de données (et vous pouvez extraire les informations de code directement à partir de la base de données, sans transformation compliquée sur le code d'application pour une intégration de systèmes).

Fabricio Araujo
la source
Voulez-vous autoriser un nullcode?
Jack Douglas
Oui, le code est facultatif pour permettre de représenter un type de véhicule qui n'est pas encore codifié.
Fabricio Araujo
Pourquoi les gens aiment-ils continuer à supprimer les commentaires? C'est assez ennuyeux.
Fabricio Araujo
@FabricioAraujo - Si un commentaire est obsolète (par exemple, "je vais le modifier dans ma réponse" et vous le faites en fait), alors il est bon de nettoyer les commentaires qui ne s'appliquent plus.
Nick Chammas
1
Je suggérerais d'ajouter un type "non classifié" à votre table de types et de faire de la valeur par défaut de votre champ VehTypeId cette valeur non classifiée, plutôt que d'autoriser une valeur nulle dans le champ de clé étrangère. Il est généralement mauvais de faire en sorte que "null" ait une signification commerciale valide.
Michael Blackburn