Quelle est la différence entre les types de données MySQL VARCHAR et TEXT?

19

Après la version 5.0.3 (qui autorisait VARCHAR à 65 535 octets et arrêtait de tronquer les espaces de fin), existe-t-il une différence majeure entre ces deux types de données?

Je lisais la liste des différences et les deux seules à noter sont:

Pour les index sur les colonnes BLOB et TEXT, vous devez spécifier une longueur de préfixe d'index. Pour CHAR et VARCHAR, une longueur de préfixe est facultative. Voir Section 7.5.1, «Index des colonnes».

et

Les colonnes BLOB et TEXT ne peuvent pas avoir de valeurs DEFAULT.

Donc, en raison de ces deux limitations du type de données TEXT, pourquoi l'utiliseriez-vous sur varchar (65535)? Y a-t-il des ramifications de performance de l'une sur l'autre?

Derek Downey
la source
1
quand vous voulez plus de 65535 caractères dans les données?
BlackICE
Voici un assez bon fil de discussion sur les benchmarks entre varchar et le texte: http://forums.mysql.com/read.php?24,105964,105964
divisé le
Parce que la liste là-bas fait vraiment un bon travail de présentation des détails explicites, et parce que vous avez déjà la liste énumérée des différences, je ne suis pas sûr que ce soit le genre de question dont nous avons besoin sur DBA. Y a-t-il une raison pour laquelle la liste que vous avez citée et les raisons que vous avez données ne sont pas assez bonnes dans ce cas? Sinon, je vais à VtC
jcolebrand
1
J'ai mis à jour ma question, mais une raison évidente dont je ne suis pas sûr est la performance de l'un par rapport à l'autre. Je ne sais pas s'il y a d'autres raisons pas si évidentes
Derek Downey
Alors, est-il juste que vous demandiez les caractéristiques de performance de l'une par rapport à l'autre?
jcolebrand

Réponses:

13

divisé lié à des informations qui expliquent le problème de base (il y a des différences de performances), mais ce n'est pas assez simple pour dire que l'un est toujours meilleur que l'autre. (sinon, il n'y aurait aucune raison d'avoir les deux.) De plus, dans MyISM, la taille maximale de 64 Ko pour VARCHAR n'est pas par champ - c'est par enregistrement.

Fondamentalement, il existe 4 façons de stocker des chaînes dans des enregistrements de base de données:

  1. longueur fixe
  2. Chaînes de style C (marquées d'un caractère NULL ou similaire à la fin de la chaîne)
  3. Chaînes de style Pascal (quelques octets pour indiquer la longueur, puis la chaîne)
  4. Pointeurs (stocker la chaîne ailleurs)

MyISM utilise quelque chose de similaire à # 3 pour VARCHAR, et une approche hybride pour TEXT où il stocke le début de la chaîne dans l'enregistrement, puis le reste de la chaîne ailleurs. InnoDB est similaire pour VARCHAR, mais stocke le champ TEXT complet en dehors de l'enregistrement.

Avec 1 & 4, le contenu de l'enregistrement est toujours de la même longueur, il est donc plus facile de sauter si vous n'avez pas besoin de la chaîne, mais que vous avez besoin de la suite. Les # 2 et # 3 ne sont pas trop mauvais pour les cordes courtes ... # 2 doit continuer à chercher le marqueur, tandis que # 3 peut aller de l'avant ... à mesure que les cordes s'allongent, # 2 s'aggrave pour cette utilisation particulière Cas.

Si vous avez réellement besoin de lire la chaîne, # 4 est plus lent, car vous devez lire l'enregistrement, puis lire la chaîne qui pourrait être stockée ailleurs sur le disque, selon la façon dont cette base de données la gère. # 1 est toujours assez simple, et encore une fois vous rencontrez des problèmes similaires où pour # 2 s'aggrave plus la chaîne est longue, tandis que # 3 est un peu pire que # 2 pour les très petites chaînes, mais mieux car elle s'allonge.

Ensuite, il y a des exigences de stockage ... # 1 est toujours une longueur fixe, donc il peut avoir un gonflement si la plupart des chaînes ne sont pas la longueur maximale. # 2 a 1 octet supplémentaire; # 3 a généralement 2 octets supplémentaires si la longueur maximale = 255, 4 octets supplémentaires si un maximum de 64k. # 4 a la longueur du pointeur, plus les règles pour # 3 généralement.

Pour les implémentations spécifiques dans MySQL 5.1, les documents pour MyISM indiquent :

  • Prise en charge d'un véritable type VARCHAR; une colonne VARCHAR commence par une longueur stockée dans un ou deux octets.
  • Les tables avec des colonnes VARCHAR peuvent avoir une longueur de ligne fixe ou dynamique.
  • La somme des longueurs des colonnes VARCHAR et CHAR dans une table peut atteindre 64 Ko.

Alors que pour InnoDB :

  • La partie de longueur variable de l'en-tête d'enregistrement contient un vecteur de bits pour indiquer les colonnes NULL. Si le nombre de colonnes de l'index pouvant être NULL est N, le vecteur binaire occupe les octets CEILING (N / 8). (Par exemple, s'il existe entre 9 et 15 colonnes pouvant être NULL, le vecteur de bits utilise deux octets.) Les colonnes qui sont NULL n'occupent pas d'espace autre que le bit dans ce vecteur. La partie de longueur variable de l'en-tête contient également les longueurs des colonnes de longueur variable. Chaque longueur prend un ou deux octets, selon la longueur maximale de la colonne. Si toutes les colonnes de l'index ne sont PAS NULES et ont une longueur fixe, l'en-tête d'enregistrement n'a pas de partie de longueur variable.
  • Pour chaque champ de longueur variable non NULL, l'en-tête d'enregistrement contient la longueur de la colonne en un ou deux octets. Deux octets ne seront nécessaires que si une partie de la colonne est stockée en externe dans des pages de débordement ou si la longueur maximale dépasse 255 octets et la longueur réelle dépasse 127 octets. Pour une colonne stockée en externe, la longueur sur deux octets indique la longueur de la partie stockée en interne plus le pointeur de 20 octets sur la partie stockée en externe. La partie interne est de 768 octets, donc la longueur est de 768 + 20. Le pointeur de 20 octets stocke la vraie longueur de la colonne.

...

comme avec tant d'autres choses lorsque vous traitez avec des bases de données, si vous n'êtes pas sûr de ce qui convient le mieux à vos besoins, essayez de le comparer avec des données et une utilisation similaires, et voyez comment elles se comportent.

Joe
la source
Le thread divise les états liés que MySQL stocke les objets blob
Michael Mior
1
Nitpick ... À toutes fins pratiques, il n'y a pas de limite de 64 Ko sur une ligne dans les deux moteurs. LONGTEXTet en LONGBLOBsont un exemple. Les chaînes de style C ne sont utilisées nulle part par MySQL (à ma connaissance). InnoDB utilise une approche "hybride", mais elle est plus complexe, en fonction de la taille de la ligne, du format de ligne, etc. . InnoDB en a 4 ROW_FORMATs; le texte n'en traite que 1 ou 2.
Rick James
2

Lorsqu'un SELECT doit créer une table temporaire (comme pour trier les résultats), il crée soit une table MEMORY, soit une table MyISAM. MEMORY est plus efficace. Il y a des restrictions sur la MÉMOIRE - l'une consiste à interdire TEXT et BLOB. Par conséquent, un SELECT peut s'exécuter plus lentement avec TEXT que VARCHAR.

Rick James
la source