Melhor tipo de campo de banco de dados para um URL

352

Eu preciso armazenar um URL em uma tabela MySQL. Qual é a melhor prática para definir um campo que conterá um URL com um comprimento indeterminado?

Jesse Hattabaugh
fonte
11
Depende do que você precisa, indexação, unicidade?
Thomas Decaux
2
Eu esperava uma resposta bastante direta aqui, mas fiquei bastante surpreso com as respostas que cobriam itens que não havia considerado. Leitura muito interessante que adicionei à minha conta educacional.
HPWD 16/07/19
11
Basta ir com o TEXTtipo e pular a leitura de todas essas respostas abaixo. No final, é o que a maioria deles sugere. :) Obviamente, se você precisar de indexação ou exclusividade, vá em frente VARCHAR, pois TEXTnão pode ser indexado tão facilmente .
Aleksandar

Respostas:

324
  1. Menor comprimento máximo de URL do denominador comum entre os navegadores populares: 2.083 (Internet Explorer)

  2. http://dev.mysql.com/doc/refman/5.0/en/char.html Os
    valores nas colunas VARCHAR são cadeias de comprimento variável. O comprimento pode ser especificado como um valor de 0 a 255 antes do MySQL 5.0.3 e de 0 a 65.535 na 5.0.3 e versões posteriores. O comprimento máximo efetivo de um VARCHAR no MySQL 5.0.3 e posterior está sujeito ao tamanho máximo da linha (65.535 bytes, que é compartilhado entre todas as colunas) e ao conjunto de caracteres usado.

  3. Então ...
    <MySQL 5.0.3 usa TEXT
    ou
    > = MySQL 5.0.3 usa VARCHAR (2083)

micahwittman
fonte
14
Boa resposta, mas pessoalmente eu limitaria o comprimento. Dependendo do projeto, você pode querer limitar os URLs aceitos. Quem usa url longet que 200?
John
2
É melhor que eles inventem um tipo de dados uri que "entenda" a estrutura do uri, para que a indexação e a pesquisa sejam feitas de forma eficiente, como a Oracle fez ... espere, o mysql agora é da Oracle ... download.oracle.com/docs/ cd / B10464_05 / web.904 / b12099 /…
redben 26/03
80
Essa resposta é um pouco enganadora. Observe que "Menor denominador comum" aqui não faz sentido; você deseja usar o número mais alto que um navegador ou servidor aceitará (o que não é consistente e está sujeito a alterações). Como o seu link diz: " ... a especificação do protocolo HTTP não especifica nenhum comprimento máximo ... ", então não se preocupe com isso VARCHAR(2083), basta usar TEXT.
Wesley Murch
4
Exemplo, também no seu link: " Após 65.536 caracteres, a barra de localização não exibe mais o URL no Windows Firefox 1.5.x. No entanto, URLs mais longos funcionarão. Parei de testar após 100.000 caracteres. "
Wesley Murch
11
O recurso boutell.com caiu da rede. Aqui está uma referência a ele em um livro digitalizado de O'Reilly: books.google.ca/… #
micahwittman
33

VARCHAR(512)(ou similar) deve ser suficiente. No entanto, como você realmente não sabe o tamanho máximo dos URLs em questão, talvez eu vá direto para TEXT. O perigo disso é, obviamente, a perda de eficiência devido ao fato de CLOBser muito mais lento do que um tipo de dados de string simples VARCHAR.

Daniel Spiewak
fonte
e o agrupamento?
kommradHomer
16

varchar(max) para SQLServer2005

varchar(65535) para MySQL 5.0.3 e posterior

Isso alocará o armazenamento conforme necessário e não deve afetar o desempenho.

Bob Probst
fonte
11
No seu snippet, é maxum especificador mágico ANSI SQL para aumentar o tamanho do VARCHAR conforme necessário, ou é apenas uma metavariável por uma questão de exemplo?
Daniel Spiewak 20/10/08
4
No MySQL, você provavelmente não pode ter um varchar tão grande, a menos que seja a única coluna da tabela.
Carson
11
@ Daniel Spiewak: "A diferença básica entre TEXT e VARCHAR (MAX) é que um tipo TEXT sempre armazena os dados em um blob, enquanto o tipo VARCHAR (MAX) tenta armazenar os dados diretamente na linha, a menos que exceda os 8 k limitação e nesse momento ele é armazenado em um blob ". stackoverflow.com/questions/834788/… Mas a pergunta era sobre o MySQL, então isso não é realmente relevante aqui.
Stijn Bollen
9

Você desejará escolher entre uma coluna TEXT ou VARCHAR com base na frequência com que o URL será usado e se você realmente precisa que o tamanho seja ilimitado.

