Nenhum DBMS que conheço possui qualquer "otimização" que faça VARCHAR
com que um 2^n
comprimento tenha um desempenho melhor do que um com um max
comprimento que não seja uma potência 2.
Acho que as primeiras versões do SQL Server tratavam um VARCHAR
comprimento 255 diferente daquele que possuía um comprimento máximo maior. Não sei se ainda é esse o caso.
Para quase todos os DBMS, o armazenamento real necessário é determinado apenas pelo número de caracteres que você coloca nele, não pelo max
comprimento definido. Portanto, do ponto de vista do armazenamento (e provavelmente também do desempenho), não faz diferença se você declara uma coluna como VARCHAR(100)
ou VARCHAR(500)
.
Você deve ver o max
comprimento fornecido para uma VARCHAR
coluna como um tipo de restrição (ou regra de negócios) em vez de algo técnico / físico.
Para o PostgreSQL, a melhor configuração é usar text
sem restrição de comprimento e CHECK CONSTRAINT
que limite o número de caracteres para o que sua empresa exigir.
Se esse requisito mudar, alterar a restrição de verificação é muito mais rápido do que alterar a tabela (porque a tabela não precisa ser reescrita)
O mesmo pode ser aplicado para Oracle e outros - no Oracle, em VARCHAR(4000)
vez disso text
.
Não sei se há uma diferença de armazenamento físico entre VARCHAR(max)
e, por exemplo, VARCHAR(500)
no SQL Server. Mas, aparentemente, há um impacto no desempenho ao usar varchar(max)
em comparação com varchar(8000)
.
Veja este link (postado por Erwin Brandstetter como um comentário)
Edit 22-09-2013
Em relação ao comentário de bigown:
Em Postgres versões antes 9.2 (que não estava disponível quando eu escrevi a resposta inicial) uma alteração na definição de coluna fez reescrever toda a tabela, ver, por exemplo aqui . Desde 9.2, esse não é mais o caso, e um teste rápido confirmou que o aumento do tamanho da coluna de uma tabela com 1,2 milhão de linhas levou apenas 0,5 segundos.
Para a Oracle, isso também parece verdadeiro, a julgar pelo tempo necessário para alterar a varchar
coluna de uma grande tabela . Mas não encontrei nenhuma referência para isso.
Para o MySQL, o manual diz " Na maioria dos casos, ALTER TABLE
faz uma cópia temporária da tabela original ". E meus próprios testes confirmam que: executar um ALTER TABLE
em uma tabela com 1,2 milhão de linhas (o mesmo que no meu teste com o Postgres) para aumentar o tamanho de uma coluna levou 1,5 minutos. No MySQL, no entanto, você não pode usar a "solução alternativa" para usar uma restrição de verificação para limitar o número de caracteres em uma coluna.
Para o SQL Server, não consegui encontrar uma declaração clara sobre isso, mas o tempo de execução para aumentar o tamanho de uma varchar
coluna (novamente a tabela de 1,2 milhão de linhas acima) indica que nenhuma reescrita ocorre.
Editar 2017-01-24
Parece que eu estava (pelo menos parcialmente) errado sobre o SQL Server. Veja esta resposta de Aaron Bertrand que mostra que o comprimento declarado de uma nvarchar
ou varchar
colunas faz uma enorme diferença para o desempenho.
varchar(max)
é provavelmente mais parecido com o da OracleCLOB
VARCHAR(255)
eVARCHAR(2)
ocupe exatamente a mesma quantidade de espaço em disco! Portanto, o único motivo para limitá-lo é se você tem uma necessidade específica de que ele seja menor. Caso contrário, faça todos eles 255.Especificamente, ao fazer a classificação, uma coluna maior ocupa mais espaço; portanto, se isso prejudica o desempenho, você precisa se preocupar com isso e reduzi-lo. Mas se você selecionar apenas uma linha dessa tabela, poderá fazê-las todas 255 e isso não importa.
Veja: Quais são os tamanhos ótimos de varchar para o MySQL?
fonte
VARCHAR(MAX)
? Espaço não é a única consideração ao modelar um banco de dados. O domínio que você está modelando deve direcionar tipos e tamanhos de dados.VARCHAR(MAX)
não é o mesmo quevarchar(255)
ouvarchar(65535)
- varchar max é um tipo de tipo detext
dados. E ao seu ponto - se ele soubesse qual o "domínio que ele estava modelando", ele não faria essa pergunta. Claramente, ele não sabe o tamanho dos dados e estou assegurando-lhe que fazê-lo em tamanho real não prejudica nada.(a,b,c,d)
índice quando todas as quatro colunas estiveremVARCHAR(255)
.Sempre que configuro uma nova tabela SQL, sinto da mesma maneira que 2 ^ n é mais "par" ... mas, para resumir as respostas aqui, não há impacto significativo no espaço de armazenamento simplesmente definindo varchar (2 ^ n) ou mesmo varchar (MAX).
Dito isso, você ainda deve antecipar as implicações potenciais sobre armazenamento e desempenho ao definir um limite alto de varchar (). Por exemplo, digamos que você crie uma coluna varchar (MAX) para armazenar descrições de produtos com indexação de texto completo. Se 99% das descrições tiverem apenas 500 caracteres e, de repente, você conseguir alguém que substitua as descrições por artigos da wikipedia, você poderá perceber acertos significativos inesperados de armazenamento e desempenho.
Outra coisa a considerar de Bill Karwin :
Basicamente, basta apresentar restrições comerciais razoáveis e erros em um tamanho um pouco maior. Como @onedaywhen apontou, os nomes de família no Reino Unido geralmente têm entre 1 e 35 caracteres. Se você decidir fazer o varchar (64), não vai machucar nada ... a menos que esteja armazenando o nome de família desse cara com 666 caracteres. Nesse caso, talvez varchar (1028) faça mais sentido.
E, caso seja útil, eis como varchar 2 ^ 5 a 2 ^ 10 pode parecer se preenchido:
fonte
O melhor valor é o correto para os dados, conforme definido no domínio subjacente.
Para alguns domínios,
VARCHAR(10)
é adequado para oName
atributo, para outros domíniosVARCHAR(255)
pode ser a melhor opção.fonte
Adicionando à resposta de a_horse_with_no_name, você pode encontrar o seguinte de interesse ...
Não se esqueça do byte de comprimento e do byte nulo;
name varchar(100) not null
terá 1 byte (comprimento) + até 100 caracteres (latin1)name varchar(500) not null
terá 2 bytes (comprimento) + até 500 caracteres (latin1)name varchar(65533) not null
terá 2 bytes (comprimento) + até 65533 caracteres (latin1)name varchar(65532)
terá 2 bytes (comprimento) + até 65532 caracteres (latin1) + 1 byte nuloEspero que isto ajude :)
fonte
Sempre verifique com seu especialista em domínio comercial. Se for você, procure um padrão do setor. Se, por exemplo, o domínio em questão for o nome de família (sobrenome) de uma pessoa natural, para uma empresa no Reino Unido, eu iria ao catálogo de padrões de dados do Govtalk do Reino Unido para obter informações pessoais e descobriria que um nome de família terá entre 1 e 35 caracteres .
fonte
Não verifiquei isso recentemente, mas sei no passado com a Oracle que o driver JDBC reservaria um pedaço de memória durante a execução da consulta para manter o conjunto de resultados retornando. O tamanho do pedaço de memória depende das definições da coluna e do tamanho da busca. Portanto, o comprimento das colunas varchar2 afeta a quantidade de memória reservada. Isso causou sérios problemas de desempenho para mim anos atrás, pois sempre usamos varchar2 (4000) (o máximo da época) e a coleta de lixo era muito menos eficiente do que é hoje.
fonte
De certa forma, você está certo, embora algo menor que 2 ^ 8 caracteres ainda seja registrado como um byte de dados.
Se você considerar o caractere base que deixa qualquer coisa com um VARCHAR <255 como consumindo a mesma quantidade de espaço.
255 é uma boa definição de linha de base, a menos que você particularmente queira reduzir a entrada excessiva.
fonte