Em que tipo de dados devo armazenar um endereço de email no banco de dados?

44

Entendo que um endereço de email de 254 caracteres é válido, mas as implementações que pesquisei tendem a usar um varchar (60) para varchar (80) ou equivalente. Por exemplo: esta recomendação do SQL Server usa varchar (80) ou este exemplo do Oracle

Existe um motivo para não usar o máximo de 254 caracteres? Um varchar por definição não usa apenas o armazenamento necessário para armazenar os dados?

Existem implicações / trocas significativas de desempenho que fazem com que tantas implementações usem menos do que os 254 caracteres possíveis?

Thronk
fonte

Respostas:

45

Eu sempre usei VARCHAR(320). Aqui está o porquê. O padrão determina as seguintes limitações:

  • 64 caracteres para a "parte local" (nome de usuário).
  • 1 caractere para o @símbolo.
  • 255 caracteres para o nome do domínio.

Agora, algumas pessoas dirão que você precisa apoiar mais do que isso. Algumas pessoas também dizem que você precisa dar suporte ao Unicode para nomes de domínio (o que significa que você precisa mudar para NVARCHAR). Enquanto o padrão pode mudar nesse meio tempo (já faz um tempo desde que eu participei do jogo), estou bastante confiante de que, no momento, a maioria dos servidores no mundo não aceita endereços de email Unicode e tenho certeza muitos servidores terão problemas ao criar e / ou aceitar endereços com> 320 caracteres.

Dito isso, você pode se preparar para o pior agora, se quiser (e se estiver usando a compactação de dados no SQL Server 2008 R2 ou melhor, você se beneficiará da compactação Unicode, o que significa que você paga apenas a penalidade de 2 bytes pelos caracteres que realmente precisam isto). Dessa forma, você pode tornar sua coluna a largura que desejar e permitir que as pessoas coloquem lá o lixo que desejarem por muito tempo - elas não receberão um e-mail se lhe derem lixo da mesma maneira que não querem receber um email se a inserção falhar. O problema é se você deixar lixo inválida no, vocêtem que lidar com isso. E não importa o tamanho que você escolher - se alguém tentar inserir 400 caracteres em uma coluna de 320 caracteres, alguém tentará inserir 1025 caracteres em uma coluna de 1024 caracteres. Não há razão para que qualquer pessoa sensata tenha um endereço de e-mail com mais de 320 caracteres, a menos que esteja usando-o para testar explicitamente os limites do sistema.

Mas pare de pedir opiniões sobre isso - e pare de procurar outras implementações para obter orientação (neste caso, as que você referenciou não se deram ao trabalho de fazer sua própria lição de casa e apenas escolheram números de suas, bem, você sabe) . Você tem acesso direto ao padrão - consulte a versão mais atual, suporte-a no mínimo e fique por dentro do padrão para poder se adaptar às alterações nas especificações.


EDIT graças a @ypercube pelo ping no bate-papo.

Como um aparte, talvez você não queira despejar o endereço inteiro em uma única coluna em primeiro lugar. A normalização pode sugerir que você não deseja armazenar @hotmail.com15 milhões de vezes quando um FK int muito mais fino funcionaria bem e não teria a sobrecarga adicional de colunas de comprimento variável. Você também pode normalizar o nome de usuário [email protected]e [email protected]compartilhar um nome de usuário comum - eles não se conhecem, mas seu banco de dados não se importa com isso.

Eu falei sobre isso aqui:

http://www.mssqltips.com/sqlservertip/2657/storing-email-addresses-more-efficiently-in-sql-server/

http://www.mssqltips.com/sqlservertip/2671/storing-email-addresses-more-efficiently-in-sql-server--part-2/

No entanto, isso apresenta desafios ao limite de 254 caracteres acima, pois não parece haver consenso sobre o que acontece quando um domínio válido de 255 caracteres é combinado com uma parte local válida de 1 caractere. Isso deve ser aceito pela maioria dos servidores em todo o mundo, mas parece violar esse limite de 254 caracteres. Então, você cria uma Domainstabela que possui uma restrição artificialmente menor no tamanho dos endereços de email, quando o domínio pode ser reutilizado como um URL válido de 255 caracteres?

Aaron Bertrand
fonte
Eu gosto dessa abordagem, mas e a exclusividade do email? Como é gerenciado?
Roberto Rizzi
2
@RobertoRizzi Uma restrição exclusiva ou chave primária na combinação de DomainID + LocalPart ou vice-versa.
Aaron Bertrand
5

Existem algumas considerações com esta decisão. Primeiro e acima de tudo, é usar previsões atuais e futuras das limitações necessárias às quais os dados deverão estar em conformidade. Há uma razão pela qual você não deseja definir todos os tipos de dados da coluna de string varchar(1024)quando estiver apenas armazenando uma string que não deve exceder 32 caracteres (ênfase na palavra - chave should ).

Se você tiver algum tipo de vulnerabilidade em que todos os emails são modificados para se tornarem 255 caracteres, é possível que tenha um longo impacto no desempenho das divisões de página. Isso pode parecer fora do comum, e provavelmente é, mas você precisa dimensionar seus dados de acordo com os requisitos comerciais . Assim como a restrição antiga no banco de dados versus o debate sobre aplicativos, acredito firmemente que as limitações de tipo de dados e os valores permitidos também devem ser aplicados na camada de dados.

