103 votes

L'utilisation d'un varchar générique (255) pour tous les champs textuels présente-t-elle des inconvénients?

J'ai un contacts tableau qui contient les champs de postcode, first name, last name, town, country, phone number etc, qui sont définis comme VARCHAR(255) même si aucun de ces champs ne viendra jamais près d'avoir de 255 caractères. (Si vous vous demandez, c'est de cette façon parce que Ruby on Rails migrations carte des champs de type Chaîne de VARCHAR(255) par défaut et je n'ai jamais pris la peine de le remplacer).

Depuis VARCHAR ne stocke le nombre de caractères du champ (avec la longueur de champ), est-il un avantage distinct (performance ou autre) à l'aide, par exemple, VARCHAR(16) sur VARCHAR(255)?

En outre, la plupart de ces champs ont des indices sur eux. Ne un plus grand VARCHAR taille sur le champ une incidence sur la taille ou la performance de l'indice à tous?

Pour info je suis de l'utilisation de MySQL 5.

134voto

Bill Karwin Points 204877

Dans le stockage, VARCHAR(255) est assez intelligent pour stocker uniquement la longueur dont vous avez besoin sur une ligne donnée, à la différence de CHAR(255) qui serait toujours magasin de 255 caractères.

Mais puisque vous tagged cette question avec MySQL, je vais vous parler d'un spécifique à MySQL astuce: comme les lignes sont copiées à partir du moteur de stockage en couche SQL couche, VARCHAR champs sont convertis CHAR de gain de l'avantage de travailler avec une largeur fixe de lignes. Afin que les chaînes dans la mémoire de devenir collier à la longueur maximale de votre déclarée VARCHAR colonne.

Lorsque votre requête implicitement génère une table temporaire, par exemple, alors que le tri ou GROUP BY, ce peut utiliser beaucoup de mémoire. Si vous utilisez beaucoup d' VARCHAR(255) champs pour les données qui n'ont pas besoin d'être long, ce qui peut rendre la table temporaire très grand.

Vous aimerez peut-être aussi de savoir que ce "remplissage" comportement signifie qu'une chaîne déclarée avec le jeu de caractères utf8 plaquettes de trois octets par caractère, même pour les chaînes que vous stockez avec un octet de contenu (par exemple, ascii ou caractères latin1). Et de même utf8mb4 jeu de caractères causes de la chaîne de tampon à quatre octets par caractère dans la mémoire.

Ainsi, un VARCHAR(255) en utf8 stocker une chaîne courte comme "Pas d'opinion" prend de 11 octets sur le disque (dix bas-jeu de caractères caractères, plus un octet pour la longueur), mais il faut 765 octets en mémoire, et donc dans des tables temporaires ou triés résultats.

J'ai aidé les utilisateurs MySQL qui, sans le savoir créé 1,5 GO de tables temporaires fréquemment et ont rempli leur espace disque. Ils avaient beaucoup d' VARCHAR(255) colonnes qui, dans la pratique, le stockage des chaînes courtes.

Il est préférable de définir la colonne en fonction du type de données que vous souhaitez stocker. Il a des avantages à faire appliquer les contraintes liées, comme d'autres personnes l'ont mentionné. Mais il a les avantages physiques pour éviter à la mémoire de déchets que j'ai décrit ci-dessus.

Il est difficile de savoir ce que la plus longue à l'adresse postale est, bien sûr, qui est pourquoi beaucoup de gens choisissent un long VARCHAR qui est certainement plus que n'importe quelle adresse. Et 255 est de coutume, car il est la longueur maximale d'un VARCHAR dont la longueur peut être codé avec un octet. Il a été également le maximum, VARCHAR de la longueur de MySQL plus ancienne que la version 5.0.

25voto

shufler Points 591

En plus de la taille et de la performance des considérations de réglage de la taille d'un varchar (et peut-être plus important, de stockage et de traitement de l'obtenir moins cher à chaque seconde), l'inconvénient de l'utilisation de type varchar(255) "juste parce que" est réduite à l'intégrité des données.

