Quels sont les cas d'utilisation pour sélectionner CHAR sur VARCHAR dans SQL?


270

Je me rends compte que CHAR est recommandé si toutes mes valeurs sont à largeur fixe. Mais alors quoi? Pourquoi ne pas simplement choisir VARCHAR pour tous les champs de texte juste pour être sûr.

Réponses:


386

Choisissez généralement CHAR si toutes les lignes auront presque la même longueur . Choisissez VARCHAR lorsque la longueur varie considérablement. CHAR peut également être un peu plus rapide car toutes les lignes sont de la même longueur.

Cela varie selon l'implémentation de la base de données, mais généralement VARCHAR utilise un ou deux octets de stockage supplémentaires (pour la longueur ou la terminaison) en plus des données réelles. Donc (en supposant que vous utilisez un jeu de caractères d'un octet) stocker le mot "FooBar"

  • CHAR (6) = 6 octets (pas de surcharge)
  • VARCHAR (10) = 8 octets (2 octets de surcharge)
  • CHAR (10) = 10 octets (4 octets de surcharge)

En bout de ligne, CHAR peut être plus rapide et plus efficace en termes d'espace pour des données de même longueur (dans une différence de longueur de deux caractères).

Remarque : Microsoft SQL a 2 octets de surcharge pour un VARCHAR. Cela peut varier d'une base de données à l'autre, mais généralement il y a au moins 1 octet de surcharge nécessaire pour indiquer la longueur ou la fin de vie sur un VARCHAR.

Comme l'a souligné Gaven dans les commentaires, si vous utilisez un jeu de caractères multi-octets de longueur variable comme UTF8, CHAR stocke le nombre maximal d'octets nécessaires pour stocker le nombre de caractères. Donc, si UTF8 a besoin d'au plus 3 octets pour stocker un caractère, alors CHAR (6) sera fixé à 18 octets, même s'il ne stocke que des caractères latin1. Dans ce cas, VARCHAR devient donc un bien meilleur choix.


20
Une autre raison est le fractionnement et la fragmentation des pages. J'avais une table avec un IDEN PK qui a été fragmenté à 99% en raison des fractionnements de page sur les colonnes varchar. Une table très active et par nature de l'application, une nouvelle ligne vide serait créée puis remplie. Char a résolu le problème de fragmentation.
paparazzo du

12
@Jim McKeeth - ces calculs ne sont vrais que si vous utilisez le jeu de caractères latin1. Étant donné que la plupart des gens devraient utiliser utf8 ces jours-ci, vos colonnes CHAR utiliseront en moyenne 3 fois l'espace en tant que VARCHAR qui stocke principalement des caractères dans le plan multilingue de base.
Gavin Towey

11
@ JimMcKeeth oui, c'est exactement correct. Puisque CHAR est de longueur fixe, il doit donc être fixé à l'espace maximum possible qui pourrait être utilisé. En UTF8, c'est 3 octets par caractère. Pour varchar, il est libre d'utiliser 1 à 3 octets par caractère selon les besoins. C'est dans le manuel MySQL: dev.mysql.com/doc/refman/5.0/en/charset-unicode-utf8.html
Gavin Towey

3
Quelle est la différence avec la chaîne FooBar et varchar (100) vs char (100)? Je pense que cela démontre mieux la différence, non? Non?
Nenotlep

4
@GavinTowey SQLSERVER utilise UCS-2 pour ses types de données NCHAR et NVARCHAR. C'est toujours deux octets par caractère.
1010

69

Si vous travaillez avec moi et que vous travaillez avec Oracle, je vous ferais probablement utiliser varchardans presque toutes les circonstances. L'hypothèse qui charutilise moins de puissance de traitement que varcharpeut être vrai ... pour l'instant ... mais les moteurs de base de données s'améliorent avec le temps et ce genre de règle générale a fait un futur "mythe".

