Si capisce bene che, se non è necessario usare un INT, è preferibile passare a uno SMALLINT o, ancora meglio, ad un TINYINT.
Questo non solo perché vi è uno spreco di spazio, ma anche per migliorare l’utilizzo generale della memoria e soprattutto ottimizzare le performance durante una richiesta al database quando i dati saranno molti.
Per questi motivi, è fondamentale conoscere ogni tipo di dato che possiamo utilizzare prima di intraprendere uno sviluppo applicativo, in modo tale da puntare ad una ottimizzazione crescente.
Analizziamo quindi i vari tipi dati a nostra disposizione, suddividendoli in macrocategorie a seconda di ciò che vogliamo memorizzare.
Dati Numerici Esatti
Questa categoria racchiude i data types che si possono utilizzare per contenere tutti i tipi di dati numerici che non richiedono trasformazioni per essere letti. Sono quindi dati Esatti.
Data type | Descrizione | Dimensioni |
BIGINT | Utilizzato per memorizzare numeri interi (integer), ha un intervallo di 2^63 per le cifre positive e -2^63 per quelle negative. C’è da notare che le costanti integer maggiori di 2.147.483.647 vengono convertite nel tipo di dati DECIMAL e non nel tipo di dati BIGINT, come invece ci si aspetterebbe. | 8 bytes |
INT | Utilizzato per memorizzare numeri interi (integer), ha un intervallo di 2^31 per le cifre positive e -2^31 per quelle negative | 4 bytes |
SMALLINT | Utilizzato per memorizzare numeri interi (integer), ha un intervallo di -2^15 (-32.768) a 2^15-1 (32.767). | 2 bytes |
TINYINT | Utilizzato per memorizzare numeri interi (integer), ha un intervallo di [0..255] e non contiene valori negativi. | 1 byte |
NUMERIC | Utilizzato per numeri con precisione decimale fissa. Quando si va a definire il data type si deve specificare la precisione e la scala. | Max 17 bytes |
DECIMAL | Funzionalmente identico a NUMERIC, quindi il funzionamento è lo stesso. | Max 17 bytes |
BIT | Un flag che può essere settato a 0, 1. Si possono inserire anche le stringhe ‘True’ o ‘False’, che verranno automaticamente convertite rispettivamente in 1 e 0. Il motore di SQL Server ottimizza l’archiviazione di colonne di questo tipo: se una tabella contiene al massimo 8 colonne di tipo bit, le colonne vengono archiviate come singolo byte. | 1 bit |
MONEY | Usato per rappresentare valori monetari o valutari, è caratterizzato da una precisione pari a dieci millesimi delle unità monetarie rappresentate. Nella conversione dal tipo INTEGER a MONEY, le unità vengono interpretate come unità di valuta. | 8 bytes |
SMALLMONEY | Usato per rappresentare valori monetari o valutari, è caratterizzato da una precisione pari a dieci millesimi delle unità monetarie rappresentate. | 4 bytes |
DECIMAL, NUMERIC: quando si va a definire il data type si deve specificare la precisione e la scala. La precisione è il numero totale di cifre che possono essere ricordate. La scala invece è il numero di cifre dopo il punto decimale. Un esempio pratico: 123.456 ha precisione 6 e scala 3. DECIMAL (6,3) o NUMERIC (6,3). Notare bene che SQL Server considera ogni possibile combinazione di precisione e scala come un data type differente. Lo spazio di archiviazione dipende dalla precisione utilizzata; il massimo si raggiunge a precisione 17-38, occupando 17 bytes.
Dati Numerici Approssimati
Categoria che racchiude i tipi di dati utilizzati per memorizzare numeri in virgola mobile. Questi dati sono approssimati. Pertanto, non tutti i valori nell'intervallo del tipo di dati possono essere rappresentati in modo esatto.
Data type | Descrizione | Dimensioni |
FLOAT, REAL | FLOAT e REAL sono due tipi dati approssimati . Questo significa che non tutti i valori nell'intervallo del tipo di dati possono essere rappresentati in modo esatto. Alla dichiarazione di un nuovo tipo FLOAT si può specificare il numero di bit (n) usato per archiviare la mantissa del numero in notazione scientifica e pertanto determinare la sua precisione e le sue dimensioni di archiviazione. Se n è specificato, deve essere un valore tra 1 e 53. Se non è specificato il valore predefinito è 53. Float:(n) Da - 1,79E+308 a -2,23E-308, 0 e da 2,23E-308 a 1,79E+308 | Variabili |
Notare bene che la conversione dei valori FLOAT che usano come notazione scientifica DECIMAL o NUMERIC è limitata ai soli valori con precisione a 17 cifre. Qualsiasi valore minore di 5E-18 viene arrotondato per difetto a 0 in quanto non rappresentabile.
Date e Tempo
Data types che permettono la memorizzazione di unità di tempo.
Data type | Descrizione | Dimensioni |
DATE | Definisce una data con il formato predefinito YYYY-MM-DD, ha accuratezza di un giorno e supporta molti formati, eccetto ymd. | 3 bytes |
DATETIMEOFFSET | Definisce una data in combinazione con un’ora del giorno con considerazione del fuso orario, formato 24 ore. Il formato è YYYY-MM-DD hh:mm:ss[.nnnnnnn] [{+|-}hh:mm]. L’ora legale non è considerata. | 10 bytes |
DATETIME2 | Definisce una data costituita dalla combinazione di un'ora del giorno espressa nel formato 24 ore. DATETIME2 può essere considerato un'estensione del tipo DATETIME con un più ampio intervallo di date, una maggiore precisione frazionaria predefinita e la possibilità per l’utente di specificare una precisione facoltativa. | Max 8 bytes |
DATETIME | Definisce una data costituita dalla combinazione di un'ora del giorno espressa nel formato 24 ore. | Max 8 bytes |
SMALLDATETIME | Obsoleto. Identico a DATETIME, si differenzia solo per il fatto che non possiede il frazionamento dei secondi. | 4 bytes |
TIME | Definisce l'ora di un giorno. Il fuso orario non viene preso in considerazione e il formato è basato sulle 24 ore. Si può specificare la scala dei secondi frazionaria. | 5 bytes |
Stringhe di Caratteri
Data types che permettono la memorizzazione di stringhe o caratteri.
La lunghezza massima di questi tipi dipende dal CHARSET. Se si tratta di un charset single-byte (come Latin), allora n caratteri occuperanno n bytes (massimo valore di n è 8000). Se invece il charset è double-byte allora la lunghezza massima è dimezzata (4000).
I data types che utilizzano unicode sono contrassegnati con una “N” iniziale.
Data type | Descrizione | Dimensioni |
CHAR | Utilizzato per i tipi di carattere a lunghezza fissa. Alla creazione occorre specificare la lunghezza della stringa caratteri(n). | N bytes (N = numero caratteri) |
VARCHAR | Utilizzato per i tipi di carattere a lunghezza variabile. Alla creazione occorre specificare la lunghezza della stringa caratteri(n). VARCHAR a pari valore di n occuperà sempre 2 bytes in più delle sua corrispondente versione statica. | N +2 bytes (N = numero caratteri) |
NCHAR | Utilizzato per i tipi di carattere a lunghezza fissa. Alla creazione occorre specificare la lunghezza della stringa caratteri(n) UNICODE. | N bytes (N = numero caratteri) |
NVARCHAR | Utilizzato per i tipi di carattere a lunghezza variabile. Alla creazione occorre specificare la lunghezza della stringa caratteri(n). NVARCHAR a pari valore di n occuperà sempre 2 bytes in più delle sua corrispondente versione statica. | N + 2 bytes (N = numero caratteri) |
TEXT | Tipi di dati a lunghezza fissa e variabile per l'archiviazione di dati di tipo binario e caratteri non Unicode di dimensioni elevate. Notare bene: questi tipi di dati verranno rimossi e sono obsoleti, quindi se ne sconsiglia l’utilizzo. Essendo non unicode ogni carattere occuperà 1 byte. | Max 2 GB |
NTEXT | Tipi di dati a lunghezza fissa e variabile per l'archiviazione di dati di tipo binario e carattere Unicode di dimensioni elevate. Notare bene: questi tipi di dati verranno rimossi e sono obsoleti, quindi se ne sconsiglia l’utilizzo. Essendo unicode ogni carattere occuperà 2 bytes. | Max 2 GB |
IMAGE | Tipi di dati a lunghezza fissa e variabile per l'archiviazione di dati di tipo binario e carattere sia Unicode che non Unicode di dimensioni elevate. Notare bene: questi tipi di dati verranno rimossi e sono obsoleti, quindi se ne sconsiglia l’utilizzo. | 2 GB |
CHAR, VARCHAR, NCHAR, NVARCHAR: notare bene che alla creazione del data type si può inserire MAX al posto di un numero per indicare il massimo spazio disponibile di memorizzazione (2 GB).
Stringhe Binarie
Data type | Descrizione | Dimensioni |
BINARY | Tipi di dati binary a lunghezza fissa. | Max 8.000 bytes |
VARBINARY | Tipi di dati binary a lunghezza variabile. VARBINARY occupa +2 bytes rispetto alla sua controparte statica. | Max 2^31-1 byte |
TIMESTAMP | Valore binario unico generato dal sistema ed utilizzato per la versioning di una row. | 8 bytes |
Tipi di dato avanzati
Data type | Descrizione | Dimensioni |
ROWVERSION | Tipo di dati che espone numeri binari univoci generati automaticamente all'interno di un database. ROWVERSION viene in genere usato come meccanismo per contrassegnare le righe di tabella con il numero della versione. | 8 bytes |
UNIQUEIDENTIFIER | Semplice GUID (Globally Unique Identifier) alfanumerico. | 16 bytes |
HIERARCHYID | Può essere usato per memorizzare tipi di dato gerarchico in forma esadecimale. Il data type è provvisto di molti metodi che permettono agli sviluppatori di navigare facilmente la gerarchia creatasi. | 892 bytes |
XML | Data type utilizzato per memorizzare dati in formato XML nativo. | Max 2 GB |
GEOGRAPHY | Serve per memorizzare coordinate geografiche con latitudine e longitudine. Queste coordinate vengono scritte con valori binari. | Max 2^31 – 1 bytes |
GEOMETRY | Analogo a GEOGRAPHY, ma utilizza una visione del mondo in due dimensioni e non a tre. Viene utilizzato per posizioni su forme geometriche. | Max 2^31 – 1 bytes |
TABLE | Usato per ricordare un result set di una query per utilizzi futuri. | Max 2 GB |
SQL_VARIANT | Può contenere dati di tipi diversi. Può essere utilizzato quando non si conosce a priori la tipologia dei dati che verranno scritti su una data colonna, ma se ne sconsiglia vivamente l’uso anche per problemi di ottimizzazione. | Variabili a seconda dei tipi di dato inseriti. |
Per quanto riguarda i NULL, essi sono trattati in dettaglio nel nostro approfondimento dedicato.
di Matteo Lucato, pubblicato il 12 aprile 2019