Quante dimensioni assume il valore "Null" in SQL Server


118

Ho una grande tabella con diciamo 10 colonne. 4 di loro rimangono nulli il più delle volte. Ho una query che fa il valore nullo prende qualsiasi dimensione o nessuna dimensione in byte. Ho letto alcuni articoli che alcuni di loro dicono:

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

C'è un malinteso che se abbiamo i valori NULL in una tabella non occupi spazio di archiviazione. Il fatto è che un valore NULL occupa spazio - 2 byte

SQL: utilizzo di valori NULL rispetto a valori predefiniti

Un NULLvalore nei database è un valore di sistema che occupa un byte di memoria e indica che un valore non è presente al contrario di uno spazio o di uno zero o di qualsiasi altro valore predefinito.

Puoi guidarmi per quanto riguarda la dimensione presa dal valore nullo.

Risposte:


146

Se il campo è a larghezza fissa, la memorizzazione di NULL occupa lo stesso spazio di qualsiasi altro valore: la larghezza del campo.

Se il campo è di larghezza variabile, il valore NULL non occupa spazio.

Oltre allo spazio richiesto per memorizzare un valore null, esiste anche un sovraccarico per avere una colonna nullable. Per ogni riga viene utilizzato un bit per colonna nullable per contrassegnare se il valore per quella colonna è nullo o meno. Questo è vero se la colonna è di lunghezza fissa o variabile.


Il motivo delle discrepanze che hai osservato nelle informazioni provenienti da altre fonti:

  • L'inizio del primo articolo è un po 'fuorviante. L'articolo non parla del costo della memorizzazione di un valore NULL, ma del costo di avere la possibilità di memorizzare un NULL (ovvero il costo per rendere annullabile una colonna). È vero che costa qualcosa nello spazio di archiviazione per rendere annullabile una colonna, ma una volta fatto ciò, ci vuole meno spazio per memorizzare un NULL rispetto a quello necessario per memorizzare un valore (per colonne a larghezza variabile).

  • Il secondo collegamento sembra essere una domanda su Microsoft Access. Non conosco i dettagli di come Access memorizza i NULL, ma non sarei sorpreso se fosse diverso da SQL Server.


1
@Mark "È vero che costa qualcosa nello spazio di archiviazione per rendere annullabile una colonna, ma una volta fatto ciò, ci vuole meno spazio per memorizzare un NULL di quello che serve per memorizzare un valore (per colonne a larghezza variabile)" Con questo intendi per dire che richiede 1 bit come dimensione presa in memoria per i tipi di dati variabili.
Rocky Singh,

13
La più piccola unità di memoria indirizzabile nella maggior parte dei sistemi di computer è una byte(in genere 8 bit). Quindi, in realtà, un bitrichiede un file byte. Ottima risposta Marco: +1.
JohnB

20
Tuttavia, un secondo bit, un terzo bit e fino a un ottavo bit rientrano nello stesso byte.
Matti Virkkunen

1
@Mark - Sì, sembra molto più chiaro. Mi scuso per il commento che scompare. Volevo rivederlo, ma la mia connessione Internet è caduta tra l'eliminazione e l'invio! Dipende anche un po '(dalla sezione commenti qui) "Per il record di indice heap e cluster, c'è sempre una bitmap NULL. Per gli indici non cluster, non ci sarà se tutte le colonne nell'indice NON sono NULL."
Martin Smith,

2
@ Martin Smith: non lo sapevo. Ciò rende le cose più complicate perché se lo capisco correttamente significa che rendere annullabile una colonna non aumenta lo spazio di archiviazione richiesto (perché la bitmap nulla è sempre presente) a meno che quella colonna non sia anche in un indice e le altre colonne nell'indice non sono annullabili. In questo caso l'indice deve ora includere una bitmap nulla.
Mark Byers

30

Il seguente collegamento rivendicazioni che se la colonna è di lunghezza variabile, cioè varcharquindi NULLprende 0 byte (più 1 byte è utilizzato per segnalare se il valore è NULLo no):

Il collegamento sopra, così come il collegamento sotto, affermano che per le colonne di lunghezza fissa, ovvero char(10)o int, un valore di NULLoccupa la lunghezza della colonna (più 1 byte per contrassegnare se lo è NULLo meno):

Esempi:

  1. Se imposti un char(10)a NULL, occupa 10 byte (azzerato)
  2. Un intrichiede 4 byte (anche azzerato).
  3. Un varchar(1 million)set a NULLrichiede 0 byte (+ 2 byte)

Nota: su una leggera tangente, la dimensione di archiviazione di varcharè la lunghezza dei dati inseriti + 2 byte.


Un varchar che memorizza un NULL non richiederebbe 0 + 2 + 1 (overhead NULL) byte?
Akash

Dovrebbe essere + 1 bit per contrassegnare NULL. @Akash: 2 byte non dovrebbero essere necessari poiché la bitmap contrassegna già il valore come NULL (non verrebbe aggiunta alcuna informazione).
Simo Kivistö

5

Da questo link :

Ogni riga ha una bitmap nulla per le colonne che consentono valori null. Se la riga in quella colonna è nulla, un bit nella bitmap è 1 altrimenti è 0.

Per i tipi di dati a dimensione variabile, la dimensione effettiva è 0 byte.

Per il tipo di dati a dimensione fissa, la dimensione effettiva è la dimensione del tipo di dati predefinita in byte impostata sul valore predefinito (0 per i numeri, "" per i caratteri).


Vuoi dire che per i tipi di dati come nvarchar (max) varchar (max) Null richiederà 0 byte e per int, chars ecc. Ci vorrà la dimensione predefinita ai valori predefiniti che hanno?
Rocky Singh,

4

La memorizzazione di un valore NULL non richiede spazio.

"Il fatto è che un valore NULL occupa spazio - 2 byte."

Questo è un malinteso: sono 2 byte per riga e sono abbastanza sicuro che tutte le righe utilizzino quei 2 byte indipendentemente dal fatto che siano presenti colonne nullable.

Un valore NULL nei database è un valore di sistema che occupa un byte di memoria

Si tratta di database in generale, non specificamente di SQL Server. SQL Server non utilizza 1 byte per memorizzare i valori NULL.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.