web-dev-qa-db-fra.com

Meilleures pratiques pour la longueur de colonne SQL varchar

Chaque fois que vous configurez une nouvelle table SQL ou que vous ajoutez une nouvelle colonne varchar à une table existante, je me demande une chose: quelle est la meilleure valeur pour la length.

Donc, disons que vous avez une colonne appelée name de type varchar. Donc, vous devez choisir la longueur. Je ne peux pas penser à un nom> 20 caractères, mais vous ne le saurez jamais. Mais au lieu d’utiliser 20, j’arrondis toujours au numéro suivant 2 ^ n. Dans ce cas, je choisirais 32 comme longueur. Je le fais, car d’un point de vue informaticien, un nombre 2 ^ n me semble plus even que d’autres chiffres et je suppose simplement que l’architecture sous-jacente peut gérer ces chiffres légèrement mieux que d’autres.

Par exemple, le serveur MSSQL, par exemple, définit la longueur par défaut sur 50 lorsque vous choisissez de créer une colonne varchar. Cela me fait penser à ça. Pourquoi 50? est-ce juste un nombre aléatoire, ou basé sur la longueur de colonne moyenne, ou quoi?

Il est également probable, ou probable, que différentes implémentations de serveurs SQL (telles que MySQL, MSSQL, Postgres, ...) aient différentes valeurs de longueur de colonne.

264
esskar

Aucun SGBD que je connaisse ne possède une "optimisation" permettant à une VARCHAR avec une longueur de 2^n de mieux fonctionner que celle avec une longueur de max qui n'est pas une puissance de 2.

Je pense que les premières versions de SQL Server traitaient en réalité un VARCHAR de longueur 255 différemment de celui dont la longueur maximale était supérieure. Je ne sais pas si c'est toujours le cas.

Pour presque tous les SGBD, le stockage réel requis est uniquement déterminé par le nombre de caractères que vous y mettez, et non par la longueur max que vous définissez. Donc, du point de vue du stockage (et très probablement aussi du point de vue des performances), que vous déclariez une colonne comme étant VARCHAR(100) ou VARCHAR(500) ne fait aucune différence.

Vous devriez voir la longueur max fournie pour une colonne VARCHAR comme une sorte de contrainte (ou règle de gestion) plutôt que technique/physique.

Pour PostgreSQL, la meilleure configuration consiste à utiliser text sans restriction de longueur et un CHECK CONSTRAINT qui limite le nombre de caractères à votre besoin.

Si cette exigence change, la modification de la contrainte de vérification est beaucoup plus rapide que celle de la table (car la table n'a pas besoin d'être réécrite).

La même chose peut être appliquée pour Oracle et d'autres. Dans Oracle, il s'agirait toutefois de VARCHAR(4000) au lieu de text.

Je ne sais pas s’il existe une différence de stockage physique entre VARCHAR(max) et par ex. VARCHAR(500) dans SQL Server. Mais apparemment, il y a un impact sur les performances lorsque vous utilisez varchar(max) par rapport à varchar(8000).

Voir ce lien (posté par Erwin Brandstetter en commentaire)

Edit 2013-09-22

En ce qui concerne le commentaire de bigown:

Dans les versions de Postgres antérieures à la version 9.2 (qui n’était pas disponible au moment où j’écrivais la réponse initiale), une modification de la définition de la colonne a réécrit la table entière, voir par exemple ici . Depuis la version 9.2, ce n’est plus le cas et un test rapide a confirmé que l’augmentation de la taille de la colonne pour une table de 1,2 million de lignes ne prenait en réalité que 0,5 seconde.

Pour Oracle, cela semble également être vrai, à en juger par le temps nécessaire pour modifier la colonne varchar d'une grande table. Mais je n'ai trouvé aucune référence pour cela.

Pour MySQL le manuel dit " Dans la plupart des cas, ALTER TABLE crée une copie temporaire de la table d'origine ". Et mes propres tests confirment que: exécuter un ALTER TABLE sur une table de 1,2 million de lignes (comme dans mon test avec Postgres) pour augmenter la taille d'une colonne prenait 1,5 minute. Dans MySQL, cependant, vous pouvez pas utiliser la "solution de contournement" pour utiliser une contrainte de vérification afin de limiter le nombre de caractères dans une colonne.

