Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Tamanho máximo da linha do SQL Server vs tamanho Varchar(Max)


No Microsoft SQL Server, os dados (que incluem índices) são armazenados em uma ou mais "páginas" de 8k (8192 bytes). Existem diferentes tipos de páginas que podem ser usadas para lidar com várias situações (por exemplo, Data, LOB, Index, AllocationMap, etc). Cada página tem um cabeçalho que são metadados sobre essa página e o que ela contém.

A maioria dos dados é armazenada na própria linha e uma ou mais dessas linhas, por sua vez, são armazenadas em uma página para "dados na linha". Devido ao espaço ocupado pelo cabeçalho da linha, o maior que uma linha pode ter (para dados "in-row") é 8060 bytes.

No entanto, nem todos os dados são armazenados na linha. Para certos tipos de dados, os dados podem ser armazenados em uma página "LOB data" enquanto um ponteiro é deixado nos dados "in-row":

  • Tipos de LOB legados / obsoletos que ninguém deveria usar mais (TEXT , NTEXT e IMAGE ), por padrão, sempre armazenam seus dados em páginas LOB e sempre usam um ponteiro de 16 bytes para essa página LOB.

  • Os tipos de LOB mais recentes (VARCHAR(MAX) , NVARCHAR(MAX) , VARBINARY(MAX) e XML ), por padrão, tentará ajustar os dados diretamente na linha, se for o caso. Caso contrário, ele armazenará os dados em páginas LOB e usará um ponteiro de 24 a 72 bytes (dependendo do tamanho dos dados LOB).

É assim que você pode armazenar até 78 GB + 4 bytes (não se esqueça do INT Chave Primária;-) em uma única linha:o tamanho máximo da linha será entre 940 bytes ((39 * 24) + 4) e 2812 bytes ((39 * 72) + 4). Mas, novamente, esse é apenas o alcance máximo; se os dados em cada um dos 39 VARCHAR(MAX) field for de apenas 10 bytes, então todos os dados serão armazenados na linha e o tamanho da linha será de 394 bytes ((39 * 10) + 4).

Dado que você tem tantos campos de comprimento variável (sejam eles MAX ou não), a única maneira de estimar o tamanho das linhas futuras é ter uma boa ideia sobre quais dados você armazenará nesta tabela. No entanto, uma tabela com todos, ou mesmo a maioria, tipos de dados MAX implica que ninguém realmente tem ideia do que será armazenado nessa tabela.

Nessa linha, deve-se ressaltar que esta é uma tabela horrivelmente modelada / uso horrível de campos de tipo de dados MAX e deve ser refatorada.

Para obter mais detalhes sobre como as páginas de dados são estruturadas, consulte minha resposta à seguinte pergunta do DBA.StackExchange:

SOMA de DATALENGTHs que não corresponde ao tamanho da tabela de sys.allocation_units