2010-11-19 31 views
25

disons que j'ai une colonne sur ma table définie comme suit:De combien d'espace disque avez-vous besoin pour stocker une valeur NULL en utilisant DB postgresql?

"MyColumn" smallint NULL 

Enregistrement d'une valeur comme 0, 1 ou quelque chose d'autre devrait avoir besoin de 2 octets (1). Mais combien d'espace est nécessaire si je mets "MyColumn" à NULL? A-t-il besoin de 0 octet?

Existe-t-il des octets supplémentaires nécessaires à des fins d'administration ou autres pour chaque colonne/ligne?

(1) http://www.postgresql.org/docs/9.0/interactive/datatype-numeric.html

Répondre

31

colonnes nulles ne sont pas stockées. La ligne a un bitmap au début et un bit par colonne qui indique quels sont null ou non-nul. Le bitmap peut être omis si toutes les colonnes sont non nulles dans une ligne. Ainsi, pour toute ligne donnée avec un ou plusieurs NULL, la taille ajoutée à celle-ci serait celle de l'image bitmap (N bits pour une table N-colonne, arrondie à la valeur supérieure).

discussion plus approfondie de la documentation here

0

Il devrait avoir besoin de 1 octet (0x00) mais il est la structure de la table qui fait la majeure partie de l'espace, l'ajout de cette une valeur pourrait changer quelque chose (comme l'ajout d'une ligne) qui a besoin plus d'espace que la somme des données qu'il contient.

Edit: Laramie semble en savoir plus sur null que moi :)

30

Laramie est juste sur le bitmap et il relie au bon endroit dans le manuel. Pourtant, ce qui est presque, mais pas tout à fait correct:

Donc, pour une ligne donnée avec une ou plusieurs valeurs nulles, la taille ajoutée à elle serait celle du bitmap (N bits pour une table-colonne N, arrondi à la hausse).

On doit prendre en compte l'alignement des données. Le HeapTupleHeader (par ligne) a une longueur de 23 octets, les données de colonne réelles commencent toujours à un multiple de MAXALIGN (généralement 8 octets). Cela laisse un octet de remplissage qui peut être utilisé par le bitmap nul. En effet Le stockage NULL est absolument gratuit pour les tables jusqu'à 8 colonnes.

Ensuite, un autre MAXALIGN (généralement 8) octets est alloué pour les prochaines MAXALIGN * 8 colonnes (généralement 64). Etc. Toujours pour le nombre total de colonnes utilisateur (tout ou rien). Mais seulement s'il y a au moins une valeur NULL réelle dans la ligne.

J'ai effectué des tests approfondis pour vérifier tout cela. Plus de détails:

+2

Ajout de colonnes sans valeur par défaut de grandes tables est généralement une opération rapide. Peut-il être lent lorsque vous franchissez le seuil entre 8 et 9 colonnes (ou 72 et 73 avec 'MAXALIGN = 8')? –

+1

@ PatrickBrinich-Langlois: Oui, c'est une conséquence possible du mécanisme. La taille de la table physique augmente également plus que ce que l'on pourrait attendre dans ces cas. L'effet n'est pas nécessairement linéaire car d'autres facteurs tels que les tuples morts sont impliqués. La table ne se développe pas du tout si les bitmaps NULL existants (par ligne) ont de l'espace pour un autre bit NULL, ce qui est le cas courant. –