La définition de limites maximales pour les chaînes de caractères est une bonne chose à faire pour éviter plus de temps que prévu chaînes d'entrer dans le SGBDR et de causer des dépassements de la mémoire tampon ou des exceptions et des erreurs plus tard lors de la récupération et l'analyse des valeurs de la base de données de plus (plus d'octets que prévu.

Par exemple, si vous avez un domaine qui accepte de deux chaînes de caractères, pour les pays les abréviations n'est pas concevable de raison de s'attendre à ce que vos utilisateurs (dans ce contexte, les programmeurs) à l'entrée complète des noms de pays. Puisque vous ne voulez pas entrer dans un "Antigua-et-Barbuda" (AG) ou "l'Île heard et des Îles McDonald" (HM), vous ne la laissez pas à la couche de base de données. Aussi, il est probable que certains programmeurs n'ont pas encore RTFMed la documentation de conception (qui existe sûrement) à savoir de ne pas le faire.

Définir le champ d'accepter deux personnages et de laisser les SGBDR (soit gracieusement par tronquer ou de ungracefully en rejetant leurs SQL avec une erreur).

Des exemples de données réelles qui n'a aucune raison de dépasser une certaine longueur:

  • Codes Postaux canadiens sont au format A1A1A1 et sont toujours à 6 caractères, même pour Santa Claus (6 caractères exclut l'espace qui peut être spécifié pour la lisibilité).
  • adresses e-mail - jusqu'à 64 octets avant le @, jusqu'à 255 octets après. Jamais plus, de peur de casser l'Internet.
  • Amérique du nord les Numéros de Téléphone ne sont jamais plus de 10 chiffres (hors l'indicatif de pays).
  • Les ordinateurs exécutant (les versions récentes de Windows ne peut pas avoir d'ordinateur les noms de plus de 63 octets, bien que plus de 15 ans n'est pas recommandée et va briser votre Windows NT serveur de la ferme.
  • État abréviations sont 2 personnages (comme les codes de pays exampled ci-dessus)
  • Les numéros de suivi UPS sont soit 18-, 12-, 11-, ou 9 caractères. Le 18 caractères des numéros commençant par "1Z" et le 11 caractères, le nombre commence par "T", qui vous fait vous demander comment ils livrent tous ces paquets si ils ne savent pas la différence entre les lettres et les chiffres.

Et ainsi de suite...

Prendre le temps de penser à vos données et de ses limites. Si vous êtes un architecte, développeur ou programmeur, c'est votre travail, après tout.

À l'aide d'un varchar(n) au lieu de varchar(255) vous permet d'éliminer le problème où les utilisateurs (utilisateurs finaux, de programmeurs, d'autres programmes) entrez une longueur inattendue de données qui va revenir hanter votre code plus tard.

Et je ne dis pas que vous ne devriez pas également de mettre en œuvre cette restriction dans le code de la logique métier utilisées par votre application.

15voto

S.Lott Points 207588

Je suis avec vous. Pointilleux attention au détail est une douleur dans le cou et a une valeur limitée.

Une fois, le disque était une denrée précieuse et nous avons utilisé à la sueur de balles pour l'optimiser. Le prix de stockage, a chuté d'un facteur 1000, ce qui rend le temps passé sur la compression de chaque octet de moins précieux.

Si vous utilisez uniquement le CHAR champs, vous pouvez obtenir de longueur fixe les lignes. Cela peut économiser de disque réel retraiter si vous avez choisi des tailles précises pour les champs. Vous pouvez obtenir plus denses de données (moins d'I/O pour les analyses de la table) et des mises à jour plus rapides (plus facile de localiser les espaces ouverts dans un bloc pour les mises à jour et des inserts.)

Toutefois, si vous sur-estimez votre tailles, ou de vos données réelles tailles sont variables, on finit par perdre de l'espace avec CHAR champs. Les données de vent moins dense (pour plus d'I/O pour les grandes ponctions).

En général, les avantages de performance, de tenter de mettre une taille sur les champs variables sont mineures. Vous pouvez facilement de référence en utilisant le type VARCHAR(255) par rapport à CHAR(x) pour voir si vous pouvez mesurer la différence.

Cependant, parfois, j'ai besoin de fournir un "petit", "moyen", "grand" de l'indice. Donc j'utilise 16, 64 et 255 pour les tailles.

13voto

Will Hartung Points 57465

Aujourd'hui, je ne peux imaginer que c'est vraiment important.

Il y a un calcul de frais généraux à l'aide de champs de longueur variable, mais avec les excès de Processeurs d'aujourd'hui, il n'est même pas la peine d'envisager. Le système d'e/S sont tellement lent qu'une de calcul des coûts de la poignée varchars effectivement inexistante. En fait, le prix d'un varchar de calcul est probablement un gain net de plus de la quantité d'espace disque enregistré en utilisant les champs de longueur variable sur des champs de longueur fixe. Vous avez probablement une plus grande ligne de la densité.

Maintenant, la complexité des champs varchar est que vous ne pouvez pas trouver facilement un enregistrement via le numéro d'enregistrement. Lorsque vous avez une longueur fixe de la taille de la ligne (avec des champs de longueur fixe), il est trivial pour calculer le bloc de disque qui un numéro de rangée de points. Avec une longueur variable rowsize, ce genre de va à la fenêtre.

Donc, maintenant vous avez besoin pour maintenir un certain type d'enregistrement numéro index, comme n'importe quelle autre clé primaire, OU vous avez besoin de faire un solide identificateur de ligne qui encode les détails (comme le bloc, etc.) à l'identificateur. Si vous le faites, cependant, les id doivent être recalculés si jamais la ligne est déplacée sur le stockage persistant. Pas grand-chose, juste besoin de réécrire toutes les entrées de l'index et assurez-vous que le vous de a) ne jamais l'exposer à la consommation ou b) ne jamais affirmer que le nombre est fiable.

Mais depuis que nous avons champs varchar aujourd'hui, la seule valeur de type varchar(16) sur varchar(255), c'est que la bd va appliquer le 16 char limite sur le type varchar(16). Si la DB modèle est censé être réellement représentatif du modèle physique de données, puis d'avoir des champs de longueur peut être de valeur. Si, toutefois, il s'agit simplement de "stockage" plutôt qu'un "modèle ET de stockage", il n'y a pas besoin que ce soit.

Ensuite, il vous suffit de discerner entre un champ de texte qui est indexable (par exemple de type varchar) vs quelque chose qui n'est pas (comme un texte ou CLOB champ). La fraise des champs ont tendance à avoir une limite sur la taille pour faciliter l'index alors que le CLOB champs ne sont pas (dans la raison).

6voto

BradC Points 18833

Dans mon expérience, si vous laissez un type de données de 255 caractères, certaines stupide de l'utilisateur (ou une personne expérimentée) aura fait de la remplir.

Ensuite, vous avez toutes sortes de problèmes, y compris de combien d'espace vous permettent de ces champs dans les rapports et les affichages à l'écran dans votre application. Sans parler de la possibilité de dépasser la limite de ligne de données dans votre base de données (si vous avez eu plus de quelques-uns de ces caractères 255 champs).

Beaucoup plus facile de choisir une limite raisonnable au début, puis la faire respecter par le biais de l'application et de la base de données.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X