Devo usar varchar(255)
ou varchar(256)
ao projetar tabelas? Ouvi dizer que um byte é usado para o comprimento da coluna ou para armazenar metadados.
Isso importa mais neste momento?
Eu vi alguns posts na internet, porém eles se aplicam a Oracle e MySQL.
Temos o Microsoft SQL Server 2016 Enterprise Edition, como se aplica a este ambiente?
Agora diga, por exemplo, e se eu dissesse aos meus clientes para manter, por exemplo, uma descrição de texto com 255 caracteres em vez de 256, há alguma diferença? O que li "Com comprimento máximo de 255 caracteres, o SGBD pode optar por usar um único byte para indicar o comprimento dos dados no campo. Se o limite fosse 256 ou maior, seriam necessários dois bytes." Isso é verdade?
Dimensione cada coluna adequadamente. NÃO use um tamanho "padrão" para cada coluna. Se você precisa apenas de 30 caracteres, por que criar uma coluna que possa lidar com 255? Estou tão feliz que você não está defendendo o uso
varchar(max)
de suas colunas de string.Este é um conselho especialmente prudente se você precisar indexar uma coluna ou se estiver usando uma coluna como chave primária e ela tiver referências de chave estrangeira. O SQL Server usa o tamanho de cada coluna em seu otimizador de consulta para entender os requisitos estimados de memória para processamento de consulta. Ter colunas superdimensionadas pode prejudicar o desempenho.
Índices em colunas muito grandes podem resultar na geração de erros:
A tentativa de criar o índice acima resulta neste aviso:
900 bytes é o tamanho máximo da chave para índices clusterizados (e índices não clusterizados no SQL Server 2012 e anteriores). 1700 bytes é o tamanho máximo da chave para índices não clusterizados em versões mais recentes do SQL Server. Se você projetar colunas com uma largura genérica, como (255), poderá encontrar esse aviso com muito mais frequência do que o esperado.
Caso esteja interessado em armazenamento interno, você pode usar o pequeno teste a seguir para entender melhor como o SQL Server armazena dados de armazenamento de linha não compactados.
Primeiro, vamos criar uma tabela onde podemos armazenar colunas de vários tamanhos:
Agora vamos inserir uma única linha:
Esta consulta usa as funções não documentadas e não suportadas
sys.fn_RowDumpCracker
esys.fn_PhyslocCracker
mostra alguns detalhes interessantes sobre a tabela:A saída será semelhante a esta:
Como você pode ver, o
InRowLength
para cada valor é mostrado, juntamente com o local de armazenamento físico de cada linha - o "file_id", "page_id" e "slot_id".Se pegarmos os valores
file_id
epage_id
dos resultados da consulta acima e executarmosDBCC PAGE
com eles, podemos ver o conteúdo real da página física:Os resultados da minha máquina são:
Outros já apontaram que o número de bytes necessários para armazenar o comprimento é fixo. Eu queria focar nesta parte em sua pergunta:
Você tem sua pergunta marcada com edição corporativa, o que geralmente significa que você terá uma quantidade razoável de dados. Muitas vezes, as diferenças de um byte por linha realmente não importam muito na prática. Por exemplo, a tabela a seguir com uma
VARCHAR(255)
coluna totalmente preenchida ocupa 143176 KB de espaço em disco:Resultados:
Vamos criar uma segunda tabela com uma
VARCHAR(256)
coluna totalmente preenchida. Isso vai levar pelo menos mais um byte por linha, certo?Resultados:
Acontece que ambas as tabelas ocupam a mesma quantidade de espaço. O mesmo número de linhas cabe em cada página de 8k. É ótimo que você queira gastar tempo otimizando seu aplicativo, mas suspeito que é melhor se concentrar em diferentes áreas.
O tamanho declarado do varchar raramente tem impacto no desempenho 1 . Os dados podem ser realmente armazenados como um rowstore com compactação de página ou compactação de linha. Como um Columnstore em cluster ou como uma tabela com otimização de memória. Cada um deles terá diferentes compensações de desempenho, mas nunca importa se você declara um varchar(255) ou varchar(256).
1 - em circunstâncias específicas, há implicações de desempenho em torno do tamanho das colunas que variam de caracteres; Brent Ozar tem um ótimo artigo sobre isso aqui