Use VARCHAR com comprimento máximo > = 2,083, como micahwittman sugeriu se:

  1. Você usará muitos URLs por consulta (diferentemente das colunas TEXT, os VARCHARs são armazenados alinhados com a linha)
  2. Você tem certeza de que um URL nunca excederá o limite de linhas de 65.535 bytes.

Use TEXT se:

  1. O URL pode realmente quebrar o limite de linhas de 65.535 bytes
  2. Suas consultas não selecionam ou atualizam vários URLs de uma só vez (ou com muita frequência). Isso ocorre porque as colunas TEXT apenas mantêm um ponteiro embutido e os acessos aleatórios envolvidos na recuperação dos dados referenciados podem ser dolorosos.
mrgrieves
fonte
9

Você deve usar um VARCHAR com uma codificação de caracteres ASCII. Os URLs são codificados em porcentagem e os nomes de domínio internacionais usam o punycode, portanto o ASCII é suficiente para armazená-los. Isso usará muito menos espaço que o UTF8.

VARCHAR(512) CHARACTER SET 'ascii' COLLATE 'ascii_general_ci' NOT NULL
Flavio Tordini
fonte
5
o UTF-8 não usa mais espaço quando precisa apenas?
kommradHomer
7

Isso realmente depende do seu caso de uso (veja abaixo), mas o armazenamento TEXTé um problema de desempenho e, VARCHARna maioria dos casos, parece um exagero.

Minha abordagem: use um VARCHARtamanho generoso, mas não excessivamente grande , como VARCHAR(500)esse, e incentive os usuários que precisam de uma URL maior a usar um encurtador de URL como safe.mn.

A abordagem do Twitter: para um UX realmente bom, forneça um encurtador de URL automático para URLs muito longos e armazene a "versão de exibição" do link como um trecho da URL com elipses no final. (Exemplo: http://stackoverflow.com/q/219569/1235702seria exibido como stackoverflow.com/q/21956...e vincularia a um URL reduzido http://ex.ampl/e1234)

Notas e Advertências

  • Obviamente, a abordagem do Twitter é melhor, mas para as necessidades do meu aplicativo, a recomendação de um encurtador de URL foi suficiente.
  • Os encurtadores de URL têm suas desvantagens, como preocupações de segurança. No meu caso, não é um risco enorme, porque os URLs não são públicos e não são muito usados; no entanto, isso obviamente não funcionará para todos. O safe.mn parece bloquear muitos URLs de spam e phishing, mas eu ainda recomendaria cautela.
  • Observe que você não deve forçar seus usuários a usar um encurtador de URL. Na maioria dos casos (pelo menos para as necessidades do meu aplicativo), 500 caracteres são excessivamente suficientes para o que a maioria dos usuários o usará. Use / recomende apenas um encurtador de URL para links muito longos.
brokethebuildagain
fonte
10
Se você estiver fornecendo um encurtador de URL interno, ainda não precisará armazenar o URL completo em um banco de dados em algum lugar para que ele funcione? :-)
Neil Neyman
2
Claro; mas duvido que a maioria das pessoas escreva seu próprio encurtador. Desde que escrevi isso, aprendi que existem muitas APIs de encurtamento de URL por aí (71 estão listadas aqui: programmableweb.com/news/… ), para que você possa automatizar o processo sem nem mesmo escrever o seu. Ainda depende do conhecimento e consentimento do usuário, é claro.
brokethebuildagain
1

A maioria dos servidores da Web possui um limite de tamanho de URL (é por isso que existe um código de erro para "URI muito longo"), o que significa que existe um tamanho superior prático. Encontre o limite de tamanho padrão para os servidores Web mais populares e use o maior deles como tamanho máximo do campo; deveria ser mais que suficiente.

CesarB
fonte
1

É melhor usar varchar (max), o que (em termos de tamanho) significa varchar (65535). Isso ainda armazena seus endereços da Web maiores e economiza seu espaço também.

O especificador max expande os recursos de armazenamento dos tipos de dados varchar, nvarchar e varbinary. varchar (max), nvarchar (max) e varbinary (max) são chamados coletivamente de tipos de dados de grande valor. Você pode usar os tipos de dados de grande valor para armazenar até 2 ^ 31-1 bytes de dados.

Consulte este artigo no TechNet sobre o uso de tipos de dados de grande valor

sohaiby
fonte
varchar (max)é a sintaxe SQLServer, não adequada para MySQL (como na pergunta original). Além disso, isso não significa varchar (65535)que 65535 é o número máximo de caracteres ASCII seguidos no mysql, portanto depende também dos outros campos e do conjunto de caracteres.
Furin