Autre chose: je n'ai jamais vu de problème de performance car quelqu'un a décidé d'y aller varchar. Vous utiliserez beaucoup mieux votre temps à écrire du bon code (moins d'appels à la base de données) et du SQL efficace (comment fonctionnent les index, comment l'optimiseur prend-il des décisions, pourquoi est-il existsplus rapide que d' inhabitude ...).

Pensée finale: j'ai vu toutes sortes de problèmes avec l'utilisation de CHAR, les gens qui recherchent `` quand ils devraient chercher '', ou les gens qui recherchent 'FOO' quand ils devraient chercher 'FOO (tas d'espaces ici)' ' , ou des personnes ne supprimant pas les blancs de fin, ou des bogues avec Powerbuilder ajoutant jusqu'à 2000 blancs à la valeur renvoyée par une procédure Oracle.


20
Je suis en désaccord avec votre premier paragraphe, car char peut fournir un indice qui pourrait être utile aux optimiseurs, même futurs, et cela peut aider à communiquer l'intention de la colonne. Mais +1 pour votre troisième paragraphe. Je déteste tous les espaces supplémentaires. Un champ doit simplement stocker tout ce que je mets dedans sans tout le rembourrage [explicatif]. Fondamentalement, j'utilise simplement char si toutes les données doivent être exactement de la même longueur, ni plus ni moins, maintenant et pour toujours. Ceci est très rare, bien sûr, et est généralement un caractère (1).
Jeffrey L Whitledge

char fournit également des conseils aux analystes et aux développeurs ... cette chose est x nombre de caractères .... S'ils envisagent de le sérialiser dans un autre format, cela pourrait être utile. (J'ai été forcé de stocker une somme de contrôle md5 dans un caractère dans mssql qui n'avait pas de type uuid ... et je n'ai jamais voulu quoi que ce soit <32 octets ... a également mis une contrainte sur la colonne).
joefromct

31

En plus des avantages de performance, CHARpeut être utilisé pour indiquer que toutes les valeurs doivent être de la même longueur, par exemple, une colonne pour les abréviations des États américains.


Ou les codes de pays - peuvent aider à distinguer l'utilisation d'une abréviation de code de pays à 2 ou 3 caractères
Dan Field

Si c'est vraiment une longueur fixe, alors il devrait y avoir une contrainte imposant cela. Bien que si vous utilisez CHAR, vous devrez vous assurer que votre contrainte réduit le remplissage.
jpmc26

18

Char est un peu plus rapide, donc si vous avez une colonne que vous SAVEZ avoir une certaine longueur, utilisez char. Par exemple, stocker (M) ale / (F) emale / (U) nknown pour le sexe, ou 2 caractères pour un état américain.


4
Je ne suis pas sûr que ce soit une excellente réponse, car un ENUM aurait généralement beaucoup plus de sens, même si je ne sais pas à quel point ce type est largement pris en charge (en dehors de MySQL).
Bobby Jack

Il me semble que l'ensemble des états n'est pas nécessairement immuable, donc char (2) semble beaucoup plus approprié qu'une énumération.
Kearns

1
@Bobby Jack - Je ne connais pas les détails spécifiques d'une implémentation d'énumération SQL particulière, mais gardez à l'esprit qu'une énumération stockée sous la forme d'un entier de 4 octets peut nécessiter plus d'espace qu'une colonne char (1) ou char (2) avec la colonne mêmes données. Il y a un sens dans lequel les énumérations sont plus logiques en termes d'interprétation, et cela peut être convaincant, mais tout dans un système SGBDR est abstrait à un certain niveau et soumis aux prédicats définis pour les tables.
Jeffrey L Whitledge

4
Mauvais exemple, ENUM est le meilleur pour ce cas. Un meilleur exemple serait un code d'aéroport IATA à 3 lettres
Andrew G. Johnson

5
@Andrew, tous les types de données ENUM ne sont pas pris en charge par db. MSSQLServer, par exemple, ne le fait pas. En outre, un ENUM, stocké en tant qu'int, prend 4 octets. CHAR (1) prend 1 octet et NCHAR (1) prend 2 octets.
Jarrett Meyer

17

NChar ou Char fonctionnent-ils mieux que leurs alternatives var?

