Melhores práticas para o comprimento da coluna varchar SQL

Cada vez que se cria uma nova tabela SQL ou se adiciona uma nova coluna {[[0]} a uma tabela existente, pergunto-me uma coisa: qual é o melhor valor para o length.

Então, digamos que você tem uma coluna chamada name do tipo varchar. Então, você tem que escolher o comprimento. Não consigo pensar num nome > 20 caracteres, mas nunca saberás. Mas em vez de usar 20, Eu sempre arredondar para o próximo número 2^n. Neste caso, eu escolheria 32 como o comprimento. Eu faço isso, porque a partir de um ponto cientista da computação of view, a number 2^n looks more even to me than other numbers and i'm just supposing that the architecture underneath can handle those numbers slightly better than others.

por outro lado, o servidor MSSQL, por exemplo, define o valor de tamanho padrão para 50, quando você optar por criar uma coluna varchar. Isso faz-me pensar nisso. Porquê 50? é apenas um número aleatório, ou baseado no comprimento médio da coluna, ou o quê?

também pode ser - ou provavelmente é-que diferentes servidores SQL implementações (como MySQL, MSSQL, Postgres,...) têm diferentes melhores valores de comprimento de coluna.

Author: MaxiWheat, 2011-11-28

7 answers

Nenhum DBMS que eu conheça tem qualquer "optimização" que faça um {[[0]} com um 2^n Comprimento executar melhor do que um com um max Comprimento que não é uma potência de 2.

Acho que as versões iniciais do servidor de SQL trataram realmente um {[[0]} com o comprimento 255 de forma diferente de um com um comprimento máximo mais elevado. Não sei se ainda é assim.

Para quase todos os DBMS, o armazenamento real que é necessário é determinado apenas pelo número de caracteres que você coloca nele, não o max comprimento que define. Assim, do ponto de vista do armazenamento (e provavelmente também do desempenho), não faz qualquer diferença se você declara uma coluna como VARCHAR(100) ou VARCHAR(500).

Você deve ver o max Comprimento previsto para uma coluna VARCHAR como uma espécie de restrição (ou regra de negócio) em vez de uma coisa técnica/física.

Para o PostgreSQL a melhor configuração é usar {[[9]} sem uma restrição de comprimento e um {[10] } que limita o número de caracteres para qualquer que seja o seu negócio requerer.

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 seria VARCHAR(4000) Em vez de text embora.

Não sei se existe uma diferença física de armazenamento entre VARCHAR(max) e por exemplo VARCHAR(500) no servidor SQL. Mas aparentemente há um impacto no desempenho quando se usa varchar(max) em comparação com varchar(8000).

Ver Este link (publicado por Erwin Brandstetter como comentário)

Editar 2013-09-22

Quanto ao Comentário de bigown:

Nas versões Postgres antes de 9.2 (que não estava disponível quando escrevi a resposta inicial) uma alteração na definição da coluna fez reescrever a tabela inteira, ver por exemplo aqui. Uma vez que 9.2 este já não é o caso e um teste rápido confirmou que o aumento do tamanho da coluna para uma tabela com 1,2 milhões as linhas de fato levaram apenas 0,5 segundos.

Para a Oracle, isto também parece ser verdade, a julgar pelo tempo necessário para alterar a coluna de uma grande tabela. Mas não encontrei nenhuma referência para isso. 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ões de linhas (o mesmo que em meu teste com Postgres) para aumentar o tamanho de uma coluna levou 1,5 minuta. No MySQL, no entanto, você pode Não usar o "workaround" para usar uma restrição de verificação para limitar o número de caracteres numa coluna.

Para o servidor de SQL não consegui encontrar uma declaração clara sobre isto, mas o tempo de execução para aumentar o tamanho de uma coluna varchar (mais uma vez a tabela de 1.2 milhões de linhas acima) indica que não a reescrita tem lugar.

Editar 2017-01-24

Parece que eu estava (pelo menos parcialmente) errado sobre o servidor SQL. Ver esta resposta de Aaron Bertrand {[42] } que mostra que o comprimento declarado de uma nvarchar ou varchar colunas faz uma enorme diferença para o desempenho.

 184
Author: a_horse_with_no_name, 2017-08-11 15:43:01

VARCHAR(255) e VARCHAR(2) tome exactamente a mesma quantidade de espaço no disco! Então a única razão para limitá-lo é se você tem uma necessidade específica para que ele seja menor. Caso contrário, torna-os todos 255.

Especificamente, ao fazer a triagem, coluna maior ocupa mais espaço, por isso, se isso prejudicar o desempenho, então você precisa se preocupar com isso e torná-los menores. Mas se você só selecionar uma linha daquela mesa, então você pode apenas torná-los todos 255 e não vai importar.

Ver: Quais são os tamanhos de varchar ideais para o MySQL?

 50
Author: Ariel, 2018-04-26 03:49:25

O melhor valor é o correcto para os dados, tal como definido no domínio subjacente.

Para alguns domínios, VARCHAR(10) é correcto para o atributo Name, para outros domínios VARCHAR(255) pode ser a melhor escolha.

 29
Author: Oded, 2011-11-28 11:28:45
Sempre que monto uma nova tabela SQL sinto o mesmo sobre 2^n ser 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). [[[2]} dito isto, você ainda deve antecipar as potenciais implicações no armazenamento e desempenho ao definir um alto limite varchar (). Por exemplo, digamos que você cria uma coluna varchar(MAX) para manter descrições de produtos com indexação de texto completo. Se 99% dos as descrições têm apenas 500 caracteres de comprimento, e de repente você tem alguém que substitui essas descrições com artigos da Wikipédia, você pode notar um armazenamento significativo imprevisto e sucessos de performance.

Outra coisa a considerar de Bill Karwin:

Há um possível impacto no desempenho: em MySQL, mesas temporárias e as tabelas de memória armazenam uma coluna VARCHAR como uma coluna de comprimento fixo, acolchoado até ao seu comprimento máximo. Se desenhar muito as colunas VARCHAR maior do que o maior tamanho que você precisa, você vai consumir mais memória do que é preciso. Isso afeta a eficiência de cache, a velocidade de triagem, etc.
Basicamente, inventa restrições de Negócio razoáveis e erros num tamanho ligeiramente maior. Como @onedaywhen apontou, os nomes de família no Reino Unido são geralmente entre 1-35 caracteres. Se você decidir fazer varchar (64), Você realmente não vai machucar nada... a não ser que estejas a guardar o nome de família deste tipo. até 666 caracteres de comprimento. Nesse caso, talvez varchar(1028) faça mais sentido.

E no caso de ser útil, aqui está o que varchar 2^5 a 2^10 pode parecer se for preenchido:

varchar(32)     Lorem ipsum dolor sit amet amet.

varchar(64)     Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donecie

varchar(128)    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donecie
                vestibulum massa. Nullam dignissim elementum molestie. Vehiculas

varchar(256)    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donecie
                vestibulum massa. Nullam dignissim elementum molestie. Vehiculas
                velit metus, sit amet tristique purus condimentum eleifend. Quis
                que mollis magna vel massa malesuada bibendum. Proinde tincidunt

varchar(512)    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donecie
                vestibulum massa. Nullam dignissim elementum molestie. Vehiculas
                velit metus, sit amet tristique purus condimentum eleifend. Quis
                que mollis magna vel massa malesuada bibendum. Proinde tincidunt
                dolor tellus, sit amet porta neque varius vitae. Seduse molestie
                lacus id lacinia tempus. Vestibulum accumsan facilisis lorem, et
                mollis diam pretium gravida. In facilisis vitae tortor id vulput
                ate. Proin ornare arcu in sollicitudin pharetra. Crasti molestie

varchar(1024)   Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donecie
                vestibulum massa. Nullam dignissim elementum molestie. Vehiculas
                velit metus, sit amet tristique purus condimentum eleifend. Quis
                que mollis magna vel massa malesuada bibendum. Proinde tincidunt
                dolor tellus, sit amet porta neque varius vitae. Seduse molestie
                lacus id lacinia tempus. Vestibulum accumsan facilisis lorem, et
                mollis diam pretium gravida. In facilisis vitae tortor id vulput
                ate. Proin ornare arcu in sollicitudin pharetra. Crasti molestie
                dapibus leo lobortis eleifend. Vivamus vitae diam turpis. Vivamu
                nec tristique magna, vel tincidunt diam. Maecenas elementum semi
                quam. In ut est porttitor, sagittis nulla id, fermentum turpist.
                Curabitur pretium nibh a imperdiet cursus. Sed at vulputate este
                proin fermentum pretium justo, ac malesuada eros et Pellentesque
                vulputate hendrerit molestie. Aenean imperdiet a enim at finibus
                fusce ut ullamcorper risus, a cursus massa. Nunc non dapibus vel
                Lorem ipsum dolor sit amet, consectetur Praesent ut ultrices sit
 21
Author: Kit, 2018-07-24 20:58:12

Adicionando à resposta do a_horse_with_ no_name, poderá encontrar o seguinte interessante...

Não faz diferença se declara uma coluna como VARCHAR (100) ou varchar(500).

-- try to create a table with max varchar length
drop table if exists foo;
create table foo(name varchar(65535) not null)engine=innodb;

MySQL Database Error: Row size too large.

-- try to create a table with max varchar length - 2 bytes for the length
drop table if exists foo;
create table foo(name varchar(65533) not null)engine=innodb;

Executed Successfully

-- try to create a table with max varchar length with nullable field
drop table if exists foo;
create table foo(name varchar(65533))engine=innodb;

MySQL Database Error: Row size too large.

-- try to create a table with max varchar length with nullable field
drop table if exists foo;
create table foo(name varchar(65532))engine=innodb;

Executed Successfully

Não se esqueça do byte (S) comprimento e do byte nullable so:

name varchar(100) not null será de 1 byte (comprimento) + até 100 caracteres (latin1)

name varchar(500) not null será de 2 bytes (comprimento) + até 500 caracteres (latin1)

name varchar(65533) not null serão 2 bytes (comprimento) + até 65533 caracteres (latin1)

name varchar(65532) serão 2 bytes (comprimento) + até 65532 caracteres (latin1) + 1 byte nulo

Espero que isto ajude.
 12
Author: Jon Black, 2011-11-28 14:26:33

Verifique sempre com o seu especialista no domínio de negócios. Se és tu, procura um padrão industrial. Se, por exemplo, o domínio em questão for o nome de família de uma pessoa singular (apelido), então, para uma empresa do Reino Unido, eu iria ao catálogo de padrões de dados do GOVTALK do Reino Unido para informações sobre pessoas e descobriria que um nome de família será entre 1 e 35 caracteres.

 5
Author: onedaywhen, 2011-11-28 12:00:26
Não tenho verificado isto ultimamente, mas sei no passado com a Oracle que o controlador do JDBC reservaria um pedaço de memória durante a execução da consulta para manter o resultado a voltar. O tamanho do bloco de memória depende das definições de coluna e do tamanho de busca. Assim, o comprimento das colunas varchar2 afeta a quantidade de memória reservada. Isso causou sérios problemas de desempenho para mim anos atrás, como sempre usamos varchar2 (4000) (o máximo na época) e coleta de lixo foi muito menos eficiente do que é hoje.
 3
Author: user1041892, 2017-06-27 15:49:49