Um valor de coluna vazio ocupa o mesmo espaço de armazenamento que um valor de coluna preenchido?


15

Eu tenho uma tabela com 2 colunas. O tipo de ambas as colunas está definido como varchar(38). Se eu criar uma linha com um valor vazio para uma das colunas, será necessário o mesmo espaço de armazenamento como se o valor não estivesse vazio?

Em outras palavras, o MySQL reservará espaço de armazenamento para a coluna (dependendo do seu tipo) quando uma linha for criada?

Respostas:


11

Na estrutura da linha física do Innodb, marcador nº 7 em REDUNDANT ROW_FORMAT

Um valor SQL NULL reserva um ou dois bytes no diretório de registro. Além disso, um valor SQL NULL reserva zero bytes na parte de dados do registro, se armazenado em uma coluna de comprimento variável . Em uma coluna de comprimento fixo, ele reserva o comprimento fixo da coluna na parte de dados do registro. A reserva do espaço fixo para valores NULL permite que uma atualização da coluna de NULL para um valor não NULL seja feita no local sem causar fragmentação da página de índice.

Na estrutura da linha física do Innodb, marcador nº 2 em COMPACT ROW_FORMAT

A parte de comprimento variável do cabeçalho do registro contém um vetor de bits para indicar colunas NULL. Se o número de colunas no índice que pode ser NULL for N, o vetor de bit ocupará CEILING (N / 8) bytes . (Por exemplo, se houver entre 9 e 15 colunas que podem ser NULL, o vetor de bit usa dois bytes.) As colunas NULL não ocupam espaço além do bit desse vetor . A parte de comprimento variável do cabeçalho também contém os comprimentos das colunas de comprimento variável. Cada comprimento ocupa um ou dois bytes, dependendo do comprimento máximo da coluna. Se todas as colunas no índice NÃO forem nulas e tiverem um comprimento fixo, o cabeçalho do registro não terá parte de comprimento variável.

Com base nesses marcadores, eis o que um NULLvalor ocupa no armazenamento de uma coluna

  • comprimento da variável: um valor NULL ocupa nenhum armazenamento na própria linha
  • comprimento fixo: ocupa o espaço reservado

Agora, você deve decidir entre usar CHAR e VARCHAR por causa do que o primeiro ponto trouxe à tona

A reserva do espaço fixo para valores NULL permite que uma atualização da coluna de NULL para um valor não NULL seja feita no local sem causar fragmentação da página de índice

Isso impedirá a introdução de qualquer fragmentação de uma linha no caminho depois que dados não-NULL forem armazenados. Isso é algo que eu discuti antes com relação ao MyISAM: Veja minha postagem antiga Qual é o impacto no desempenho do uso de CHAR vs VARCHAR em um campo de tamanho fixo? .


Oi Rolando, havia outro item que esqueci de mencionar, a diferença na alocação de memória entre uma declaração do tipo varchar (5) e varchar (100). Ou realmente a penalidade incorrida pela superalocação.
Craig Efrein

@ CraigEfrein Você definitivamente deve adicionar alocação de memória à sua resposta. (BTW eu já upvoted sua resposta)
RolandoMySQLDBA

1
A penalidade pela alocação excessiva ocorre quando você tem um complexo SELECTque precisa criar uma tabela temporária. Se possível, ele irá usar MEMORY, e converter VARCHARa CHARpara a tabela tmp. Agora VARCHAR(100)leva 100 (ou 300) bytes fixos, possivelmente diminuindo a velocidade da consulta.
Rick James

@RolandoMySQLDBA, o comportamento explicado na sua resposta é aplicável aos formatos de linha Mysql 5.7 DYNAMIC e COMPACT.
Dinesh Kumar # /

@DineshKumar Estes parágrafos ainda estão no Docs 5.7 / 8.0. Consulte dev.mysql.com/doc/refman/5.7/en/innodb-row-format-dynamic.html para DYNAMIC.
RolandoMySQLDBA

8

Independentemente do comprimento que você definir para sua coluna varchar, o espaço de armazenamento usado por uma coluna vazia será o mesmo.

Os tipos CHAR e VARCHAR

insira a descrição da imagem aqui

Isso aborda apenas o espaço usado pela coluna varchar e não considera o espaço total de armazenamento usado pela linha, seus índices, chaves primárias e outras colunas.

Como o ypercube menciona em seu comentário, há considerações adicionais para o armazenamento de linhas como um todo quando pelo menos uma coluna anulável está presente.

Estrutura da linha física do Innodb

A parte de comprimento variável do cabeçalho do registro contém um vetor de bits para indicar colunas NULL. Se houver entre 9 e 15 colunas que podem ser NULL, o vetor de bit usa dois bytes.)

...

A parte de comprimento variável do cabeçalho também contém os comprimentos das colunas de comprimento variável. Cada comprimento ocupa um ou dois bytes, dependendo do comprimento máximo da coluna. Se todas as colunas no índice NÃO forem nulas e tiverem um comprimento fixo, o cabeçalho do registro não terá parte de comprimento variável

E sim, o espaço de armazenamento usado muda de acordo com o tipo que você escolhe, é fixo ou variável, o agrupamento e outros fatores, como o mecanismo.

O MySQL faz recomendações sobre como otimizar o armazenamento de dados aqui: Otimizando o Tamanho dos Dados

Atualizar

Uma consideração adicional com varchar e isso é memória. É importante no MySQL limitar o tamanho de uma coluna de comprimento variável o máximo possível. Mesmo que a coluna seja variável e o espaço de armazenamento usado seja variável, o MySQL alocará memória em partes fixas para armazenar valores. Por exemplo, varchar (200) usará mais memória que varchar (5). Este não é um problema de espaço de armazenamento, mas ainda há algo a considerar ao definir suas colunas.


Os números acima assumem CHARACTER SETlatin1 ou ascii. Para utf8, o Obrigatório de armazenamento para CHAR(4)é 12.
Rick James
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.