Grande question. La réponse simple est oui dans certaines situations. Voyons si cela peut être expliqué.

Évidemment, nous savons tous que si je crée une table avec une colonne de varchar (255) (appelons cette colonne maColonne) et que j'insère un million de lignes mais que je mets seulement quelques caractères dans maColonne pour chaque ligne, la table sera beaucoup plus petite (dans l'ensemble nombre de pages de données nécessaires au moteur de stockage) que si j'avais créé myColumn en tant que char (255). Chaque fois que je fais une opération (DML) sur cette table et demande beaucoup de lignes, ce sera plus rapide lorsque myColumn est varchar car je n'ai pas à me déplacer à la fin de tous ces espaces "supplémentaires". Déplacer, comme lorsque SQL Server effectue des tris internes, comme lors d'une opération distincte ou d'union, ou s'il choisit une fusion pendant son plan de requête, etc.

Mais il y a des frais généraux à utiliser varchar. SQL Server doit utiliser un indicateur de deux octets (surcharge) pour, sur chaque ligne, savoir combien d'octets cette colonne particulière contient ma colonne. Ce n'est pas les 2 octets supplémentaires qui posent le problème, c'est le fait de "décoder" la longueur des données dans myColumn sur chaque ligne.

D'après mes expériences, il est plus judicieux d'utiliser char au lieu de varchar sur les colonnes qui seront jointes dans les requêtes. Par exemple, la clé primaire d'une table ou une autre colonne qui sera indexée. CustomerNumber sur une table démographique, ou CodeID sur une table de décodage, ou peut-être OrderNumber sur une table de commande. En utilisant char, le moteur de requête peut effectuer plus rapidement la jointure car il peut effectuer l'arithmétique du pointeur droit (de manière déterministe) plutôt que de déplacer ses pointeurs d'une quantité variable d'octets lors de la lecture des pages. Je sais que je pourrais vous avoir perdu sur cette dernière phrase. Les jointures dans SQL Server sont basées sur l'idée de «prédicats». Un prédicat est une condition. Par exemple, myColumn = 1 ou OrderNumber <500.

Donc, si SQL Server exécute une instruction DML et que les prédicats ou les "clés" joints sont de longueur fixe (char), le moteur de requête n'a pas à faire autant de travail pour faire correspondre les lignes d'une table aux lignes de une autre table. Il ne sera pas nécessaire de savoir combien de temps les données sont dans la ligne, puis de parcourir la chaîne pour trouver la fin. Tout cela prend du temps.

Gardez maintenant à l'esprit que cela peut facilement être mal mis en œuvre. J'ai vu des caractères utilisés pour les champs de clé primaire dans les systèmes en ligne. La largeur doit être réduite, c.-à-d. Char (15) ou quelque chose de raisonnable. Et cela fonctionne mieux dans les systèmes en ligne, car vous ne récupérez ou n'insérez généralement qu'un petit nombre de lignes, donc avoir à "rtrim" ces espaces de fin que vous obtiendrez dans le jeu de résultats est une tâche triviale au lieu d'avoir à rejoindre des millions de des lignes d'une table à des millions de lignes sur une autre table.

Une autre raison pour laquelle CHAR a du sens par rapport à varchar sur les systèmes en ligne est qu'elle réduit les divisions de page. En utilisant char, vous "réservez" (et gaspillez) cet espace, donc si un utilisateur arrive plus tard et met plus de données dans cette colonne, SQL lui a déjà alloué de l'espace et y va.

Une autre raison d'utiliser CHAR est similaire à la deuxième raison. Si un programmeur ou un utilisateur effectue une mise à jour "par lots" sur des millions de lignes, en ajoutant une phrase à un champ de note par exemple, vous ne recevrez pas d'appel de votre DBA au milieu de la nuit pour vous demander pourquoi leurs lecteurs sont pleins. En d'autres termes, cela conduit à une croissance plus prévisible de la taille d'une base de données.

