2012-11-03 12 views
8

sto cercando di capire il modo migliore per gestire le colonne che sono in gran parte vuoto in termini di spazio su disco e indice di prestazioni. C'è una differenza tra mettere in tutti i posti vuoti NULL vs '' (per varchar/testo) contro 0 (per int).implicazioni spazio su disco modificando valore colonna MySQL NULL invece di 0 o ''

Grazie.

+0

[Possibilmente A Duplicato] (http://stackoverflow.com/questions/5015990/mysql-integer-0-vs-null) – gks

+0

@Thanga grazie per il ref è simile, ma mi interessa sapere di implicazioni sullo spazio su disco e sull'indice. Chiarirò – Noam

+2

oltre alla mia risposta qui sotto, il mio consiglio è che questo suona come un caso di "ottimizzazione prematura". Questo non vale davvero il tuo tempo per preoccuparti. Basta progettare uno schema che abbia senso. Ti garantisco che questo non sarà il tuo collo di bottiglia più grande. –

risposta

10

No, l'utilizzo di NULL non occupa meno spazio di un campo vuoto VARCHAR o INT. In effetti potrebbe occupare lo spazio più. Ecco perché:

A VARCHAR viene memorizzato come dimensione + valore. Il numero di byte utilizzati per la dimensione dipende dalla memoria massima di VARCHAR. VARCHAR(255) richiede un byte, VARCHAR(65536) richiede due byte e così via.

Quindi la colonna VARCHAR(255) occupa un byte anche se si memorizza una stringa vuota. La seguente tabella richiederebbe un minimo di un byte per riga (più qualche altro overhead possibile a seconda del motore di archiviazione).

CREATE TABLE sample (
    a VARCHAR(255) NOT NULL 
); 

Per salvare NULL valori, MySQL utilizza una maschera di bit per ogni riga. Fino a 8 colonne nullable possono essere memorizzate per byte. Quindi, se hai una tabella come questa:

CREATE TABLE sample (
    a VARCHAR(255) NULL 
); 

Prendeva almeno due byte per riga. Memorizzare NULL imposta solo il bit, è già prenotato sia che lo si usi o meno. Il byte per la dimensione di VARCHAR viene comunque utilizzato per ogni riga anche se la colonna è impostata su NULL.

+0

Buona risposta, questo vale per MySQL e ms SQL server? – SteB

+0

So che questo è vero per MySQL, ma non pretendo di conoscere altri - questa risposta sembra indicare che è simile: http://stackoverflow.com/questions/3731172/how-much-size-null-value-takes -in-sql-server –

+0

@GavinTowey buona risposta, ma presumo che la maschera di bit che hai menzionato aiuti MySQL a gestire gli indici in modo più efficiente? In tal caso, non risulterebbe in uno spazio minore nei casi in cui esiste un indice su quella colonna? – Noam

0

La risposta semplice è forse (anche se non dovrebbe essere importante), i valori nulli possono occupare meno spazio su disco, anche se il risparmio di spazio sarà probabilmente minimo (anche se piccoli risparmi si sommeranno).
A meno che lo spazio su disco non sia strettamente vincolato, non mi preoccuperei (lo spazio su disco è molto più economico del tempo del programmatore).
Inoltre, null e 0 (o ''), sono semanticamente differenti, quindi non dovrebbero essere usati in modo intercambiabile, certamente non per un guadagno teorico (o molto piccolo) delle prestazioni.

Vedere this question per ulteriori dettagli.

Non credo che l'indicizzazione sarà fortemente influenzata, potrebbe esserci un lieve miglioramento della velocità.
Vedere this question per ulteriori dettagli.

This question si occupa specificamente di MySQL e prestazioni nulle.

+1

Perché un valore NULL occupa meno spazio di un campo VARCHAR vuoto? –

+0

@GavinTowey - scusate, stavo pensando a varchar con dati, correggerò la mia risposta, probabilmente al massimo prenderanno 1 carattere in meno. – SteB

0

Dipende.

Se si dispone di una tabella a larghezza fissa (senza VARCHAR, VARBINARY, BLOB o TEXT), sarà probabilmente fare alcuna differenza.

In una tabella a larghezza variabile, uno NULL probabilmente occuperà lo spazio di un numero vuoto VARCHAR.

Se si hanno quasi tutti i valori NULL e solo pochissimi contengono dati, è possibile creare una tabella separata a cui ci si unisce.

Quindi supponiamo di avere una lista di persone in cui solo alcune di loro hanno la data di nascita.

Così, invece di

CREATE TABLE people (id INT UNSIGNED NOT NULL PRIMARY KEY AUTOINCREMENT, name VARCHAR(60) NOT NULL, birthday DATE) 

si potrebbe fare

CREATE TABLE people (id INT UNSIGNED NOT NULL PRIMARY KEY AUTOINCREMENT, name VARCHAR(60) NOT NULL) 
CREATE TABLE birthdates (id INT UNSIGNED, birthday DATE NOT NULL) 

e interrogare i dati con un LEFT JOIN.

Se ci sono applicazioni che devono accedere alla tabella nel vecchio formato, è possibile definire una vista.

Problemi correlati