Uma página de banco de dados do SQL Server é definida como tendo 8192 bytes de tamanho. Há algumas informações de cabeçalho que dizem ter 96 bytes de tamanho.
E se você já tentou criar uma tabela com mais de 8053 bytes de definições de coluna, você receberá a mensagem de erro:
Creating or altering table 'Generated_Data_GUID' failed because the minimum row size would be 8061, including 7 bytes of internal overhead. This exceeds the maximum allowable table row size of 8060 bytes.
A seguir está um exemplo de tabela DDL:
CREATE TABLE [dbo].[Generated_Data_GUID](
[ID] [int] IDENTITY(1,1) NOT NULL,
[GUID] [uniqueidentifier] NOT NULL,
[SEQGUID] [uniqueidentifier] NOT NULL,
[Data1] [char](4000) NULL,
[Data2] [char](4000) NULL,
[Data3] [char](9) NULL,
[EntryDate] [datetime2](7) NULL
) ON [PRIMARY]
Com o DDL acima, se eu alterar a definição da coluna para column Data3
to be char(10)
, vou receber a mensagem de erro.
Os tamanhos de byte para cada tipo de coluna são os seguintes:
int : 4 bytes
uniqueidentifiere : 16 bytes
char(n) : n bytes
datetime2(n) : 6 bytes if n < 3
7 bytes if n = 3 or n = 4
8 bytes if n > 4
Se fizermos algumas contas simples, acabamos com o seguinte cálculo:
Page Size : 8192 bytes
-----------
Header : 96 bytes -
Internal Overhead : 7 bytes -
Max Size : 8053 bytes -
-----------
Missing Data : 36 bytes
===========
Pergunta
O que esses 36 bytes contêm?
Material de referência
- Guia de arquitetura de páginas e extensões (Microsoft Docs)
- Dentro do Storage Engine: Anatomia de uma página (SQLSkills.com)
Paul Randal realmente responde a essa pergunta exata nos comentários da postagem do blog que você vinculou:
Então, respondendo à pergunta no corpo do seu post:
Os 36 bytes "extras" em uma página são usados da seguinte forma:
Apenas para confirmar que a tabela definida na pergunta tem, de fato, 8060 bytes de largura, vamos fazer uma reprodução completa.
Primeiro vamos configurar o banco de dados e a tabela, e inserir uma linha nela. Estou adicionando um índice clusterizado porque os heaps são os piores.
Podemos ver todas as páginas alocadas ao índice executando este comando DBCC:
Aquela com um tipo de página 1 é a página de índice (ID de página 336). Podemos despejar todos os tipos de informações sobre essa página com este outro comando DBCC:
Aqui estão alguns trechos importantes da saída desse comando. Na seção HEADER:
Isso significa que há 34 bytes de espaço livre na página. Esses são os 36 que você descreveu em sua postagem original, menos os 2 bytes para a entrada da matriz de slot. Falando nisso:
Isso significa que há apenas um registro nesta página.
Agora, para baixo na seção de registro:
Isso indica que o único registro armazenado nesta página é de 8060 bytes (que é a soma de todos os tamanhos de armazenamento de tipo de dados mais a sobrecarga de 7 bytes por registro).
Portanto, temos um registro de 8060 bytes de tamanho completo nesta página. No entanto, ainda podemos espremer 34 bytes adicionais nesta página se tentarmos mais.
Por exemplo, eu poderia criar uma tabela com 2015 bytes de largura. Cada linha ocuparia 2015 + 7 (sobrecarga interna) + 2 (matriz de slot) = 2024 bytes na página. Portanto, quatro linhas devem somar 8096 bytes, preenchendo exatamente o espaço restante após o cabeçalho de 96 bytes. Vamos tentar no mesmo banco de dados:
Agora encontramos nossa página, e há apenas uma como esperado:
Então agora queremos obter informações na página 352:
E aqui estão as coisas boas:
Sem espaço livre! Esta página está cheia com nossas 4 linhas.