Ce sont donc 3 façons dont un système en ligne (OLTP) peut bénéficier de char sur varchar. Je n'utilise presque jamais char dans un scénario d'entrepôt / d'analyse / OLAP car généralement vous avez tellement de données que toutes ces colonnes de char peuvent ajouter jusqu'à beaucoup d'espace gaspillé.

Gardez à l'esprit que char peut augmenter considérablement la taille de votre base de données, mais la plupart des outils de sauvegarde ont une compression de données, de sorte que vos sauvegardes ont généralement la même taille que si vous aviez utilisé varchar. Par exemple, LiteSpeed ​​ou RedGate SQL Backup.

Une autre utilisation est dans les vues créées pour exporter des données vers un fichier à largeur fixe. Disons que je dois exporter certaines données dans un fichier plat pour être lues par un ordinateur central. C'est une largeur fixe (non délimitée). J'aime stocker les données dans ma table "intermédiaire" en tant que varchar (consommant ainsi moins d'espace sur ma base de données), puis utiliser une vue pour tout CAST à son équivalent char, avec la longueur correspondant à la largeur de la largeur fixe pour cette colonne . Par exemple:

create table tblStagingTable (
pkID BIGINT (IDENTITY,1,1),
CustomerFirstName varchar(30),
CustomerLastName varchar(30),
CustomerCityStateZip varchar(100),
CustomerCurrentBalance money )

insert into tblStagingTable
(CustomerFirstName,CustomerLastName, CustomerCityStateZip) ('Joe','Blow','123 Main St Washington, MD 12345', 123.45)

create view vwStagingTable AS
SELECT CustomerFirstName = CAST(CustomerFirstName as CHAR(30)),
CustomerLastName = CAST(CustomerLastName as CHAR(30)),
CustomerCityStateZip = CAST(CustomerCityStateZip as CHAR(100)),
CustomerCurrentBalance = CAST(CAST(CustomerCurrentBalance as NUMERIC(9,2)) AS CHAR(10))

SELECT * from vwStagingTable

C'est cool car en interne mes données prennent moins de place car elles utilisent varchar. Mais lorsque j'utilise DTS ou SSIS ou même juste un copier-coller de SSMS vers le Bloc-notes, je peux utiliser la vue et obtenir le bon nombre d'espaces de fin. Dans DTS, nous avions l'habitude d'avoir une fonctionnalité appelée, putain j'oublie que je pense qu'elle s'appelait "suggérer des colonnes" ou quelque chose. Dans SSIS, vous ne pouvez plus faire cela, vous devez définir fastidieusement le gestionnaire de connexion de fichiers plats. Mais comme vous avez configuré votre vue, SSIS peut connaître la largeur de chaque colonne et gagner beaucoup de temps lors de la création de vos tâches de flux de données.

Donc, en fin de compte ... utilisez varchar. Il y a un très petit nombre de raisons d'utiliser char et ce n'est que pour des raisons de performances. Si vous avez un système avec des centaines de millions de lignes, vous verrez une différence notable si les prédicats sont déterministes (char), mais pour la plupart des systèmes, l'utilisation de char gaspille simplement de l'espace.

J'espère que cela pourra aider. Jeff


Vous dites que le chat fixe prend plus de place non seulement lorsqu'il est stocké, mais aussi lorsqu'il est transporté ou "déplacé" comme vous le dites? Du serveur DB à mon client par exemple? Quand perdons-nous ces octets nuls?
The Red Pea

9

Il existe des avantages en termes de performances, mais en voici un qui n'a pas été mentionné: la migration des lignes. Avec char, vous réservez tout l'espace à l'avance, alors disons que vous avez un char (1000), et que vous stockez 10 caractères, vous utiliserez les 1000 caractères de l'espace. Dans un varchar2 (1000), vous n'utiliserez que 10 caractères. Le problème survient lorsque vous modifiez les données. Supposons que vous mettez à jour la colonne pour qu'elle contienne désormais 900 caractères. Il est possible que l'espace pour développer le varchar ne soit pas disponible dans le bloc actuel. Dans ce cas, le moteur de base de données doit migrer la ligne vers un autre bloc et créer un pointeur dans le bloc d'origine vers la nouvelle ligne du nouveau bloc. Pour lire ces données, le moteur DB devra maintenant lire 2 blocs.
Personne ne peut dire de manière équivoque que varchar ou char sont meilleurs. Il y a un espace pour le compromis temporel et la question de savoir si les données seront mises à jour, surtout s'il y a de fortes chances qu'elles augmentent.


Je pense que vous avez une faute de frappe dans votre message - varchar2 (1000) ne devrait-il pas être CHAR (1000)?
Matt Rogish

8

Il existe une différence entre l'optimisation précoce des performances et l'utilisation d'un type de règle de meilleure pratique. Si vous créez de nouvelles tables où vous aurez toujours un champ de longueur fixe, il est logique d'utiliser CHAR, vous devriez l'utiliser dans ce cas. Ce n'est pas une optimisation précoce, mais plutôt l'implémentation d'une règle empirique (ou meilleure pratique).

ie - Si vous avez un champ d'état à 2 lettres, utilisez CHAR (2). Si vous avez un champ avec les noms d'état réels, utilisez VARCHAR.


8

Je choisirais varchar à moins que la colonne stocke une valeur fixe comme le code d'état américain - qui est toujours de 2 caractères et que la liste des codes d'états américains valides ne change pas souvent :).

