¿Un valor de columna vacía ocupa el mismo espacio de almacenamiento que un valor de columna lleno?
15
Tengo una mesa con 2 columnas. El tipo de ambas columnas está establecido en varchar(38). Si creo una fila con un valor vacío para una de las columnas, ¿ocupará el mismo espacio de almacenamiento que si el valor no estuviera vacío?
En otras palabras, ¿MySQL reservará espacio de almacenamiento para la columna (dependiendo de su tipo) cuando se cree una fila?
Un valor NULL de SQL reserva uno o dos bytes en el directorio de registros. Además de eso, un valor SQL NULL reserva cero bytes en la parte de datos del registro si se almacena en una columna de longitud variable . En una columna de longitud fija, reserva la longitud fija de la columna en la parte de datos del registro. Reservar el espacio fijo para valores NULL permite que se realice una actualización de la columna de NULL a un valor no NULL sin causar fragmentación de la página de índice.
La parte de longitud variable del encabezado del registro contiene un vector de bits para indicar columnas NULL. Si el número de columnas en el índice que puede ser NULL es N, el vector de bits ocupa bytes CEILING (N / 8) . (Por ejemplo, si hay entre 9 y 15 columnas que pueden ser NULL, el vector de bits usa dos bytes). Las columnas que son NULL no ocupan espacio que no sea el bit en este vector . La parte de longitud variable del encabezado también contiene las longitudes de las columnas de longitud variable. Cada longitud toma uno o dos bytes, dependiendo de la longitud máxima de la columna. Si todas las columnas del índice NO SON NULAS y tienen una longitud fija, el encabezado del registro no tiene una parte de longitud variable.
En base a estos puntos de viñeta, esto es lo que ocupa un NULLvalor para el almacenamiento de una columna
longitud variable: un valor NULL no ocupa almacenamiento en la fila misma
longitud fija: ocupa el espacio reservado
Ahora, debe decidir entre usar CHAR y VARCHAR debido a lo que trajo el primer punto
Reservar el espacio fijo para valores NULL permite realizar una actualización de la columna de NULL a un valor que no sea NULL sin causar fragmentación de la página de índice.
Hola Rolando, había otro elemento que olvidé mencionar, la diferencia en la asignación de memoria entre una declaración de tipo varchar (5) y varchar (100). O realmente la pena incurrida por la sobreasignación.
Craig Efrein
@CraigEfrein Definitivamente debe agregar la asignación de memoria que a su respuesta. (Por cierto, ya he votado tu respuesta)
RolandoMySQLDBA
1
La penalización por sobreasignación ocurre cuando tiene un complejo SELECTque necesita crear una tabla temporal. Si es posible, usará MEMORYy convertirá VARCHARa CHARpara la tabla tmp. Ahora VARCHAR(100)toma unos 100 (o 300) bytes fijos, lo que posiblemente ralentiza la consulta.
Rick James
@RolandoMySQLDBA, ¿El comportamiento explicado en su respuesta se aplica a los formatos de fila Mysql 5.7 DYNAMIC y COMPACT?
Esto solo aborda el espacio utilizado por la columna varchar y no considera el espacio de almacenamiento total utilizado por la fila, sus índices, claves primarias y otras columnas.
Como ypercube menciona en su comentario, hay consideraciones adicionales para el almacenamiento de filas en su conjunto cuando al menos una columna anulable está presente.
La parte de longitud variable del encabezado del registro contiene un vector de bits para indicar columnas NULL. Si hay entre 9 y 15 columnas que pueden ser NULL, el vector de bits usa dos bytes).
...
La parte de longitud variable del encabezado también contiene las longitudes de las columnas de longitud variable. Cada longitud toma uno o dos bytes, dependiendo de la longitud máxima de la columna. Si todas las columnas del índice NO SON NULAS y tienen una longitud fija, el encabezado del registro no tiene una parte de longitud variable
Y sí, el espacio de almacenamiento utilizado cambia según el tipo que elija, es fijo o variable, la clasificación y otros factores, como el motor.
Una consideración adicional con varchar y eso es memoria. Es importante en MySQL limitar el tamaño de una columna de longitud variable tanto como sea posible. Aunque la columna es variable y el espacio de almacenamiento utilizado es variable, MySQL asignará memoria en fragmentos fijos para almacenar valores. Por ejemplo, varchar (200) usará más memoria que varchar (5). Este no es un problema de espacio de almacenamiento, pero aún es algo a considerar al definir sus columnas.
SELECT
que necesita crear una tabla temporal. Si es posible, usaráMEMORY
y convertiráVARCHAR
aCHAR
para la tabla tmp. AhoraVARCHAR(100)
toma unos 100 (o 300) bytes fijos, lo que posiblemente ralentiza la consulta.Independientemente de la longitud que defina para su columna varchar, el espacio de almacenamiento utilizado por una columna vacía será el mismo.
Los tipos CHAR y VARCHAR
Esto solo aborda el espacio utilizado por la columna varchar y no considera el espacio de almacenamiento total utilizado por la fila, sus índices, claves primarias y otras columnas.
Como ypercube menciona en su comentario, hay consideraciones adicionales para el almacenamiento de filas en su conjunto cuando al menos una columna anulable está presente.
Estructura de fila física de Innodb
Y sí, el espacio de almacenamiento utilizado cambia según el tipo que elija, es fijo o variable, la clasificación y otros factores, como el motor.
MySQL hace recomendaciones para optimizar el almacenamiento de datos aquí: Optimización del tamaño de datos
Actualizar
Una consideración adicional con varchar y eso es memoria. Es importante en MySQL limitar el tamaño de una columna de longitud variable tanto como sea posible. Aunque la columna es variable y el espacio de almacenamiento utilizado es variable, MySQL asignará memoria en fragmentos fijos para almacenar valores. Por ejemplo, varchar (200) usará más memoria que varchar (5). Este no es un problema de espacio de almacenamiento, pero aún es algo a considerar al definir sus columnas.
fuente
CHARACTER SET
latin1 o ascii. Para utf8, el almacenamiento requeridoCHAR(4)
es 12.