Eu entendo que um endereço de e-mail 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 uma razão 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/compensações significativas de desempenho que fazem com que tantas implementações usem menos do que os 254 caracteres possíveis?
Eu sempre usei
varchar(320)
, mas na verdade provavelmente deveria servarchar(319)
. Aqui está o porquê. A norma impõe as seguintes limitações:@
símbolo.<
colchetes angulares potenciais ao redor>
).Agora, algumas pessoas dirão que você precisa apoiar mais do que isso. Algumas pessoas também dirão que você precisa oferecer suporte a Unicode para nomes de domínio (o que significa que você precisa mudar para
nvarchar
). Embora o padrão possa mudar nesse meio tempo (já faz um tempo desde que tive skin no jogo), estou bastante confiante de que, neste momento, a maioria dos servidores do mundo não aceitará endereços de e-mail Unicode, e tenho certeza muitos servidores terão problemas para criar e/ou aceitar endereços com > 319 caracteres (e possivelmente > 254/255/256). Um limite superior razoável deve ser algo como 128 caracteres porque, na verdade, endereços de e-amil mais longos do que isso simplesmente não são práticos, mesmo que sejam automatizados fora de algum serviço.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 superior, você se beneficiará da compactação Unicode, o que significa que você paga apenas a penalidade de 2 bytes para caracteres que realmente precisam isto). Dessa forma, você pode tornar sua coluna tão grande quanto quiser, e você pode permitir que as pessoas coloquem qualquer lixo muito longo que quiserem - eles não receberão um e-mail se derem lixo, assim como não receberão receber um e-mail se a inserção falhar. O problema é que se você deixar lixo inválido entrar, vocêtem que lidar com isso. E não importa o tamanho que você fizer - se alguém tentar colocar 400 caracteres em uma coluna de 319 caracteres, alguém tentará colocar 1025 caracteres em uma coluna de 1024 caracteres. Não há motivo para qualquer pessoa sensata ter um endereço de e-mail > 319 caracteres, a menos que o esteja usando para testar explicitamente os limites do sistema.
Mas acho que precisamos parar de pedir opiniões sobre isso - e parar de olhar para outras implementações para orientação (acontece neste caso que aqueles que você mencionou não se preocuparam em fazer sua própria lição de casa e apenas escolheram números de seus, bem, você sabe). Você tem acesso direto ao padrão - certifique-se de consultar a versão mais atual, suporte isso no mínimo e fique no topo do padrão para que possa se adaptar às mudanças nas especificações.
EDIT obrigado a @ypercube pelo ping no chat.
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.com
15 milhões de vezes quando um int FK 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, como[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.Falei um pouco sobre isso aqui:
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
Domains
tabela que tem uma restrição artificialmente menor de comprimento para endereços de e-mail, quando o domínio pode ser reutilizado como um URL válido de 255 caracteres?EDIT Houve um comentário:
Embora eu concorde que existem casos de uso para colunas de string "ilimitadas", este não é um deles. Quando você conhece o domínio de dados de padrões bem estabelecidos, você deve usá-los. O link fala sobre como , se você escolher mal , isso pode levar a erros para os usuários finais. E daí? Não há razão para permitir que as pessoas insiram valores fora do domínio (por exemplo, um endereço de e-mail com 600 milhões de caracteres) apenas para que não recebam um erro ao fazê-lo. Na verdade, eu argumentaria que o e-mail é precisamente o tipo de contra-exemplo sobre o qual o link fala.
Definir a coluna corretamente, pelo menos no SQL Server, significa que você não sofrerá com as penalidades de desempenho documentadas de
max
tipos ou memória desperdiçada devido avarchar/nvarchar
declarações muito amplas . Embora empregar uma restrição de verificação para limitar o comprimento torne mais fácil ajustar o comprimento máximo em qualquer direção posteriormente, isso não parece ter nenhum outro benefício em relação à definição de coluna adequada (o usuário recebe um erro de qualquer maneira).Há algumas considerações com esta decisão. O primeiro e mais importante é usar as previsões atuais e futuras das limitações necessárias às quais os dados terão que estar em conformidade. Há uma razão pela qual você não deseja definir todos os tipos de dados de coluna de string para
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 os e-mails são todos modificados para se tornarem 255 caracteres, poderá ter um impacto de longo desempenho nas divisões de página. Isso pode parecer fora do comum, e provavelmente é, mas você precisa dimensionar seus dados de acordo com os requisitos de negócios . Assim como a antiga restrição no debate banco de dados versus aplicativo, acredito firmemente que as limitações de tipo de dados e 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 pode inserir apenas 80 caracteres para um endereço de e-mail, por que deseja que o tipo de dados seja maior? A empresa precisa responder a duas perguntas:
Só assim você terá sua resposta.
Sim e não. Haverá uma espécie de deslocamento para os dados de comprimento variável para registrar o comprimento deles.
RFC 5321 (a especificação SMTP atual, obsoleta RFC2821) afirma:
Portanto, 64 + 255 + sinal @ implica VARCHAR(320). Você provavelmente nunca precisará de tanto, mas é seguro tê-lo, apenas no caso.
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, digamosvarchar(320)
, essa alteração deve ser uma operação trivial no servidor de banco de dados - dependendo, é claro, do produto do banco de dados.Segundo, dependendo do tamanho médio da linha e do tamanho da página, usar
varchar(320)
em vez devarchar(240)
pode não alterar o número de páginas alocadas (o espaço em disco realmente ocupado pela tabela).Terceiro, alguém acima falou sobre validar um endereço de e-mail. Eu afirmo que há apenas uma maneira segura de validar um endereço de e-mail e que é enviar um e-mail para ele. :-)
Qualquer variação de VARCHAR usa 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 o comprimento de uma coluna VARCHAR é realmente um "comprimento máximo", ele deve ser definido como maior que o comprimento máximo possível em qualquer circunstância. Apenas o espaço necessário para cada linha será usado. Os programas de aplicativos devem ser projetados com campos de rolagem ou o que fizer sentido com base em valores típicos.
Um projeto de banco de dados é como um pedaço de papel físico, pois define os limites rígidos quanto ao tamanho. Uma página de papel não pode ser ampliada. Nesta analogia, o programa aplicativo é como um formulário impresso na página. Há muito que pode ser feito para ajustar a quantidade de dados que podemos armazenar no formulário.
Embora o comando para aumentar o tamanho de um VARCHAR possa parecer simples e ser executado instantaneamente em uma tabela pequena, fazê-lo em uma tabela com milhares de linhas ou mais provavelmente exigirá algum tipo de quiesce de banco de dados enquanto regenera todos os dados e blocos de índice. Uma maneira é copiar tudo para uma nova tabela com as colunas maiores. Qualquer que seja a técnica usada, é um grande problema. Assim, você deve considerar o tamanho da coluna VARCHAR amplamente imutável quando uma tabela de produção for carregada.
VARCHAR é o melhor tipo de dados a ser usado para endereços de e-mail, pois os e-mails variam muito em tamanho. NVARCHAR também é uma alternativa, mas eu recomendaria usar apenas se o endereço de email contiver caracteres estendidos e lembre-se de que requer o dobro de espaço de armazenamento em comparação com VARCHAR.
No meu ambiente, usamos varchar(70), pois os mais longos que encontrei têm cerca de 60 a 70 caracteres, mas também depende da base de clientes da sua empresa. Além disso, como uma observação lateral, certifique-se de ter alguma verificação de validação de e-mail no local para a validade dos endereços de e-mail, como usar restrições de verificação ou CHARINDEX
Usando SQL
DOMAIN
Se você estiver usando um servidor Enterprise Database, deve haver alguma maneira de armazenar um endereço de e-mail
DOMAIN
com algum nível de validade. Os domínios são especificados na especificação SQLPor exemplo, o PostgreSQL gratuito e de código aberto suporta isso, exceto quaisquer limitações em sua implementação da especificação, a própria coluna contém um email válido. Você pode por exemplo..
DOMAIN
sobre a especificação HTML5 de e-mail.DOMAIN
que verifique o servidor em busca de um registro MX no momento da verificação.Eu avalio essas opções nesta resposta que é específica do PostgreSQL