882 votes

MySQL : Grand VARCHAR vs. TEXT ?

J'ai une table de messages dans MySQL qui enregistre des messages entre utilisateurs. En dehors des ids et des types de messages typiques (tous des types entiers), j'ai besoin de sauvegarder le texte du message réel en tant que VARCHAR ou TEXT. Je fixe une limite côté front-end de 3000 caractères, ce qui signifie que les messages ne seront jamais insérés dans la base de données avec une longueur supérieure à cela.

Y a-t-il une justification pour choisir entre VARCHAR(3000) ou TEXT ? Il y a quelque chose à propos d'écrire simplement VARCHAR(3000) qui semble quelque peu contre-intuitif. J'ai parcouru d'autres publications similaires sur Stack Overflow mais ce serait bien d'obtenir des points de vue spécifiques à ce type de stockage de messages courant.

33 votes

Un peu vieux, mais je suis venu ici parce que je suis tombé sur un problème qui m'a fait réfléchir à cela. Dans mon cas, mon formulaire front-end était limité à 2 000 caractères, mais le codage implicite dans ma méthode de stockage encodait les caractères internationaux sous forme de plusieurs caractères (ce qui peut apparemment varier de 3 à 12 par caractère). Ainsi, mes 2 000 caractères deviennent soudainement jusqu'à 24 000. Quelque chose à méditer...

3 votes

J'ai trouvé que le texte était significativement plus rapide pour de nombreuses insertions concurrentes.

1 votes

@JamesS: utf8mb4... >.< @JamesS: utf8mb4... >.<

830voto

MindStalker Points 7476
  • TEXTE et BLOB peuvent être stockés en dehors de la table, la table contenant simplement un pointeur vers l'emplacement du stockage réel. L'endroit où il est stocké dépend de nombreuses choses comme la taille des données, la taille des colonnes, le format de ligne et la version de MySQL.

  • VARCHAR est stocké en ligne avec la table. VARCHAR est plus rapide lorsque la taille est raisonnable, le compromis en matière de vitesse dépend de vos données et de votre matériel, vous voudriez faire des tests de performance avec un scénario réel avec vos données.

153 votes

