Quelle est la taille de la valeur «Null» dans SQL Server

118

J'ai une grande table avec disons 10 colonnes. 4 d'entre eux restent nuls la plupart du temps. J'ai une requête qui fait que la valeur nulle prend n'importe quelle taille ou aucune taille en octets. J'ai lu quelques articles que certains d'entre eux disent:

http://www.sql-server-citation.com/2009/12/common-mistakes-in-sql-server-part-4.html

Il y a une idée fausse que si nous avons les valeurs NULL dans une table, cela n'occupe pas d'espace de stockage. Le fait est qu'une valeur NULL occupe de l'espace - 2 octets

SQL: utilisation des valeurs NULL par rapport aux valeurs par défaut

Une NULLvaleur dans les bases de données est une valeur système qui occupe un octet de stockage et indique qu'une valeur n'est pas présente par opposition à un espace ou zéro ou toute autre valeur par défaut.

Pouvez-vous s'il vous plaît me guider concernant la taille prise par valeur nulle.

Rocky Singh
la source

Réponses:

146

Si le champ est de largeur fixe, le stockage de NULL prend le même espace que toute autre valeur - la largeur du champ.

Si le champ est de largeur variable, la valeur NULL ne prend pas d'espace.

En plus de l'espace requis pour stocker une valeur nulle, il y a également une surcharge pour avoir une colonne Nullable. Pour chaque ligne, un bit est utilisé par colonne Nullable pour indiquer si la valeur de cette colonne est NULL ou non. Cela est vrai que la colonne soit de longueur fixe ou variable.


La raison des écarts que vous avez constatés dans les informations provenant d'autres sources:

  • Le début du premier article est un peu trompeur. L'article ne parle pas du coût de stockage d'une valeur NULL, mais du coût d'avoir la capacité de stocker un NULL (c'est-à-dire le coût de rendre une colonne nullable). Il est vrai que cela coûte quelque chose en espace de stockage pour rendre une colonne nullable, mais une fois que vous avez fait cela, il faut moins d'espace pour stocker un NULL qu'il n'en faut pour stocker une valeur (pour les colonnes de largeur variable).

  • Le deuxième lien semble être une question sur Microsoft Access. Je ne connais pas les détails de la façon dont Access stocke les NULL, mais je ne serais pas surpris qu'il soit différent de SQL Server.

Mark Byers
la source
1
@Mark "Il est vrai que cela coûte quelque chose en espace de stockage pour rendre une colonne nullable, mais une fois que vous avez fait cela, il faut moins d'espace pour stocker un NULL qu'il n'en faut pour stocker une valeur (pour les colonnes de largeur variable)" Vous voulez dire pour dire qu'il faut 1 bit comme taille prise en mémoire pour les types de données variables.
Rocky Singh
13
La plus petite unité de mémoire adressable dans la plupart des systèmes informatiques est une byte(généralement 8 bits). Donc en réalité, un bitprend un byte. Excellente réponse Mark: +1.
JohnB
20
Cependant, un deuxième bit, et un troisième bit, et tout le chemin jusqu'à un huitième bit rentrent dans le même octet.
Matti Virkkunen
1
@Mark - Oui, cela semble beaucoup plus clair. Toutes mes excuses pour le commentaire qui disparaît. J'avais l'intention de le réviser mais ma connexion Internet est tombée entre la suppression et la soumission! Cela dépend aussi un peu (De la section des commentaires ici) "Pour l'enregistrement d'index en tas et en cluster, il y a toujours un bitmap NULL. Pour les index non clusterisés, il n'y en aura pas si toutes les colonnes de l'index ne sont PAS NULL."
Martin Smith
2
@Martin Smith: Je ne le savais pas. Cela complique les choses car si je comprends bien, cela signifie que rendre une colonne nullable n'augmente pas l'espace de stockage requis (car le bitmap nul est toujours présent) à moins que cette colonne ne soit également dans un index et les autres colonnes de l'index ne peuvent pas être annulés. Dans ce cas, l'index doit maintenant inclure un bitmap nul.
Mark Byers
30

Les revendications de liaison suivant que si la colonne est de longueur variable, à savoir varcharpuis NULLprend 0 octets (plus 1 octet est utilisé pour signaler si la valeur est NULLou non):

Le lien ci-dessus, ainsi que le lien ci-dessous, affirment que pour les colonnes de longueur fixe, c'est-à-dire char(10)ou int, une valeur de NULLoccupe la longueur de la colonne (plus 1 octet pour indiquer si c'est NULLou non):

Exemples:

  1. Si vous définissez un char(10)sur NULL, il occupe 10 octets (remis à zéro)
  2. An intprend 4 octets (également remis à zéro).
  3. Un varchar(1 million)ensemble à NULLprend 0 octets (+ 2 octets)

Remarque: sur une légère tangente, la taille de stockage de varcharest la longueur des données saisies + 2 octets.

JohnB
la source
Un varchar stockant un NULL ne prendrait-il pas 0 + 2 + 1 (surcharge NULL)?
Akash
Il doit être + 1 bit pour marquer NULL. @Akash: 2 octets ne devraient pas être nécessaires car le bitmap marque déjà la valeur comme NULL (aucune information ne serait ajoutée).
Simo Kivistö
5

À partir de ce lien :

Chaque ligne a un bitmap nul pour les colonnes qui autorisent les valeurs nulles. Si la ligne de cette colonne est nulle, un bit du bitmap vaut 1, sinon 0.

Pour les types de données de taille variable, la taille réelle est de 0 octet.

Pour un type de données de taille fixe, la taille réelle est la taille par défaut du type de données en octets définie sur la valeur par défaut (0 pour les nombres, «» pour les caractères).

Kevin LaBranche
la source
Vous voulez dire que pour les types de données comme nvarchar (max) varchar (max) Null prendra 0 octet et pour int, chars, etc., il prendra la taille par défaut aux valeurs par défaut qu'ils ont?
Rocky Singh
4

Le stockage d'une valeur NULL ne prend pas d'espace.

"Le fait est qu'une valeur NULL occupe de l'espace - 2 octets."

C'est une idée fausse - c'est 2 octets par ligne , et je suis à peu près sûr que toutes les lignes utilisent ces 2 octets, qu'il y ait ou non des colonnes Nullable.

Une valeur NULL dans les bases de données est une valeur système qui occupe un octet de stockage

Il s'agit de bases de données en général, pas spécifiquement de SQL Server. SQL Server n'utilise pas 1 octet pour stocker les valeurs NULL.

Gabe
la source