Dans tous les autres cas, même si vous stockez un mot de passe haché (de longueur fixe), je choisirais varchar.

Pourquoi - la colonne de type char est toujours remplie d'espaces, ce qui fait que la colonne my_column est définie comme char (5) avec la valeur 'ABC' dans la comparaison:

my_column = 'ABC' -- my_column stores 'ABC  ' value which is different then 'ABC'

faux.

Cette fonctionnalité peut entraîner de nombreux bugs irritants lors du développement et compliquer les tests.


1
Au moins dans MSSQL Server, 'abc' = 'abc'. Je n'ai jamais vraiment compris si
Mark Brackett

Une bonne lecture sur le rembourrage des ombles ici Padding
Edward

6

CHAR prend moins d'espace de stockage que VARCHAR si toutes vos valeurs de données dans ce champ sont de la même longueur. Maintenant, peut-être qu'en 2009, une base de données de 800 Go est la même à toutes fins utiles qu'un 810 Go si vous avez converti les VARCHAR en CHAR, mais pour les chaînes courtes (1 ou 2 caractères), CHAR est toujours une «meilleure pratique» de l'industrie, je dirais.

Maintenant, si vous regardez la grande variété de types de données que la plupart des bases de données fournissent même pour les entiers seuls (bit, minuscule, int, bigint), il y a des raisons de choisir l'un plutôt que l'autre. Choisir simplement bigint à chaque fois est en fait un peu ignorant des buts et des utilisations du domaine. Si un champ représente simplement l'âge d'une personne en années, un bigint est exagéré. Maintenant, ce n'est pas nécessairement "faux", mais ce n'est pas efficace.

Mais c'est un argument intéressant, et à mesure que les bases de données s'améliorent avec le temps, on pourrait faire valoir que CHAR vs VARCHAR devient moins pertinent.


4

Je maintiens le commentaire de Jim McKeeth.

De plus, l'indexation et les analyses de table complètes sont plus rapides si votre table ne contient que des colonnes CHAR. Fondamentalement, l'optimiseur sera en mesure de prédire la taille de chaque enregistrement s'il n'a que des colonnes CHAR, alors qu'il doit vérifier la valeur de la taille de chaque colonne VARCHAR.

