Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Dimensione massima della riga di SQL Server rispetto alla dimensione Varchar(max).

In Microsoft SQL Server, i dati (che includono gli indici) sono archiviati in una o più "pagine" da 8k (8192 byte). Esistono diversi tipi di pagine che possono essere utilizzate per gestire varie situazioni (ad es. Data, LOB, Index, AllocationMap, ecc.). Ogni pagina ha un'intestazione che contiene metadati su quella pagina e su ciò che contiene.

La maggior parte dei dati viene archiviata nella riga stessa e una o più di queste righe vengono a loro volta archiviate in una pagina per i "dati interni alla riga". A causa dello spazio occupato dall'intestazione di riga, il massimo che può essere una riga (per i dati "in-row") è 8060 byte.

Tuttavia, non tutti i dati vengono archiviati nella riga. Per alcuni tipi di dati, i dati possono essere effettivamente archiviati su una pagina "dati LOB" mentre un puntatore viene lasciato nei dati "in-row":

  • Tipi LOB legacy / obsoleti che nessuno dovrebbe più utilizzare (TEXT , NTEXT e IMAGE ), per impostazione predefinita, memorizza sempre i propri dati su pagine LOB e utilizza sempre un puntatore a 16 byte a quella pagina LOB.

  • I tipi LOB più recenti (VARCHAR(MAX) , NVARCHAR(MAX) , VARBINARY(MAX) e XML ), per impostazione predefinita, tenterà di adattare i dati direttamente nella riga se si adattano. Altrimenti memorizzerà i dati sulle pagine LOB e utilizzerà un puntatore di 24 - 72 byte (a seconda della dimensione dei dati LOB).

Ecco come puoi memorizzare fino a 78 GB + 4 byte (non dimenticare il INT Chiave primaria;-) in una singola riga:la dimensione massima della riga sarà compresa tra 940 byte ((39 * 24) + 4) e 2812 byte ((39 * 72) + 4). Ma ancora una volta, questa è solo la gamma massima; se i dati in ciascuno dei 39 VARCHAR(MAX) i campi sono solo 10 byte, quindi tutti i dati verranno archiviati nella riga e la dimensione della riga sarà di 394 byte ((39 * 10) + 4).

Dato che hai così tanti campi a lunghezza variabile (indipendentemente dal fatto che siano MAX o meno), l'unico modo per stimare la dimensione delle righe future è avere una buona idea di quali dati memorizzerai in questa tabella. Anche se una tabella con tutti, o anche quasi tutti, i tipi di dati MAX implica che nessuno ha davvero idea di cosa verrà archiviato in questa tabella.

In tal senso, va sottolineato che si tratta di una tabella modellata in modo orribile / uso orribile dei campi del tipo di dati MAX e dovrebbe essere rifattorizzato.

Per maggiori dettagli su come sono strutturate le pagine di dati, vedere la mia risposta alla seguente domanda DBA.StackExchange:

SOMMA di DATALENGTH non corrispondenti alle dimensioni della tabella da sys.allocation_units