Une valeur de colonne vide occupe-t-elle le même espace de stockage qu'une valeur de colonne remplie?
16
J'ai un tableau avec 2 colonnes. Le type des deux colonnes est défini sur varchar(38). Si je crée une ligne avec une valeur vide pour l'une des colonnes, cela prendra-t-il le même espace de stockage que si la valeur n'était pas vide?
En d'autres termes, MySQL réservera-t-il de l'espace de stockage pour la colonne (selon son type) lors de la création d'une ligne?
Une valeur SQL NULL réserve un ou deux octets dans le répertoire d'enregistrement. En plus de cela, une valeur SQL NULL réserve zéro octet dans la partie données de l'enregistrement si elle est stockée dans une colonne de longueur variable . Dans une colonne de longueur fixe, il réserve la longueur fixe de la colonne dans la partie données de l'enregistrement. La réservation de l'espace fixe pour les valeurs NULL permet de mettre à jour la colonne de NULL vers une valeur non NULL sans provoquer de fragmentation de la page d'index.
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 binaire 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 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.
Sur la base de ces puces, voici ce qu'une NULLvaleur prend pour le stockage d'une colonne
longueur variable: une valeur NULL ne prend aucun stockage dans la ligne elle-même
longueur fixe: occupe l'espace réservé
Maintenant, vous devez décider entre utiliser CHAR et VARCHAR en raison de ce que le premier point a fait ressortir
La réservation de l'espace fixe pour les valeurs NULL permet de mettre à jour la colonne de NULL vers une valeur non NULL sans provoquer de fragmentation de la page d'index
Salut Rolando, il y a un autre élément que j'ai oublié de mentionner, la différence d'allocation de mémoire entre une déclaration de type varchar (5) et varchar (100). Ou vraiment la pénalité encourue par la surallocation.
Craig Efrein
@CraigEfrein Vous devez absolument ajouter l'allocation de mémoire à votre réponse. (BTW j'ai déjà voté pour votre réponse)
RolandoMySQLDBA
1
La pénalité pour surallocation se produit lorsque vous avez un complexe SELECTqui doit créer une table temporaire. Si possible, il utilisera MEMORYet convertira VARCHARen CHARpour la table tmp. Prend maintenant VARCHAR(100)un octet fixe de 100 (ou 300), ce qui peut éventuellement ralentir la requête.
Rick James
@RolandoMySQLDBA, le comportement expliqué dans votre réponse est-il applicable aux formats de ligne Mysql 5.7 DYNAMIC et COMPACT?
Cela ne concerne que l'espace utilisé par la colonne varchar et ne prend pas en compte l'espace de stockage total utilisé par la ligne, ses index, ses clés primaires et les autres colonnes.
Comme ypercube le mentionne dans son commentaire, il existe des considérations supplémentaires pour le stockage des lignes dans son ensemble lorsqu'au moins une colonne nullable est présente.
La partie de longueur variable de l'en-tête d'enregistrement contient un vecteur de bits pour indiquer les colonnes NULL. S'il y a entre 9 et 15 colonnes qui peuvent être NULL, le vecteur binaire utilise deux octets.)
...
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
Et oui, l'espace de stockage utilisé change en fonction du type que vous choisissez, est-il fixe ou variable, le classement et d'autres facteurs tels que le moteur.
Une considération supplémentaire avec varchar et c'est la mémoire. Il est important dans MySQL de limiter autant que possible la taille d'une colonne de longueur variable. Même si la colonne est variable et l'espace de stockage utilisé est variable, MySQL allouera de la mémoire en morceaux fixes pour stocker les valeurs. Par exemple, varchar (200) utilisera plus de mémoire que varchar (5). Ce n'est pas un problème d'espace de stockage, mais quelque chose à considérer lors de la définition de vos colonnes.
SELECT
qui doit créer une table temporaire. Si possible, il utiliseraMEMORY
et convertiraVARCHAR
enCHAR
pour la table tmp. Prend maintenantVARCHAR(100)
un octet fixe de 100 (ou 300), ce qui peut éventuellement ralentir la requête.Quelle que soit la longueur que vous définissez pour votre colonne varchar, l'espace de stockage utilisé par une colonne vide sera le même.
Les types CHAR et VARCHAR
Cela ne concerne que l'espace utilisé par la colonne varchar et ne prend pas en compte l'espace de stockage total utilisé par la ligne, ses index, ses clés primaires et les autres colonnes.
Comme ypercube le mentionne dans son commentaire, il existe des considérations supplémentaires pour le stockage des lignes dans son ensemble lorsqu'au moins une colonne nullable est présente.
Structure de ligne physique Innodb
Et oui, l'espace de stockage utilisé change en fonction du type que vous choisissez, est-il fixe ou variable, le classement et d'autres facteurs tels que le moteur.
MySQL fait des recommandations sur l'optimisation du stockage des données ici: Optimiser la taille des données
Mise à jour
Une considération supplémentaire avec varchar et c'est la mémoire. Il est important dans MySQL de limiter autant que possible la taille d'une colonne de longueur variable. Même si la colonne est variable et l'espace de stockage utilisé est variable, MySQL allouera de la mémoire en morceaux fixes pour stocker les valeurs. Par exemple, varchar (200) utilisera plus de mémoire que varchar (5). Ce n'est pas un problème d'espace de stockage, mais quelque chose à considérer lors de la définition de vos colonnes.
la source
CHARACTER SET
latin1 ou ascii. Pour utf8, le stockage requisCHAR(4)
est de 12.