+1: VARCHAR (stocké en ligne) est généralement plus rapide SI les données sont fréquemment récupérées (inclues dans la plupart des requêtes). Cependant, pour un volume important de données qui ne sont normalement pas récupérées (c'est-à-dire, non référencées par aucune requête), il peut être préférable de ne pas stocker les données en ligne. Il existe une limite supérieure à la taille de la ligne pour les données stockées en ligne.

4 votes

@MindStalker Est-ce toujours vrai 2 ans plus tard? Je me souviens vaguement avoir lu que le TEXTE peut également être en ligne s'ils sont petits.. ?

1 votes

@spencer7593, alors quand nous sommes dans la limite de 65535 octets en taille de ligne, devrions-nous utiliser varchar ou devrions-nous utiliser text? Quel est exactement l'avantage de stocker des données hors des tables lorsque nous sommes dans la limite de 65535 octets?

504voto

Michael Calkins Points 3927

Pouvez-vous prédire quelle serait la longueur de l'entrée utilisateur?

VARCHAR(X)

Longueur maximale: variable, jusqu'à 65 535 octets (64 Ko)
Exemple: nom d'utilisateur, email, pays, sujet, mot de passe


TEXT

Longueur maximale: 65 535 octets (64 Ko)
Exemple: messages, emails, commentaires, texte formaté, html, code, images, liens


MEDIUMTEXT

Longueur maximale: 16 777 215 octets (16 Mo)
Exemple: grands documents json, livres de longueur courte à moyenne, chaînes csv


LONGTEXT

Longueur maximale: 4,294,967,29 octets (4 Go)
Exemple: manuels, programmes, années de fichiers journaux, harry potter et la coupe de feu, enregistrement de recherches scientifiques

Il y a plus d'informations sur cette question.

8 votes

La prévisibilité est vraiment un élément secondaire ici. C'est en fait la longueur maximale attendue qui devrait être le facteur décisif. Les éléments que vous mentionnez comme étant plus prévisibles le sont uniquement parce qu'ils sont plus courts que les autres.

32 votes

@andrew-barber C'est pourtant ce que je veux dire. Tous les autres messages expliquent bien les différences mais pas les situations où vous devez réellement choisir entre les deux. J'essayais de souligner que l'utilisation de varchar pour des données courtes et prévisibles est un bon choix et l'utilisation de texte pour des données longues et arbitraires est un bon choix.

1 votes

Si toutes les colonnes sont courtes et prévisibles (par exemple : l'adresse MAC, l'IMEI, etc ... sont des choses qui ne changent jamais), utilisez des colonnes CHAR et vous pouvez rendre la taille de votre ligne fixe, ce qui devrait accélérer considérablement les choses si vous utilisez MyISAM, peut-être aussi InnoDb bien que je ne sois pas sûr.

221voto

James Points 2070

Juste pour clarifier la meilleure pratique :

  1. Les messages au format texte doivent presque toujours être stockés en tant que TEXT (ils finissent par être arbitrairement longs)

  2. Les attributs de type string doivent être stockés en tant que VARCHAR (le nom de l'utilisateur destinataire, le sujet, etc...)

Je comprends que vous avez une limite côté front end, ce qui est génial jusqu'à ce que ça ne le soit pas. *sourire* L'astuce est de considérer la base de données comme distincte des applications qui s'y connectent. Juste parce qu'une application met une limite sur les données, ne signifie pas que les données sont intrinsèquement limitées.

Qu'est-ce qui force les messages eux-mêmes à ne jamais dépasser 3000 caractères ? S'il s'agit simplement d'une contrainte d'application arbitraire (par exemple, pour une zone de texte ou quelque chose du genre), utilisez un champ TEXT au niveau des données.

0 votes

Que signifie "c'est génial jusqu'à ce que ça ne le soit plus"? À quoi fait référence "ne le soit plus"?

9 votes

@Pacerier Pour vous donner un exemple du "n'est pas" dont parle probablement James : Prenons par exemple Twitter, qui, jusqu'à très récemment, avait une limite de 140 caractères sur les MP. Ils ont décidé que ce n'était plus sensé et ont choisi de supprimer complètement cette limite. S'ils n'avaient pas anticipé cela (ce qui est probablement le cas, je pense...), ils se seraient retrouvés dans le scénario décrit ci-dessus.

9 votes

Je suis juste en train de mettre en place notre nouvelle base de données, et j'avais supposé que personne ne pourrait jamais mettre plus de 2000 caractères dans nos petits champs de commentaires, et puis, comme le note James, ce soir, tout à coup "ce n'était pas ok" parce qu'un utilisateur a soumis un commentaire très valable qui faisait 2600 caractères. J'avais utilisé varchar(2000) en pensant que cela ne pouvait pas être plus long que ça, et j'avais tort. Donc oui, c'est génial jusqu'à ce que ce ne soit pas le cas. Dans notre cas, cela n'a pris que quelques jours pour se manifester. La règle ci-dessous, Michael J. Calkins, je pense que je l'utiliserai à partir de maintenant. texte pour les messages, commentaires.

33voto

Rick James Points 15994

Réponse courte : Aucune différence pratique, de performance, ou de stockage.

Réponse longue :

Essentiellement, il n'y a pas de différence (dans MySQL) entre VARCHAR(3000) (ou toute autre limite importante) et TEXT. Le premier tronquera à 3000 caractères ; le second tronquera à 65535 octets. (Je fais une distinction entre les octets et les caractères parce qu'un caractère peut prendre plusieurs octets.)

Pour des limites plus petites en VARCHAR, il y a quelques avantages par rapport à TEXT.

  • "plus petit" signifie 191, 255, 512, 767, ou 3072, etc, selon la version, le contexte, et le JEU DE CARACTÈRES.
  • Les INDEXes sont limités en fonction de la taille d'une colonne pouvant être indexée. (767 or 3072 octets ; cela dépend de la version et des paramètres)
  • Les tables intermédiaires créées par des SELECTs complexes sont gérées de deux manières différentes - MEMORY (plus rapide) ou MyISAM (plus lent). Lorsque des colonnes 'larges' sont impliquées, la méthode la plus lente est automatiquement choisie. (Des changements significatifs sont prévus dans la version 8.0 ; donc cet élément à puce est sujet à modification.)
  • En rapport avec l'élément précédent, tous les datatypes TEXT (par opposition à VARCHAR) passent directement à MyISAM. Autrement dit, TINYTEXT est automatiquement moins bon pour les tables temporaires générées que l'équivalent VARCHAR. (Mais cela amène la discussion dans une troisième direction !)
  • VARBINARY est similaire à VARCHAR ; BLOB est similaire à TEXT.
  • Une table avec plusieurs VARCHARs 'larges' pourrait atteindre une limite de 64 Ko pour l'ensemble de la définition de la table ; passer à TEXT est une solution simple et pratique. (Exemple : (42000) Row size too large, from an Oracle dump to a MySQL dump)

Réponse aux autres réponses

La question initiale portait sur une chose (quel datatype utiliser) ; la réponse acceptée concernait autre chose (stockage hors ligne). Cette réponse est maintenant obsolète.

Lorsque ce fil de discussion a été commencé et répondu, il n'y avait que deux "formats de lignes" dans InnoDB. Peu de temps après, deux autres formats (DYNAMIC et COMPRESSED) ont été introduits.

L'emplacement de stockage pour TEXT et VARCHAR() est basé sur la taille, pas sur le nom du datatype. Pour une discussion mise à jour sur le stockage hors ligne/en ligne des grandes colonnes de texte/blob, voir ceci.

2 votes

@KostaKontos - Merci pour les compliments et la correction de la faute de frappe. Quand je vois un besoin d'une meilleure réponse, j'ajouterai une réponse, même s'il est 8 ans et 800 votes en retard.

33voto

Michael Anderson Points 21181

Avertissement: Je ne suis pas un expert MySQL ... mais cela est ma compréhension des problèmes.

Je pense que TEXTE est stocké en dehors de la ligne mysql, tandis que je pense que VARCHAR est stocké en tant que partie de la ligne. Il y a une longueur maximale de la ligne pour les lignes mysql .. donc vous pouvez limiter la quantité d'autres données que vous pouvez stocker dans une ligne en utilisant le VARCHAR.

Aussi, en raison du VARCHAR faisant partie de la ligne, je soupçonne que les requêtes regardant ce champ seront légèrement plus rapides que celles utilisant un morceau de TEXTE.

38 votes

La limite de longueur de ligne est de 65 535 octets [ dev.mysql.com/doc/refman/5.0/en/column-count-limit.html ]. Si votre colonne est encodée en utf8, cela signifie qu'une colonne varchar de 3000 caractères peut prendre jusqu'à 9000 octets.

7 votes

Les caractères UTF-8 peuvent contenir jusqu'à 4 octets, donc je pense que vous vouliez dire 12 000 octets (à moins qu'il y ait quelque chose concernant MySQL que je ne comprends pas ici).

13 votes

@raylu L'UTF-8 de MySQL est un "faux UTF-8" en ce sens qu'il ne prend en charge que 3 octets par caractère maximum, il n'y a donc aucun moyen de stocker directement des caractères Unicode au-delà du plan BMP en UTF-8 de MySQL. Cela est corrigé dans MySQL 5.5.

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