2012-06-21 71 views
5

Vi el comentario "Si tiene 50 millones de valores entre 10 y 15 caracteres en una columna varchar (20) y los mismos 50 millones en una columna varchar (50), ocuparán exactamente el mismo espacio. punto entero de varchar, en lugar de char ". ¿Alguien puede decirme el motivo? Ver What is a reasonable length limit on person "Name" fields?varchar (20) y varchar (50) son iguales?

+1

Impone un * límite * lógico (por ejemplo, una regla BO o una "seguridad"). Por favor, busque SO - ha aparecido antes y generalmente termina en un debate de guerra de fuego. –

+0

@rabudde: ¿estás seguro de eso? ¿Puedes dar una referencia? Estaría ** muy ** sorprendido si la longitud definida se puso en el índice vor una columna varchar (ahora 'char' es una cosa diferente). Ningún DBMS que conozco almacena la longitud completa en el índice, pero entonces MySQL siempre es bueno para las sorpresas. –

+1

@pst, a_horse_with_no_name: tiene razón, estaba confundido acerca de otro hecho (UTF8 e índices), y ese es exactamente el punto, una longitud 'varchar' demasiado grande puede dar como resultado un mal rendimiento en la ordenación u operaciones en tablas temporales (referenciado en Alto Rendimiento MySQL de O'Reilly) – rabudde

Respuesta

5

MySQL ofrece una selección de motores de almacenamiento. El almacenamiento físico de datos depende del motor de almacenamiento.

de almacenamiento MyISAM de VARCHAR

En MyISAM, VARCHAR s suelen ocupar sólo la longitud real de la cadena más un byte o dos de longitud. Esto se hace práctico por la limitación de diseño de MyISAM para el bloqueo de la mesa en lugar de una capacidad de bloqueo de fila. Las consecuencias de rendimiento incluyen un perfil de caché más compacto, pero también un cómputo más complicado (más lento) de las compensaciones de registros.

(De hecho, MyISAM le da a degree of choice entre el tamaño de la fila física fija y formatos de tabla tamaño de los registros físicos variables en función de los tipos de columnas que ocurren en toda la mesa. La aparición de VARCHAR cambia el método por defecto sólo, pero la presencia de una mancha TEXTfuerzasVARCHAR s en la misma mesa para utilizar el método de longitud variable también.)

el método de almacenamiento físico es particularmente importante con índices, que es una historia diferente que las tablas. MyISAM usa compresión de espacio para ambas columnasCHAR y VARCHAR, lo que significa que los datos más cortos ocupan menos espacio en el índice en ambos casos.

de almacenamiento InnoDB VARCHAR

InnoDB, como la mayoría de otras bases de datos relacionales actuales, utiliza un mecanismo más sofisticado. VARCHAR columnas cuyo ancho máximo es inferior a 768 bytes se almacenarán en línea, con espacio reservado que coincida con ese ancho máximo. Más exactamente here:

Para cada campo de longitud variable no nulo, la cabecera de registro contiene la longitud de la columna en una o dos bytes. Solo se necesitarán dos bytes si parte de la columna se almacena externamente en páginas de desbordamiento o la longitud máxima excede 255 bytes y la longitud real excede 127 bytes. Para una columna almacenada externamente, la longitud de dos bytes indica la longitud de la parte almacenada internamente más el puntero de 20 bytes a la parte almacenada externamente. La parte interna es de 768 bytes, por lo que la longitud es 768 + 20. El puntero de 20 bytes almacena la longitud verdadera de la columna .

InnoDB actualmente no tiene compresión espacial en sus índices, lo contrario de MyISAM como se describió anteriormente.

Volviendo a la pregunta

Todo lo anterior es sin embargo, sólo un detalle de puesta en práctica que puede incluso cambiar entre versiones. La verdadera diferencia entre CHAR y VARCHAR es semántica, y también lo es entre VARCHAR(20) y VARCHAR(50). Al asegurar que no hay forma de almacenar una cadena de 30 caracteres en un VARCHAR(20), la base de datos facilita la vida y la define mejor para varios procesadores y aplicaciones que supuestamente integra en una solución de comportamiento predecible. Este es el gran problema.

En cuanto a los nombres personales específicamente, this question puede darle alguna orientación práctica. Las personas con nombres completos de más de 70 caracteres UTF-8 están en problemas de todos modos.

3

Sí, de hecho es todo el punto de VARCHAR. Solo ocupa tanto espacio como el texto es largo.

Si tuviera CHAR (50), tomaría 50 bytes (o caracteres) sin importar cuán cortos sean realmente los datos (se rellenarán, generalmente por espacios).

¿Alguien puede decirme la razón?

Porque la gente pensó que era un desperdicio almacenar una gran cantidad de relleno inútil, inventaron VARCHAR.

+0

En realidad es un poco más complicado que "relleno inútil": ¿cómo decir ''foo'' de'' foo ''en un CHAR (4)? –

+0

Es cierto. Más o menos Eso puede ser importante para algunas personas.Siempre obtengo un montón de votos negativos cuando explico esto (generalmente en el contexto de la decisión de Oracle de tratar cadenas vacías como NULL), pero cuestiono el diseño de la aplicación que necesita diferenciar entre '' foo'' y ''foo' '. (Como puede ver en este hilo de comentarios, las comillas también pueden ser una solución posible, o puede agregar algo que no se usa). – Thilo

+0

Para que aparezca un mensaje positivo sobre CHAR: permite registros de longitud fija. Puede ser importante para algunas aplicaciones de propósito especial. – Thilo

2

The manual estados:

Los tipos CHAR y VARCHAR se declaran con una longitud que indica el número máximo de caracteres que desee almacenar. (...)

En contraste con CHAR, los valores de VARCHAR se almacenan como un prefijo de un byte o de dos bytes más los datos. El prefijo de longitud indica la cantidad de bytes en el valor. Una columna utiliza un byte de longitud si los valores no requieren más de 255 bytes, dos bytes de longitud si los valores pueden requerir más de 255 bytes.

en cuenta que una VARCHAR (255) es no el mismo que VARCHAR (256).

Esto es teoría. Como sugiere habeebperwad, la huella real de una fila de depende del tamaño de la página (del motor) y del tamaño del bloque (disco duro).