web-dev-qa-db-fra.com

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

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 seuls à 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, à cause de ces deux limitations sur le 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?

19
Derek Downey

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 chaînes s'allongent, # 2 empire 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 l'état MyISM :

  • 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 de bits 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 de deux octets indique la longueur de la partie stockée en interne plus le pointeur de 20 octets vers 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.

13
Joe

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.

2
Rick James