Pour SQL Server, je n'ai pas trouvé d'indication claire à ce sujet, mais le temps d'exécution nécessaire pour augmenter la taille d'une colonne varchar (à nouveau le tableau de 1,2 million de lignes ci-dessus) indique que non la réécriture a lieu.

Modifier le 2017-01-24

On dirait que je me suis trompé (au moins partiellement) sur SQL Server. Voir cette réponse d'Aaron Bertrand qui montre que la longueur déclarée d'une colonne nvarchar ou varchar fait une énorme différence pour la performance.

219

VARCHAR(255) et VARCHAR(2) prenez exactement la même quantité d'espace disque! Donc, la seule raison de le limiter est si vous avez un besoin spécifique de le réduire. Sinon, faites-les tous 255.

En particulier, lors du tri, une colonne plus grande occupe plus d'espace. Si cela nuit aux performances, vous devez vous en préoccuper et les réduire. Mais si vous ne sélectionnez qu'une seule ligne dans cette table, vous pouvez simplement les définir toutes en 255 et cela n'aura aucune importance.

Voir: Quelles sont les tailles optimales de varchar pour MySQL?

59
Ariel

À chaque fois que je configure une nouvelle table SQL, je pense de la même façon que 2 ^ n est plus "uniforme" ... mais pour résumer les réponses, il n'y a pas d'impact significatif sur l'espace de stockage en définissant simplement varchar (2 ^ n) ou même varchar (MAX).

Cela dit, vous devez toujours anticiper les implications potentielles sur le stockage et les performances lorsque vous définissez une limite élevée varchar (). Par exemple, supposons que vous créiez une colonne varchar (MAX) pour contenir les descriptions de produits avec indexation de texte intégral. Si 99% des descriptions ne contiennent que 500 caractères et que vous obtenez soudainement quelqu'un qui remplace ces descriptions par des articles de Wikipédia, vous remarquerez peut-être d'importants succès inattendus en matière de stockage et de performances.

ne autre chose à considérer de Bill Karwin :

Un impact sur les performances est possible: dans MySQL, les tables temporaires et les tables MEMORY stockent une colonne VARCHAR sous forme de colonne de longueur fixe, complétée à sa longueur maximale. Si vous concevez des colonnes VARCHAR beaucoup plus grandes que la taille maximale dont vous avez besoin, vous utiliserez plus de mémoire que nécessaire. Cela affecte l'efficacité du cache, la vitesse de tri, etc.

Fondamentalement, il suffit de proposer des contraintes commerciales raisonnables et des erreurs sur une taille légèrement supérieure. Comme @onedaywhen l'a souligné, les noms de famille au Royaume-Uni comptent généralement entre 1 et 35 caractères. Si vous décidez de lui donner varchar (64), vous ne ferez pas vraiment de mal ... sauf si vous enregistrez nom de famille de ce type , qui compterait jusqu'à 666 caractères. Dans ce cas, varchar (1028) est peut-être plus logique.

Et au cas où cela vous aiderait, voici à quoi pourrait ressembler varchar 2 ^ 5 à 2 ^ 10 s'il est rempli:

varchar(32)     Lorem ipsum dolor sit amet amet.

varchar(64)     Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donecie

varchar(128)    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donecie
                vestibulum massa. Nullam dignissim elementum molestie. Vehiculas

varchar(256)    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donecie
                vestibulum massa. Nullam dignissim elementum molestie. Vehiculas
                velit metus, sit amet tristique purus condimentum eleifend. Quis
                que mollis magna vel massa malesuada bibendum. Proinde tincidunt

varchar(512)    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donecie
                vestibulum massa. Nullam dignissim elementum molestie. Vehiculas
                velit metus, sit amet tristique purus condimentum eleifend. Quis
                que mollis magna vel massa malesuada bibendum. Proinde tincidunt
                dolor tellus, sit amet porta neque varius vitae. Seduse molestie
                lacus id lacinia tempus. Vestibulum accumsan facilisis lorem, et
                mollis diam pretium gravida. In facilisis vitae tortor id vulput
                ate. Proin ornare arcu in sollicitudin pharetra. Crasti molestie

