MySQL: Gran VARCHAR vs TEXTO?


Tengo una tabla de mensajes en MySQL que registra mensajes entre usuarios. Aparte de los identificadores típicos y los tipos de mensajes (todos los tipos enteros), necesito guardar el texto del mensaje real como VARCHAR o TEXT. Estoy estableciendo un límite de front-end de 3000 caracteres, lo que significa que los mensajes nunca se insertarían en la base de datos como más largo que esto.

¿Hay una razón para ir con VARCHAR(3000) o TEXTO? Hay algo acerca de simplemente escribir VARCHAR (3000) que se siente algo contra-intuitivo. He pasado por otras publicaciones similares en Stack Overflow, pero sería bueno obtener vistas específicas para este tipo de almacenamiento de mensajes comunes.

Author: Benjamin, 2010-01-07

6 answers

  • TEXT y BLOB se almacena fuera de la tabla con la tabla solo teniendo un puntero a la ubicación del almacenamiento real.

  • VARCHAR se almacena en línea con la tabla. VARCHAR es más rápido cuando el tamaño es razonable, la compensación de lo cual sería más rápido depende de sus datos y su hardware, usted querría comparar un escenario del mundo real con sus datos.

Actualizar Si VARCHAR o TEXT se almacena en línea, o fuera de registro depende del tamaño de los datos, tamaño de las columnas, formato de fila y versión de MySQL. no depende de "texto" vs "varchar".

 769
Author: MindStalker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-25 16:12:32

¿Puede predecir cuánto tiempo será la entrada del usuario?

VARCHAR (X)

Caso: nombre de usuario, correo electrónico, país, asunto, contraseña


TEXTO

Caso: mensajes, correos electrónicos, comentarios, texto formateado, html, código, imágenes, enlaces


MEDIUMTEXT

Caso: cuerpos json grandes, libros de corta a mediana longitud, cadenas csv


LONGTEXT

Caso: libros de texto, programas, años de archivos de registros, harry potter y el cáliz de fuego, registro de investigación científica

 422
Author: Michael J. Calkins,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-15 15:16:46

Solo para aclarar la mejor práctica:

  1. Los mensajes de formato de texto casi siempre deben almacenarse como TEXTO (terminan siendo arbitrariamente largos)

  2. Los atributos de cadena deben almacenarse como VARCHAR (el nombre de usuario de destino, el asunto, etc.)...).

Entiendo que tienes un límite de front-end, que es genial hasta que no lo es. *grin* El truco es pensar en la base de datos como independiente de las aplicaciones que se conectan a ella. Solo porque uno la aplicación pone un límite a los datos, no significa que los datos estén intrínsecamente limitados.

¿Qué pasa con los mensajes mismos que los obliga a no tener más de 3000 caracteres? Si es solo una restricción de aplicación arbitraria (por ejemplo, para un cuadro de texto o algo así), use un campo TEXT en la capa de datos.

 212
Author: James,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-09-22 20:00:44

Descargo de responsabilidad: No soy un experto en MySQL ... pero esta es mi comprensión de los problemas.

Creo que el TEXTO se almacena fuera de la fila mysql, mientras que creo que VARCHAR se almacena como parte de la fila. Hay una longitud máxima de fila para filas mysql .. por lo tanto, puede limitar la cantidad de otros datos que puede almacenar en una fila mediante el uso de VARCHAR.

También debido a que VARCHAR forma parte de la fila, sospecho que las consultas que miran ese campo serán ligeramente más rápidas que las que usan un fragmento de TEXTO.

 31
Author: Michael Anderson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-01-07 20:47:02

Respuesta corta: No hay diferencia práctica, rendimiento o almacenamiento.

Respuesta Larga:

Esencialmente no hay diferencia (en MySQL) entre VARCHAR(3000) (o cualquier otro límite grande) y TEXT. El primero truncará a 3000 caracteres ; el segundo truncará a 65535 bytes. (Yo hago una distinción entre bytes y caracteres porque un personaje puede tomar múltiples bytes.)

Para los más pequeños límites en VARCHAR, hay algunas ventajas sobre TEXT.

  • "menor" significa 191, 255, 512, 767, o 3072, etc, dependiendo de la versión, contexto, y CHARACTER SET.
  • INDEXes están limitados en el tamaño de una columna puede ser indexada. (767 o 3072 bytes ; esto depende de la versión y la configuración)
  • Las tablas intermedias creadas por complex SELECTs se manejan de dos maneras diferentes: MEMORIA (más rápida) o MyISAM (más lenta). Cuando las columnas' grandes ' están involucradas, la técnica más lenta es seleccionado automáticamente. (Cambios significativos en la versión 8.0; por lo que este elemento de viñeta está sujeto a cambios.)
  • Relacionado con el ítem anterior, todos los tipos de datos TEXT (a diferencia de VARCHAR) saltan directamente a MyISAM. Es decir, TINYTEXT es automáticamente peor para las tablas temp generadas que el equivalente VARCHAR. (¡ Pero esto lleva la discusión en una tercera dirección!)
  • VARBINARY es como VARCHAR; BLOB es como TEXT.

Refutación a otras respuestas

El la pregunta original hacía una cosa( qué tipo de datos usar); la respuesta aceptada respondía otra cosa (almacenamiento fuera de registro). Esa respuesta ahora está desactualizada.

Cuando se inició este hilo y respondió, solo había dos "formatos de fila" en InnoDB. Poco después, se introdujeron dos formatos más (DYNAMIC y COMPRESSES).

La ubicación de almacenamiento para TEXT y VARCHAR() se basa en size, no en name of datatype. Para un actualizado discusión del almacenamiento on / off-record de columnas grandes de texto/blob, vea esto .

 8
Author: Rick James,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-23 18:22:02

Las respuestas anteriores no insisten lo suficiente en el problema principal: incluso en consultas muy simples como

(SELECT t2.* FROM t1, t2 WHERE t2.id = t1.id ORDER BY t1.id) 

Se puede requerir una tabla temporal, y si un campo VARCHAR está involucrado, se convierte en un campo CHAR en la tabla temporal. Así que si usted tiene en su tabla decir 500 000 líneas con un campo VARCHAR(65000), esta columna solo utilizará 6.5*5*10^9 byte. Estas tablas temporales no se pueden manejar en memoria y se escriben en el disco. Cabe esperar que el impacto sea catastrófico.

Fuente (con métricas): https://nicj.net/mysql-text-vs-varchar-performance/ (Esto se refiere al manejo de TEXT vs VARCHAR en "estándar" (?) Motor de almacenamiento MyISAM. Puede ser diferente en otros, por ejemplo, InnoDB.)

 2
Author: Max,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-23 21:06:29