Devo adicionar um limite arbitrário de comprimento às colunas VARCHAR?

35

De acordo com os documentos do PostgreSQL , não há diferença de desempenho entre VARCHAR, VARCHAR(n)e TEXT.

Devo adicionar um limite arbitrário de tamanho a uma coluna de nome ou endereço ?

Edit: Não é um idiota de:

Sei que o CHARtipo é uma relíquia do passado e estou interessado não apenas em desempenho, mas em outros prós e contras como Erwin, em sua resposta surpreendente.

Daniel Serodio
fonte

Respostas:

45

A resposta é não .
Não adicione um modificador de comprimento varcharse puder evitá-lo. Na maioria das vezes, você realmente não precisa de uma restrição de comprimento. Basta usar textpara todos os dados de caracteres. Faça isso varchar(sem modificador de comprimento) se precisar permanecer compatível com RDBMS que não possui text.

O desempenho é quase o mesmo - texté um pouco mais rápido em situações raras , e você salva os ciclos para verificar a duração.

Se você realmente precisa aplicar um tamanho máximo, ainda use texte adicione uma restrição de verificação para isso:

ALTER TABLE tbl ADD CONSTRAINT tbl_col_len CHECK (length(col) < 51);

Você pode modificar ou eliminar essa restrição a qualquer momento, sem precisar mexer na definição da tabela e em todos os objetos dependentes (visualizações, funções, chaves estrangeiras, ...)

Com modificadores de comprimento, você apenas encontra problemas como este ou isto ou isto ...

O PostgreSQL 9.1 introduziu um novo recurso para aliviar um pouco a dor. Cito as notas de lançamento aqui :

Permitir ALTER TABLE ... SET DATA TYPEevitar a reescrita da tabela nos casos apropriados (Noah Misch, Robert Haas)

Por exemplo, converter uma varcharcoluna em texto não requer mais uma reescrita da tabela. No entanto, aumentar a restrição de comprimento em uma varcharcoluna ainda requer uma reescrita da tabela.

Erwin Brandstetter
fonte
Eu acho que essa resposta seria muito melhor se fosse simplesmente "não, nunca adicione limites arbitrários a um banco de dados real". Sinto que muitas dessas respostas precisam de correções e mais informações, mas isso é totalmente fora de tópico e desviaria sua conclusão da qual concordo totalmente.
Evan Carroll
Sim, tudo baseado nas versões do Postgres anteriores a 9.1 - 6 anos atrás. Um pouco empoeirado até agora, mas o conselho básico ainda é bom.
Erwin Brandstetter 25/03
É uma boa ou má idéia adicionar uma restrição de verificação para cada coluna de texto com o objetivo de uma verificação de integridade e garantir que um erro no cliente não consuma todo o espaço em disco do banco de dados, inserindo um texto muito grande?
Code
@ Código: É uma opção viável. Se você tiver muitas colunas com a mesma restrição, considere domínios . Ou, varchar(n)afinal, por simplicidade - se as desvantagens normalmente não o afetam. (O limite não é arbitrário no seu caso, se você deseja aplicar um comprimento máximo real.)
Erwin Brandstetter
12

Se você vir o limite de comprimento como uma espécie de restrição de verificação para validar os dados, adicione sim. Na verdade, convém não usar uma definição de comprimento, mas uma restrição de verificação real, para acelerar a alteração do limite.

Para alterar (aumentar) um limite de comprimento, é necessário executar um ALTER TABLEque pode levar muito tempo para ser concluído (devido a uma possível reescrita da tabela) durante o qual é necessário um bloqueio exclusivo da tabela.

Alterar (eliminar e recriar) uma restrição de verificação é uma operação muito breve e requer apenas a leitura dos dados da tabela; ela não altera nenhuma linha. Portanto, isso será muito mais rápido (o que, por sua vez, significa que o bloqueio exclusivo da tabela será mantido por um período muito menor).

Durante a operação, não há diferença alguma entre a text, a varcharou uma varchar(5000)coluna.

um cavalo sem nome
fonte
por pura curiosidade, por que você acha que essa verificação de comprimento não pode ser feita em um aplicativo cliente enquanto captura dados?
PirateApp
4
@PirateApp: porque muitas vezes haverá mais de um aplicativo ou alguma fonte de dados externa (pense em importações de lotes noturnos). E quase sempre o banco de dados (e os dados) vivem mais de um aplicativo.
A_horse_with_no_name 13/03
2

A questão é especificamente se adicionar um limite arbitrário de comprimento às colunas VARCHAR?

Para isso, a resposta é simplesmente "não". Não há nada que possa justificar a adição de um limite arbitrário como você faria em bancos de dados inferiores que suportam varchar(max)ou usam convenções como varchar(255). No entanto, se a especificação abordar um limite, acho que a resposta se tornará muito mais complexa, especialmente nas versões modernas do PostgreSQL. E, por isso, eu me inclinaria para o SIM .

Na minha opinião, o limite é uma escolha sábia se a especificação exigir. Especialmente para cargas de trabalho mais razoáveis. Se por nenhum outro motivo, preservar os metadados.

Da minha resposta aqui, indexe o desempenho de CHAR vs VARCHAR (Postgres) , onde abordo o valor dos metadados.

Se eu encontrasse uma especificação que tivesse chaves de texto de comprimento variável significativas e que eu confiasse em ter um comprimento máximo constante, eu usaria varchartambém. No entanto, não consigo pensar em nada que se encaixe nesse critério.

Evan Carroll
fonte
1

Parece que pode haver alguma diferença de desempenho se VARCHARfor usado regularmente para armazenar seqüências de caracteres muito grandes, pois "seqüências longas são compactadas pelo sistema automaticamente" e "valores muito longos também são armazenados em tabelas em segundo plano". Teoricamente, isso significaria que um grande volume de solicitações para um campo de string muito longo seria mais lento do que para um campo de string curto. Você provavelmente nunca terá esse problema, já que nomes e endereços não serão muito longos.

No entanto, dependendo de como você estiver usando essas cadeias de caracteres fora do banco de dados, convém adicionar um limite prático para impedir o abuso do sistema. Por exemplo, se você estiver exibindo o nome e o endereço em um formulário em algum lugar, talvez não seja possível exibir um parágrafo inteiro do texto no campo "nome"; portanto, faria sentido limitar a coluna de nome a algo como 500 personagens.

Edward
fonte
1
AFAIK não há diferença nos campos varchar e texto do TOASTing.
Dezso
VARCHARé açúcar puramente sintático TEXTno Postgres, não há diferença nenhuma no manuseio de armazenamento; o armazenamento da tabela de compactação versus plano de fundo mencionado é feito com base no comprimento real dos dados na coluna e não nos metadados da coluna. As colunas TEXT são armazenadas internamente como uma varlenaestrutura C (que é uma matriz de comprimento variável com os primeiros 4 bytes armazenando o comprimento na criação / atualização) e é essa estrutura que é otimizada com base no seu comprimento.
cowbert