varchar(1024)   Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donecie
                vestibulum massa. Nullam dignissim elementum molestie. Vehiculas
                velit metus, sit amet tristique purus condimentum eleifend. Quis
                que mollis magna vel massa malesuada bibendum. Proinde tincidunt
                dolor tellus, sit amet porta neque varius vitae. Seduse molestie
                lacus id lacinia tempus. Vestibulum accumsan facilisis lorem, et
                mollis diam pretium gravida. In facilisis vitae tortor id vulput
                ate. Proin ornare arcu in sollicitudin pharetra. Crasti molestie
                dapibus leo lobortis eleifend. Vivamus vitae diam turpis. Vivamu
                nec tristique magna, vel tincidunt diam. Maecenas elementum semi
                quam. In ut est porttitor, sagittis nulla id, fermentum turpist.
                Curabitur pretium nibh a imperdiet cursus. Sed at vulputate este
                proin fermentum pretium justo, ac malesuada eros et Pellentesque
                vulputate hendrerit molestie. Aenean imperdiet a enim at finibus
                fusce ut ullamcorper risus, a cursus massa. Nunc non dapibus vel
                Lorem ipsum dolor sit amet, consectetur Praesent ut ultrices sit
40
Kit

La meilleure valeur est celle qui convient aux données définies dans le domaine sous-jacent.

Pour certains domaines, VARCHAR(10) convient à l'attribut Name, pour d'autres domaines, VARCHAR(255) pourrait être le meilleur choix.

30
Oded

En ajoutant à la réponse de a_horse_with_no_name, vous pourriez trouver les points suivants qui vous intéressent ...

que vous déclariez une colonne en tant que VARCHAR (100) ou VACHAR (500) ne fait aucune différence.

-- try to create a table with max varchar length
drop table if exists foo;
create table foo(name varchar(65535) not null)engine=innodb;

MySQL Database Error: Row size too large.

-- try to create a table with max varchar length - 2 bytes for the length
drop table if exists foo;
create table foo(name varchar(65533) not null)engine=innodb;

Executed Successfully

-- try to create a table with max varchar length with nullable field
drop table if exists foo;
create table foo(name varchar(65533))engine=innodb;

MySQL Database Error: Row size too large.

-- try to create a table with max varchar length with nullable field
drop table if exists foo;
create table foo(name varchar(65532))engine=innodb;

Executed Successfully

N'oubliez pas le ou les octets de longueur et l'octet nullable pour:

name varchar(100) not null sera de 1 octet (longueur) + jusqu'à 100 caractères (latin1)

name varchar(500) not null sera de 2 octets (longueur) + jusqu'à 500 caractères (latin1)

name varchar(65533) not null sera de 2 octets (longueur) + jusqu'à 65 533 caractères (latin1)

name varchar(65532) sera 2 octets (longueur) + jusqu'à 65532 caractères (latin1) + 1 octet nul

J'espère que cela t'aides :)

14
Jon Black

Toujours vérifier auprès de votre expert du domaine des affaires. Si c'est votre cas, recherchez une norme de l'industrie. Si, par exemple, le domaine en question est le nom de famille d'une personne physique (nom de famille), pour une entreprise du Royaume-Uni, je voudrais aller au catalogue de normes de données Govtalk du Royaume-Uni pour obtenir des informations sur les personnes et découvrir qu'un nom de famille sera entre 1 et 35 caractères.

6
onedaywhen

Je n'ai pas vérifié cela récemment, mais je savais auparavant avec Oracle que le pilote JDBC réservait un bloc de mémoire lors de l'exécution de la requête pour que le jeu de résultats revienne. La taille du bloc de mémoire dépend des définitions de colonne et de la taille d'extraction. La longueur des colonnes varchar2 affecte donc la quantité de mémoire réservée. Cela me causait de graves problèmes de performances il y a des années, car nous utilisions toujours varchar2 (4000) (le maximum à l'époque) et la récupération de place était beaucoup moins efficace qu'aujourd'hui.

3
user1041892