Eu tenho uma contacts
tabela que contém campos, como postcode
, first name
, last name
, town
, country
, phone number
etc, todos os quais são definidos como VARCHAR(255)
embora nenhum desses campos nunca vai chegar perto de ter 255 caracteres. (Se você está se perguntando, é assim porque as migrações do Ruby on Rails mapeiam campos String VARCHAR(255)
por padrão e eu nunca me preocupei em substituí-lo).
Uma vez que VARCHAR armazenará apenas o número de caracteres reais do campo (junto com o comprimento do campo), há alguma vantagem distinta (desempenho ou não) em usar, digamos, VARCHAR(16)
over VARCHAR(255)
?
Além disso, a maioria desses campos possui índices. Um tamanho VARCHAR maior no campo afeta o tamanho ou o desempenho do índice?
Para sua informação, estou usando o MySQL 5.
Respostas:
No armazenamento,
VARCHAR(255)
é inteligente o suficiente para armazenar apenas o comprimento necessário em uma determinada linha, ao contrário doCHAR(255)
que sempre armazenaria 255 caracteres.Mas já que você marcou esta questão com o MySQL, mencionarei uma dica específica do MySQL: conforme as linhas são copiadas da camada do mecanismo de armazenamento para a camada SQL, os
VARCHAR
campos são convertidosCHAR
para obter a vantagem de trabalhar com linhas de largura fixa. Portanto, as strings na memória são preenchidas até o comprimento máximo daVARCHAR
coluna declarada .Quando sua consulta gera implicitamente uma tabela temporária, por exemplo, durante a classificação ou
GROUP BY
, isso pode usar muita memória. Se você usar muitosVARCHAR(255)
campos para dados que não precisam ser tão longos, isso pode tornar a tabela temporária muito grande.Você também pode gostar de saber que esse comportamento de "preenchimento" significa que uma string declarada com o conjunto de caracteres utf8 chega a três bytes por caractere, mesmo para strings armazenadas com conteúdo de um byte (por exemplo, caracteres ascii ou latin1). Da mesma forma, o conjunto de caracteres utf8mb4 faz com que a string preencha até quatro bytes por caractere na memória.
Portanto, a
VARCHAR(255)
in utf8 que armazena uma string curta como "Sem opinião" leva 11 bytes no disco (dez caracteres de conjuntos de caracteres inferiores, mais um byte para o comprimento), mas ocupa 765 bytes na memória e, portanto, em tabelas temporárias ou resultados classificados.Eu ajudei usuários do MySQL que, sem saber, criaram tabelas temporárias de 1,5 GB com frequência e ocuparam seu espaço em disco. Eles tinham muitas
VARCHAR(255)
colunas que, na prática, armazenavam strings muito curtas.É melhor definir a coluna com base no tipo de dados que você pretende armazenar. Ele tem benefícios para impor restrições relacionadas ao aplicativo, como outras pessoas mencionaram. Mas tem os benefícios físicos de evitar o desperdício de memória que descrevi acima.
É difícil saber qual é o endereço postal mais longo, é claro, e é por isso que muitas pessoas escolhem um longo
VARCHAR
que certamente é mais longo do que qualquer endereço. E 255 é comum porque é o comprimento máximo de aVARCHAR
para o qual o comprimento pode ser codificado com um byte. Também era oVARCHAR
comprimento máximo no MySQL anterior a 5.0.fonte
255
era usado para que o comprimento da string pudesse caber em um único byteAlém das considerações de tamanho e desempenho ao definir o tamanho de um varchar (e possivelmente mais importante, já que o armazenamento e o processamento ficam mais baratos a cada segundo), a desvantagem de usar varchar (255) "apenas porque" é a integridade dos dados reduzida .
Definir limites máximos para strings é uma boa coisa a se fazer para evitar que strings maiores do que o esperado entrem no RDBMS e causem saturações de buffer ou exceções / erros posteriormente ao recuperar e analisar valores do banco de dados que são maiores (mais bytes) do que o esperado.
Por exemplo, se você tem um campo que aceita cadeias de caracteres de dois caracteres para abreviações de países, não há razão concebível para esperar que seus usuários (neste contexto, programadores) insiram nomes completos de países. Como você não deseja que eles insiram "Antigua e Barbuda" (AG) ou "Ilha Heard e Ilhas McDonald" (HM), você não permite isso na camada de banco de dados. Além disso, é provável que alguns programadores ainda não tenham feito o RTFM da documentação de design ( que certamente existe ) para saber que não deve fazer isso.
Defina o campo para aceitar dois caracteres e deixe o RDBMS lidar com isso (seja graciosamente truncando ou desajeitadamente rejeitando seu SQL com um erro).
Exemplos de dados reais que não têm razão para exceder um determinado comprimento:
E assim por diante...
Reserve um tempo para pensar sobre seus dados e seus limites. Se você é arquiteto, desenvolvedor ou programador, o trabalho é seu , afinal.
Usando um varchar (n) em vez de varchar (255), você elimina o problema onde os usuários (usuários finais, programadores, outros programas) inserem dados inesperadamente longos que voltarão para assombrar seu código mais tarde.
E eu não disse que você também não deveria implementar essa restrição no código de lógica de negócios usado por seu aplicativo.
fonte
the design documentation (which surely exists)
Hah. : DEstou contigo. A atenção minuciosa aos detalhes é uma dor de cabeça e tem valor limitado.
Era uma vez, o disco era um bem precioso e costumávamos suar para otimizá-lo. O preço do armazenamento caiu por um fator de 1.000, tornando o tempo gasto na compressão de cada byte menos valioso.
Se você usar apenas campos CHAR, poderá obter linhas de comprimento fixo. Isso pode economizar um pouco de atualização real do disco se você escolheu tamanhos precisos para os campos. Você pode obter dados mais densamente compactados (menos E / S para varreduras de tabela) e atualizações mais rápidas (mais fácil localizar espaços abertos em um bloco para atualizações e inserções).
No entanto, se você superestimar seus tamanhos, ou se os tamanhos reais dos dados forem variáveis, você acabará perdendo espaço com campos CHAR. Os dados ficarão menos compactados (levando a mais E / S para grandes recuperações).
Geralmente, os benefícios de desempenho da tentativa de colocar um tamanho em campos variáveis são mínimos. Você pode facilmente fazer o benchmark usando VARCHAR (255) em comparação com CHAR (x) para ver se você pode medir a diferença.
No entanto, às vezes, preciso fornecer uma dica "pequena", "média", "grande". Portanto, uso 16, 64 e 255 para os tamanhos.
fonte
Hoje em dia, não consigo imaginar que isso realmente importe mais.
Há uma sobrecarga computacional no uso de campos de comprimento variável, mas com os excessos das CPUs hoje, nem vale a pena considerar. O sistema de E / S é tão lento que torna inexistentes quaisquer custos computacionais para lidar com os varchars. Na verdade, o preço de um varchar computacionalmente é provavelmente uma vitória líquida sobre a quantidade de espaço em disco economizado usando campos de comprimento variável em vez de campos de comprimento fixo. Provavelmente, você tem maior densidade de linha.
Agora, a complexidade dos campos varchar é que você não pode localizar facilmente um registro por meio de seu número de registro. Quando você tem um tamanho de linha de comprimento fixo (com campos de comprimento fixo), é trivial calcular o bloco de disco para o qual um id de linha aponta. Com um tamanho de linha de comprimento variável, isso sai pela janela.
Então, agora você precisa manter algum tipo de índice de número de registro, assim como qualquer outra chave primária, OU você precisa fazer um identificador de linha robusto que codifica detalhes (como o bloco, etc.) no identificador. Se você fizer isso, porém, o id terá que ser recalculado se alguma vez a linha for movida no armazenamento persistente. Não é grande coisa, basta reescrever todas as entradas do índice e certificar-se de que você a) nunca o exponha ao consumidor ou b) nunca afirme que o número é confiável.
Mas, como temos campos varchar hoje, o único valor de varchar (16) sobre varchar (255) é que o banco de dados aplicará o limite de 16 caracteres no varchar (16). Se o modelo de banco de dados deve ser realmente representativo do modelo de dados físico, ter comprimentos de campos pode ser valioso. Se, no entanto, for simplesmente "armazenamento" em vez de um "modelo E armazenamento", não há necessidade de qualquer coisa.
Em seguida, você simplesmente precisa discernir entre um campo de texto que é indexável (como varchar) e algo que não é (como um campo de texto ou CLOB). Os campos indexáveis tendem a ter um limite de tamanho para facilitar o índice, enquanto os campos CLOB não (dentro do razoável).
fonte
Na minha experiência, se você permitir um tipo de dados de 255 caracteres, algum usuário estúpido (ou algum testador experiente) vai realmente preencher isso.
Então você terá todos os tipos de problemas, incluindo quanto espaço você permite para esses campos em relatórios e exibições na tela em seu aplicativo. Sem falar na possibilidade de exceder o limite por linha de dados em seu banco de dados (se você tivesse mais do que alguns desses campos de 255 caracteres).
É muito mais fácil escolher um limite razoável no início, depois aplicá-lo por meio do aplicativo e do banco de dados.
fonte
É uma boa prática alocar apenas um pouco além do que você precisa. Os números de telefone nunca seriam tão grandes.
Um dos motivos é que, a menos que você valide entradas grandes, sem dúvida alguém usará tudo o que existe. Então você pode ficar sem espaço em sua linha. Não tenho certeza sobre o limite do MySQL, mas 8060 é o tamanho máximo de linhas no MS SQL.
Um padrão mais normal seria 50 imho e, em seguida, aumentaria quando necessário.
fonte
Em um contexto mysql, pode ser importante ao trabalhar com índices nas colunas varchar ditas, pois mysql tem um máximo. limite de 767 bytes por linha de índice.
Isso significa que ao adicionar um índice em várias colunas varchar 255 você pode chegar a este limite rapidamente / ainda mais rápido nas colunas utf8 ou utf8mb4 como apontado nas respostas acima
fonte