Come vengono archiviati i NULL in un database?
Domanda
Sono curioso di sapere come vengono archiviati i NULL in un database?
Dipende sicuramente dal server di database, ma vorrei avere un'idea generale a riguardo.
Primo tentativo:
Supponiamo che il server inserisca un valore indefinito (potrebbe essere qualsiasi cosa) nel campo per un valore NULL.
Potresti essere molto fortunato e recuperare il valore NULL con
...WHERE field = 'the undefined value (remember, could be anything...)'
Secondo tentativo:
Il server ha un flag o qualche meta-dato da qualche parte per indicare che questo campo è NULL?
Quindi il server deve leggere questi metadati per verificare il campo.
Se i metadati indicano un valore NULL e se la query non ha "campo IS NULL", quindi il record viene ignorato.
Sembra troppo facile ...
Soluzione
Su PostgreSQL, utilizza una bitmap opzionale con un bit per colonna (0 è null, 1 non è null). Se la bitmap non è presente, tutte le colonne non sono nulle.
Questo è completamente separato dalla memorizzazione dei dati stessi, ma si trova sulla stessa pagina della riga (quindi sia la riga che la bitmap vengono lette insieme).
References:
Altri suggerimenti
MySql utilizza il secondo metodo. Memorizza un array di bit (uno per colonna) con i dati per ogni riga per indicare quali colonne sono nulle e quindi lascia vuoti i dati per quel campo. Sono abbastanza sicuro che questo sia vero anche per tutti gli altri database.
Il problema con il primo metodo è: sei sicuro che qualsiasi valore selezionato per i tuoi dati non venga visualizzato come dato valido? Per alcuni valori (come date o numeri in virgola mobile) questo è vero. Per altri (come numeri interi) questo è falso.
Il server in genere utilizza meta informazioni anziché un valore magico. Quindi c'è un po 'fuori posto che specifica se il campo è null.
-Adam
IBM Informix Dynamic Server utilizza valori speciali per indicare valori null. Ad esempio, l'intervallo di valori valido per SMALLINT (16 bit, con segno) è -32767 .. + 32767. L'altro valore, -32768, è riservato per indicare NULL. Allo stesso modo per INTEGER (4 byte, con segno) e BIGINT (8 byte, con segno). Per altri tipi, utilizza altre rappresentazioni speciali (ad esempio, tutti i bit 1 per SQL FLOAT e SMALLFLOAT, ovvero C double e float, rispettivamente). Ciò significa che non è necessario utilizzare spazio aggiuntivo.
IBM DB2 per Linux, Unix, Windows utilizza byte extra per memorizzare gli indicatori null; AFAIK, utilizza un byte separato per ogni campo nullable, ma potrei sbagliarmi su quel dettaglio.
Quindi, come è stato sottolineato, i meccanismi differiscono a seconda del DBMS.
Il problema con valori speciali per indicare NULL è che prima o poi verrà inserito quel valore speciale. Ad esempio, verrà inserito in una tabella che specifica gli speciali indicatori NULL per diversi server di database
| DBServer | SpecialValue |
+--------------+--------------+
| 'Oracle' | 'Glyph' |
| 'SQL Server' | 'Redmond' |
; -)