La scelta del tipo di dato da associare ai valori di un determinato campo è dettata in particolare da esigenze di progettazione; se un'applicazione è destinata a manipolare stringhe plausibilmente il database di riferimento sarà caratterizzato da tabelle strutturate in campi CHAR
, VARCHAR
o TEXT
, lo stesso può dirsi per il database di supporto ad un programma per l'esecuzione di calcoli dove, in questo caso, verranno probabilmente archiviati valori numerici interi o in virgola mobile.
Dover definire il tipo di dato più adatto per specifiche tipologie di valori, può essere però anche un'esigenza legata allo spazio disponibile su disco per le proprie basi di dati, si pensi per esempio ai piani hosting a pagamento, in cui spesso la necessità di disporre di Mb aggiuntivi per i propri archivi implica un esborso di denaro.
In questa breve trattazione verranno analizzati alcuni casi concreti sulla base dei quali orientare la scelta del tipo di dato più adatto per la definizione dei campi in una tabella.
CHAR e VARCHAR per valori di piccole dimensioni
Un valore stringa può essere salvato per esempio in un campo CHAR o VARCHAR
, l'utilizzo dell'uno o dell'altro tipo di dato però non è completamente intercambiabile, almeno non dal punto di vista dello spazio occupato dai valori memorizzati. Questi due datatype non si comportano infatti esattamente nello stesso modo; si immagini infatti di definire due campi diversi, uno come CHAR(4)
e l'altro come
, entrambi permetteranno quindi di archiviare stringhe della lunghezza massima di quattro caratteri ma, come sarà possibile osservare a breve, memorizzeranno in alcuni casi una quantità diversa di dati.VARCHAR(4)
Si immagini ora di inserire all'interno del campo CHAR(4)
un valore pari ad uno spazio vuoto (" "), esso occuperà uno spazio pari a quattro byte; effettuando la stessa procedura nel campo
, lo spazio occupato sarà invece pari ad appena un byte. Perché avviene questo? Ciò è dovuto al fatto che lo spazio vuoto verrà memorizzato all'interno del campo CHAR sotto forma di quattro spazi vuoti (" "), cioè tanti quanti sono i caratteri definiti per tale campo; il campo VARCHAR(4)
VARCHAR
archivierà invece semplicemente uno spazio vuoto, indipendentemente dalla lunghezza massima predefinita per esso.
Nello stesso modo, archiviando nel campo CHAR il valore ab, a questo verranno aggiunti due spazi vuoti per ottenere quattro caratteri in totale ("ab "), nel campo VARCHAR
invece verranno memorizzati soltanto i due caratteri da cui è composto il valore; si avranno di conseguenza quattro byte occupati nel caso del primo campo e appena tre nel secondo.
Sulla base di quanto esposto finora sembrerebbe che l'utilizzo di VARCHAR
sia da ritenersi in assoluto una scelta migliore, ma alla prova dei fatti le cose non stanno esattamente così, infatti, memorizzando all'interno di un campo CHAR(4)
una stringa composta da quattro caratteri (ad esempio "abcd"), il numero di byte occupati sarà pari a quattro, mentre la stessa operazione su un campo VARCHAR(4)
porterà all'occupazione di cinque byte.
Nel caso in cui si cerchi di memorizzare in entrambi i campi un valore di lunghezza superiore a quella consentita (ad esempio "abcdef"), la stringa verrà troncata all'altezza dell'ultimo carattere consentito, ma occuperà quattro byte nel caso di CHAR
e cinque nel caso di VARCHAR
.
Tra CHAR
e VARCHAR
non vi è quindi un tipo di dato preferibile in senso assoluto, vi sono però dei casi concreti che consentono di orientare la scelta: CHAR
potrebbe per esempio essere utilizzato nel caso in cui si desideri registrare brevi stringhe alfanumeriche, come per esempio dei codici, VARCHAR
potrebbe essere scelto invece nel caso in cui si prevede di dover memorizzare valori vuoti (non nulli) come per esempio degli spazi singoli.
I tipi di dato per la definizione di uno stato
Un altro caso interessante è quello relativo alle definizioni di stato: si pensi per esempio alle applicazioni per la gestione di newsletter con conferma d'iscrizione. In questo caso in una tabella potrebbe essere presente un campo che dovrà assumere valori differenti a seconda del fatto che gli utenti abbiano confermato o meno la propria iscrizione; le definizioni di stato sono utilizzate molto di frequente per svariati altri tipi di applicazioni, un negozio di commercio elettronico potrebbe prevede un campo "pagato" da valorizzare a seconda dell'esito di un ordine, un forum di discussione potrebbe prevedere un campo da valorizzare nel caso in cui un utente sia stato sospeso.., gli esempi potrebbero essere tantissimi ma alla fine si giunge sempre ad una regola generale che vuole le definizioni di stato utilizzate per effettuare dei confronti.
Una definizione di stato può essere per esempio corrispondente ad un valore archiviato in un campo VARCHAR
, una scelta del genere è condivisibile? La risposta dovrebbe essere negativa tenendo conto unicamente del discorso relativo alle prestazioni, ma anche in questo caso non esiste una regola valida in senso assoluto; prestazionalmente VARCHAR
non è da ritenersi il tipo di dato preferibile nel caso in cui, per esempio, si debbano effettuare interrogazioni basate su JOIN
su più tabelle con storage engine MyISAM, inoltre, si tenga conto che essendo un tipo di dato che prevede valori lunghi fino a 255 caratteri non è probabilmente la scelta migliore nel caso in cui sia destinato ad ospitare dati per effettuare confronti.
VARCHAR
può però essere una buona scelta dal punto di vista descrittivo, una definizione di stato può essere per esempio "ATTIVO" o "INATTIVO", si pensi quindi al caso in cui si desideri disporre di valori da stampare o rendere immediatamente visibili sulla propria pagina Web; al contrario, per dimostrare ancora una volta che non esistono scelte valide in senso assoluto, utilizzare delle descrizioni come definizioni di stato potrebbe rappresentare un limite nel caso in cui si desideri realizzare una versione multi-lingua della propria applicazione.
Ad una definizione di stato può essere associato anche un tipo di dato ENUM
che vincola i valori inseribili in un campo a quelli (generalmente pochi) definiti da un utente; ad esempio, il record relativo all'utente attivo di un servizio potrebbe essere contrassegnato con "1" mentre "0" potrebbe essere il valore associato ad un utente inattivo. ENUM
è un tipo di dato di facile lettura che è anche molto indicato per i progetti che necessitano di buoni livelli di prestazioni, il suo utilizzo permette poi di risparmiare spazio su disco (richiede tra uno e due byte per lo storage).
Per contro potrebbe non rivelarsi una scelta ottimale nel caso in cui si abbia la necessità di modificare il numero o la tipologia dei valori da associare alla relativa definizione di stato; in generale, è possibile ritenere che ENUM sia un tipo di dato preferibile nel caso in cui sia possibile associare ad esso un numero di valori finito, infatti MySQL è in grado di reperire velocemente i valori associati a questo datatype, utilizzandolo anche come argomento per limitare il più possibile la produzione di risultati ambigui attraverso le query.
Per certi versi il tipo di dato SET
è simile ad ENUM
, ma dove ENUM
ammette soltanto un unico valore tra quelli precedentemente definiti, SET
permette di memorizzare più valori facenti parte di un intervallo predefinito; il secondo è quindi un tipo di dato utile nel caso in cui si debbano gestire definizioni di stato complesse, ma dovrebbe essere utilizzato al posto di ENUM
solo quando questo non è in grado di soddisfare tutti i criteri previsti per le definizioni di stato richieste da un'applicazione, infatti un valore di tipo SET
può occupare anche 8 volte lo spazio sufficiente ad un dato su campo ENUM
.
Infine, in alternativa a ENUM
e SET
, è possibile associare ad una definizione di stato anche un tipo di dato TINYINT
, esso ha il vantaggio di non richiedere una definizione preventiva di valori memorizzabili, inoltre, accetta un unico valore ma questo non deve appartenere forzatamente ad un determinato intervallo, inoltre, TYNYNT
occupa sempre e comunque un solo byte in notazione numerica.
Conclusioni
In questa breve trattazione è stato affrontato l'argomento relativo alla scelta dei tipi di dato corretti per le diverse esigenze di strutturazione di una tabella e delle informazioni che essa è destinata ad ospitare; per far questo è stata proposta l'analisi di alcuni casi concreti in cui, scegliere il tipo di dato più adatto per un determinato scopo, può aiutare a rendere il DBMS più efficiente e a consumare il minor spazio possibile su disco.