Per sapere perché questo è brutto, devi sapere come viene salvato un database sul disco rigido (in particolare le righe). Il contenuto fisico di una riga salvata sul disco è suddiviso nelle sue controparti statiche e dinamiche. Campi come int, byte, char (n) che hanno una lunghezza fissa sono elencati per primi. Quello che segue è un numero di lunghezza fissa che si riferisce al numero di campi di lunghezza variabile da seguire. Tutti i campi variabili (indipendentemente dall'ordine delle colonne presentate all'utente, il programmatore) vengono aggiunti alla fine, ciascuno con un numero di lunghezza fissa che determina la quantità di spazio occupata dal campo della lunghezza variabile.
Per darti un esempio concreto. Supponiamo che la mia tabella sia la seguente:
char(3) A
varchar(4) B
int C
Ora supponiamo che io faccia INSERT INTO mytable (A, B, C) VALUES ('AAA', 'B', 256)
.
Sul database, quella riga verrebbe probabilmente archiviata come segue:
IlcampoAvienesalvatocomecisiaspetterebbe.Seavessiinserito"A", avrebbe fornito un carattere speciale per contrassegnare la fine prematura della stringa dopo il primo carattere, ma occuperebbe lo stesso spazio.
Il campo C viene salvato come equivalente binario di 256. Perché C e non B? C è il prossimo campo statico con lunghezza fissa e, come tale, viene raggruppato insieme a tutti gli altri dati statici nella riga del database.
Il campo D è meta informazioni per il database che indica che nella seguente sezione di campi di lunghezza variabile, ci sarà precisamente 1 campo.
Il campo E è ancora una meta informazione per il database che indica che per questo particolare campo, ha una lunghezza massima di 1 carattere. Questa informazione è essenziale perché altrimenti il database non saprebbe dove finisce il campo B e inizia un altro campo di lunghezza variabile.
Tutto questo per dimostrare come i database gestiscono il salvataggio di campi a lunghezza variabile. BLOB è un campo a lunghezza variabile per questo effetto. La struttura del database consente a una riga di contenere sia valori piccoli che grandi nel BLOB, tuttavia, ci sono altri fattori in gioco qui. I database normalmente gestiscono blocchi di informazioni poiché ai dischi non interessa il contenuto, ma piuttosto se si inserisce in un singolo blocco.
Il database proverà ad adattare tutte le righe in un singolo blocco senza dover separare una riga in due parti, perché altrimenti l'effetto è lo stesso di avere un file frammentato sul disco rigido. Una volta caricato un chunk, se la riga supera quel particolare chunk, il disco rigido deve quindi cercare il resto in un altro blocco. Peggio ancora, non è possibile che un database sappia che una riga occupa più di un chunk senza leggerne completamente il contenuto poiché è di lunghezza variabile, quindi non è possibile ottimizzare recuperando entrambi i blocchi contemporaneamente.
Seguendo questa linea di logica, se si potesse creare un BLOB di lunghezza statica, non si avrebbe questo problema di ottimizzazione, poiché il database potrebbe semplicemente garantire che la dimensione del blocco sia maggiore della dimensione minima della riga, garantendo così che la maggior parte delle righe non dovrà essere diviso tra più blocchi. Ovviamente, i database non lo fanno perché significherebbe dedicare spazio prezioso quando probabilmente non ne avrai bisogno.
I BLOB vanno bene quando si tratta di importi relativamente piccoli, ma per file di grandi dimensioni come video e simili, una soluzione comune è semplicemente quella di salvare il percorso del file nel database e lasciare che il software si occupi di caricare il file che è quasi sempre più efficiente.
Spero che lo spieghi. :)