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?
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.
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
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.
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.
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.
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.
SELECT
que precisa criar uma tabela temporária. Se possível, ele irá usarMEMORY
, e converterVARCHAR
aCHAR
para a tabela tmp. AgoraVARCHAR(100)
leva 100 (ou 300) bytes fixos, possivelmente diminuindo a velocidade da consulta.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
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
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.
fonte
CHARACTER SET
latin1 ou ascii. Para utf8, o Obrigatório de armazenamento paraCHAR(4)
é 12.