Back to Basics: i tipi di dato in SQL Server

Datamaze
18.06.20 02:49 PM Comment(s)
Usare i tipi dato corretti quando si lavora con SQL Server è estremamente importante. Vediamo l’importanza di questa affermazione, prendendo ad esempio un problema comune, ovvero memorizzare numeri interi. La scelta più comune è di utilizzare il data type INT anche se, molto spesso, dobbiamo memorizzare solo dei numeri relativamente piccoli. Un INT occupa in memoria 4 bytes mentre uno SMALLINT ne occupa la metà. Un TINYINT occupa solamente 1 byte.


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
BIGINTUtilizzato 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
 INTUtilizzato per memorizzare numeri interi (integer), ha un intervallo di 2^31 per le cifre positive e -2^31 per quelle negative 4 bytes
 SMALLINTUtilizzato per memorizzare numeri interi (integer), ha un intervallo di -2^15 (-32.768) a 2^15-1 (32.767). 2 bytes
 TINYINTUtilizzato per memorizzare numeri interi (integer), ha un intervallo di [0..255] e non contiene valori negativi. 1 byte
 NUMERICUtilizzato 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
SMALLMONEYUsato 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 typeDescrizioneDimensioni
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.
REAL non è altro che un FLOAT(24) in quanto a livello funzionale sono identici.

Float:(n) Da - 1,79E+308 a -2,23E-308, 0 e da 2,23E-308 a 1,79E+308
Real: Da - 3,40E + 38 a -1,18E - 38, 0 e da 1,18E - 38 a 3,40E + 38

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 typeDescrizioneDimensioni
DATEDefinisce 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
DATETIME2Definisce 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
DATETIMEDefinisce una data costituita dalla combinazione di un'ora del giorno espressa nel formato 24 oreMax 8 bytes
SMALLDATETIMEObsoleto. Identico a DATETIME, si differenzia solo per il fatto che non possiede il frazionamento dei secondi.4 bytes
TIMEDefinisce 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 typeDescrizioneDimensioni
CHARUtilizzato 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)
NCHARUtilizzato per i tipi di carattere a lunghezza fissa. Alla creazione occorre specificare la lunghezza della stringa caratteri(n) UNICODE.

N bytes (N = numero caratteri)

NVARCHARUtilizzato 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
NTEXTTipi 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
IMAGETipi 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 typeDescrizioneDimensioni
BINARYTipi di dati binary a lunghezza fissa.Max 8.000 bytes
VARBINARYTipi di dati binary a lunghezza variabile. VARBINARY occupa +2 bytes rispetto alla sua controparte statica.Max 2^31-1 byte
TIMESTAMPValore binario unico generato dal sistema ed utilizzato per la versioning di una row.8 bytes

Tipi di dato avanzati


Data typeDescrizioneDimensioni
ROWVERSIONTipo 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
UNIQUEIDENTIFIERSemplice 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
TABLEUsato per ricordare un result set di una query per utilizzi futuri.Max 2 GB
SQL_VARIANTPuò 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.


di Matteo Lucato, pubblicato il 12 aprile 2019