O que me leva ao meu próximo ponto. O banco de dados provavelmente é apenas a camada de dados. O que a camada de aplicativo utiliza? Por exemplo, se você tem um aplicativo em que só pode inserir 80 caracteres para um endereço de email, por que deseja que o tipo de dados seja maior? As empresas precisam responder a duas perguntas:

  1. O que pode ser isso?
  2. O que deveria ser?

Só então você terá sua resposta.

Um varchar por definição não usa apenas o armazenamento necessário para armazenar os dados?

Sim e não. Haverá uma espécie de deslocamento para os dados de comprimento variável para registrar o comprimento deles.

Thomas Stringer
fonte
3

A RFC 5321 (a atual especificação SMTP, obsoleta a RFC2821) afirma:

O comprimento total máximo de um nome de usuário ou outra parte local é de 64 octetos. O comprimento total máximo de um nome de domínio ou número é de 255 octetos

Portanto, o sinal 64 + 255 + @ implica VARCHAR (320). Você provavelmente nunca precisará tanto, mas é seguro tê-lo, apenas por precaução.

avakharia
fonte
4
O limite correto é 254. rfc-editor.org/errata_search.php?rfc=3696&eid=1690
Neil McGuigan
1

Qualquer variação do VARCHAR utiliza apenas o espaço necessário no bloco de dados. Os bytes adicionais para armazenar o comprimento são triviais em comparação com o espaço que seria desperdiçado usando um CHAR de comprimento fixo.

Como um comprimento de coluna VARCHAR é realmente um "comprimento máximo", ele deve ser definido como maior que o comprimento máximo possível em qualquer circunstância. Somente o espaço necessário para cada linha será usado. Os programas aplicativos devem ser projetados com campos de rolagem ou o que fizer sentido com base em valores típicos.

Um design de banco de dados é como um pedaço de papel físico, pois define os limites rígidos quanto ao tamanho. Uma página em papel não pode ser ampliada. Nesta analogia, o programa aplicativo é como um formulário impresso na página. Muito pode ser feito para ajustar a quantidade de dados que podemos armazenar no formulário.

Embora o comando para aumentar o tamanho do VARCHAR possa parecer simples e executado instantaneamente em uma tabela pequena, fazê-lo em uma tabela com milhares de linhas ou mais provavelmente exigirá algum tipo de inatividade do banco de dados ao regenerar todos os blocos de dados e índices. Uma maneira é copiar tudo para uma nova tabela com as colunas maiores. Qualquer que seja a técnica usada, é um negócio muito cabeludo. Portanto, você deve considerar o tamanho da coluna VARCHAR amplamente imutável quando uma tabela de produção é carregada.

DocSalvager
fonte
1

Como um comentário para as excelentes respostas já aqui:

Primeiro, se você criou o campo como varchar(240)e deseja alterá-lo posteriormente para um campo mais longo, digamos varchar(320), essa alteração deve ser uma operação trivial no servidor de banco de dados - dependendo, é claro, do seu produto de banco de dados.

alter table Schema.Object alter column EmailAddress varchar(320) ;

Segundo, dependendo do tamanho médio da linha e do tamanho da página, usar em varchar(320)vez de varchar(240)pode não alterar o número de páginas alocadas (o espaço em disco ocupado pela tabela).

Terceiro, alguém acima falou sobre a validação de um endereço de email. Eu afirmo que existe apenas uma maneira segura de validar um endereço de email e que é enviar um email para ele. :-)

Andarilho de Pedra Verde
fonte
0

VARCHAR é o melhor tipo de dados a ser usado para endereços de email, pois os emails variam muito em tamanho. O NVARCHAR também é uma alternativa, mas eu recomendaria usá-lo apenas se o endereço de e-mail contiver caracteres estendidos e lembre-se de que exige uma quantidade dupla de espaço de armazenamento em comparação com o VARCHAR.

No meu ambiente, usamos varchar (70), pois os mais longos que encontrei têm aproximadamente 60 a 70 caracteres, mas isso também depende da base de clientes da sua empresa. Além disso, como nota lateral, verifique se há alguma verificação de validação de email em vigor para a validade dos endereços de email. Como usar restrições de verificação ou CHARINDEX

Kin Shah
fonte
0

Usando SQL DOMAIN

Se você estiver usando um servidor de banco de dados corporativo, deve haver alguma maneira de armazenar um endereço de email como um DOMAINcom algum nível de validade. Os domínios são especificados na especificação SQL

Um domínio é um objeto definido pelo usuário nomeado que pode ser especificado como uma alternativa a um tipo de dados em determinados locais onde um tipo de dados pode ser especificado. Um domínio consiste em um tipo de dados, possivelmente uma opção padrão, e zero ou mais restrições (domínio).

Por exemplo, o PostgreSQL de código aberto e gratuito suporta isso, exceto quaisquer limitações na implementação da especificação, a própria coluna contém um email válido. Você pode por exemplo ..

  • Crie um personalizado DOMAINsobre as especificações de email do HTML5.
  • Ou, nas especificações de e-mail RFC822, RFC2822, RFC5322.
  • Crie um costume DOMAINque verifique se há um registro MX no servidor no momento da verificação.

Eu avalio essas opções nesta resposta, que é específica do PostgreSQL

Evan Carroll
fonte