Tudo o que se segue é citado da datetime
linha aqui . Quebrei a citação para comentar meu entendimento.
Usa a representação de dados inteiros usando dois inteiros de 4 bytes. O valor inteiro representa o número de dias com data base de 1900-01-01.
Em outras palavras, temos oito bytes para trabalhar. Isso é exatamente igual ao que datetime
já está sendo feito.
Os primeiros 2 bytes podem representar até o ano 2079. A compactação sempre pode salvar 2 bytes aqui até esse ponto.
Ou seja, até 2079 estaremos perdendo dois bytes por ano. Depois desse ponto, perderemos mais. Isso significa que para datas anteriores a 2079, temos seis dos nossos oito bytes originais para trabalhar.
Cada valor inteiro representa 3,33 milissegundos. A compactação esgota os primeiros 2 bytes nos primeiros cinco minutos [sic] e precisa do quarto byte após as 16h.
Em outras palavras, depois das 16h, só temos dois dos seis bytes restantes para trabalhar.
Portanto, a compactação pode salvar apenas 1 byte após as 16h.
Esta é claramente a parte que não entendo . Minha aritmética anterior prova que nos restam dois adeus. No entanto, a Microsoft diz que só temos um. Isso é duplamente confuso, porque se já passarmos de 2079, os números da Microsoft nos colocariam como tendo menos um byte restante.
Quando datetime é compactado como qualquer outro número inteiro, a compactação salva 2 bytes na data.
O usuário não tem controle sobre como funciona a compactação, portanto esta linha é totalmente irrelevante.
Pelo exposto, é evidente que tenho um grande mal-entendido. O que eu perdi?
Não preste atenção à documentação para
datetime
compactação de linhas; é um absurdo. Só posso presumir que o autor combinou várias ideias sobredatetime
armazenamento, na memória e no armazenamento persistente.O fato é que ele
datetime
é compactado como um único valor de oito bytes, com quatro bytes para a data precedendo quatro para a parte da hora. Os bytes de data são um número inteiro assinado* para dias antes ou depois da data base. Os bytes de tempo são o número inteiro de ticks (1/300s) após a meia-noite.O efeito é que o armazenamento do descritor de coluna para linhas compactadas
datetime
depende quase exclusivamente da data, não da parte da hora.A única data em que o tempo entra em jogo é a data base, '1900-01-01', porque é codificada como zero na parte da data e todos esses zeros podem ser compactados.
O armazenamento físico necessário apenas naquela data depende do número de bytes necessários para codificar a parte da hora. À meia-noite da data base, o tamanho do armazenamento é zero, normalmente para compactação de linha.
O número de bytes compactados em linha necessários
datetime
está resumido abaixo:Para os valores mais comuns
datetime
(nativamente oito bytes), você pode esperar salvar um ou dois bytes.Exemplo
Como a documentação menciona sempre salvar dois bytes para datas anteriores a 2079, vamos ver como '31 de dezembro de 2078' é armazenado:
Usando
DBCC PAGE
:A data é 65.378 (0xFF62) dias após a data base. Esse número não cabe no intervalo assinado de dois bytes (-32.768 a +32.767), portanto são necessários três bytes.
Três bytes podem acomodar 16.777.216 valores e metade desse intervalo é 8.388.608. Aplicar a tendência ao nosso número de dias resulta em 65.378 - 8.388.608 = -8.323.230 (0x80FF62).
Você pode ver os bytes de data codificados
80FF62
na captura de tela, seguidos por quatro zero bytes para o componente de tempo, dando um total de sete bytes de armazenamento compactado em linha.* O formato abreviado do descritor de coluna armazena apenas valores positivos. Os números negativos são acomodados aplicando uma tendência de metade do intervalo sem sinal. Por exemplo, -1 no formato de um byte é armazenado como 127 (0x7f), após aplicar uma polarização de 128 (metade do intervalo não assinado de byte único).