De plus, si vous mettez à jour une colonne VARCHAR à une taille supérieure à son contenu précédent, vous pouvez forcer la base de données à reconstruire ses index (car vous avez forcé la base de données à déplacer physiquement l'enregistrement sur le disque). Avec les colonnes CHAR, cela n'arrivera jamais.

Mais vous ne vous soucierez probablement pas de la performance, à moins que votre table ne soit énorme.

Rappelez-vous les sages paroles de Djikstra. L'optimisation précoce des performances est à l'origine de tous les maux.


4
Il y a une certaine spéculation dans votre commentaire. J'ai vu maintes et maintes fois des hypothèses comme celles-ci se vérifier et l'exact opposé s'avère être vrai. Le problème est que de nombreux ingénieurs prendront des informations comme celle-ci comme l'évangile. Veuillez créer des cas de test qui reflètent vos situations réelles.
Ethan Post

Ethan a totalement raison. Cela dépend donc de l'implémentation que vous utilisez et sans référence au produit (produit, version), c'est complètement inutile.
David Schmitt

Lorsque vous mettez à jour une CHARcolonne, les index doivent également être mis à jour. Il n'y a aucune différence dans la mise à jour d'une colonne VARCHAR ou CHAR à cet égard. Pensez à mettre FOOà jour vers BAR.
a_horse_with_no_name

4

Beaucoup de gens ont souligné que si vous connaissez la longueur exacte de la valeur, l'utilisation de CHAR présente certains avantages. Mais tout en stockant les États américains sous le nom CHAR (2) est génial aujourd'hui, lorsque vous recevez le message des ventes que `` nous venons de faire notre première vente en Australie '', vous êtes dans un monde de douleur. J'envoie toujours pour surestimer combien de temps je pense que les champs devront être plutôt que de faire une supposition «exacte» pour couvrir les événements futurs. VARCHAR me donnera plus de flexibilité dans ce domaine.


3

Je pense que dans votre cas, il n'y a probablement aucune raison de ne pas choisir Varchar. Cela vous donne de la flexibilité et comme cela a été mentionné par un certain nombre de répondants, les performances sont telles maintenant que, sauf dans des circonstances très spécifiques, nous, les mortels (contrairement à Google DBA), ne remarquerons pas la différence.

Une chose intéressante à noter en ce qui concerne les types de base de données est que sqlite (une mini base de données populaire avec des performances assez impressionnantes) met tout dans la base de données sous forme de chaîne et de types à la volée.

J'utilise toujours VarChar et le rend généralement beaucoup plus grand que ce dont j'ai besoin. Par exemple. 50 pour Firstname, comme vous dites pourquoi ne pas simplement être en sécurité.


3

Je n'utiliserais JAMAIS de caractères. J'ai eu ce débat avec beaucoup de gens et ils évoquent toujours le cliché fatigué que l'omble chevalier est plus rapide. Eh bien, je dis combien de temps plus rapide? De quoi parle-t-on ici, millisecondes, secondes et si oui combien? Vous me dites parce que quelqu'un prétend que ses quelques millisecondes sont plus rapides, nous devrions introduire des tonnes de bugs difficiles à corriger dans le système?

Voici donc quelques problèmes que vous rencontrerez:

Chaque champ sera rembourré, donc vous vous retrouvez avec du code pour toujours avec RTRIMS partout. C'est également un énorme gaspillage d'espace disque pour les champs plus longs.

Supposons maintenant que vous ayez l'exemple par excellence d'un champ char d'un seul caractère, mais le champ est facultatif. Si quelqu'un passe une chaîne vide à ce champ, cela devient un espace. Ainsi, lorsqu'un autre application / processus l'interroge, ils obtiennent un seul espace, s'ils n'utilisent pas rtrim. Nous avons eu des documents xml, des fichiers et d'autres programmes, affichons un seul espace, dans des champs optionnels et cassons les choses.

Alors maintenant, vous devez vous assurer que vous passez des valeurs nulles et non des chaînes vides, au champ char. Mais ce n'est PAS l'utilisation correcte de null. Voici l'utilisation de null. Disons que vous obtenez un fichier d'un fournisseur

Nom | Sexe | Ville

Bob || Los Angeles

Si le sexe n'est pas spécifié, saisissez Bob, chaîne vide et Los Angeles dans le tableau. Supposons maintenant que vous obteniez le fichier et que son format change et que le sexe ne soit plus inclus mais était dans le passé.

Nom | Ville

Bob | Seattle

Eh bien maintenant, puisque le sexe n'est pas inclus, j'utiliserais null. Les Varchars soutiennent cela sans problèmes.

Char en revanche est différent. Vous devez toujours envoyer null. Si vous envoyez une chaîne vide, vous vous retrouverez avec un champ contenant des espaces.

Je pourrais continuer indéfiniment avec tous les bugs que j'ai dû corriger à partir des caractères et en environ 20 ans de développement.


2

Le calcul de la taille réelle nécessaire pour une valeur de colonne et l'allocation de l'espace pour un Varchar nécessitent un léger surcoût de traitement.Par conséquent, si vous êtes sûr de la durée de la valeur, il est préférable d'utiliser Char et d'éviter le hit.


2

C'est le compromis classique entre espace et performances.

Dans MS SQL 2005, Varchar (ou NVarchar pour les langues nécessitant deux octets par caractère, c'est-à-dire chinois) sont de longueur variable. Si vous ajoutez à la ligne après qu'elle a été écrite sur le disque dur, elle localisera les données dans un emplacement non contigieux à la ligne d'origine et conduira à la fragmentation de vos fichiers de données. Cela affectera les performances.

Donc, si l'espace n'est pas un problème, les caractères sont meilleurs pour les performances, mais si vous souhaitez réduire la taille de la base de données, les varchars sont meilleurs.


2

Fragmentation. Char réserve de l'espace et VarChar non. Le fractionnement de page peut être requis pour permettre la mise à jour de varchar.


En raison de nombreux autres facteurs, un fractionnement de page peut se produire lors de la mise à jour d'une CHARcolonne.
Rick James

1

lorsque vous utilisez des valeurs varchar, SQL Server a besoin de 2 octets supplémentaires par ligne pour stocker des informations sur cette colonne, alors que si vous utilisez char, il n'en a pas besoin, sauf si vous


0

Dans certaines bases de données SQL, VARCHAR sera complétée à sa taille maximale afin d'optimiser les décalages, ceci afin d'accélérer les analyses de table complètes et les index.

De ce fait, vous n'avez pas d'économie d'espace en utilisant un VARCHAR (200) par rapport à un CHAR (200)


3
Quelles bases de données implémentent VARCHAR de cette façon?
Troels Arvin

5
Sérieusement, quelle base de données l'implémente de cette façon? Ce que vous décrivez s'applique normalement à CHAR, pas à VARCHAR.
Richard Simões

mysql convertira les varchars en chars s'il y a des chars et varchars dans la même table.
Malfist

Mon interprétation des commentaires de MySQL est que cela ne s'applique pas au stockage de table primaire, mais pourrait éventuellement être pertinent pour les tables temporaires, par exemple. pour regrouper / trier les données. dev.mysql.com/doc/refman/8.0/en/char.html stackoverflow.com/questions/262238/…
Thomas W

0

L'utilisation de CHAR (NCHAR) et VARCHAR (NVARCHAR) apporte des différences dans la façon dont le serveur de base de données stocke les données. Le premier introduit des blancs de fin; J'ai rencontré un problème lors de son utilisation avec l'opérateur LIKE dans les fonctions SQL SERVER. Je dois donc le sécuriser en utilisant VARCHAR (NVARCHAR) tout le temps.

Par exemple, si nous avons une table TEST (ID INT, Status CHAR (1)) et que vous écrivez une fonction pour répertorier tous les enregistrements avec une valeur spécifique comme la suivante:

CREATE FUNCTION List(@Status AS CHAR(1) = '')
RETURNS TABLE
AS
RETURN
SELECT * FROM TEST
WHERE Status LIKE '%' + @Status '%'

Dans cette fonction, nous nous attendons à ce que lorsque nous mettons le paramètre par défaut, la fonction renvoie toutes les lignes, mais en fait ce n'est pas le cas. Changer le type de données @Status en VARCHAR résoudra le problème.


Cela peut également être modifié par ansi_padding Comment les valeurs sont récupérées
Edward
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.