AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 37014
Accepted
Thronk
Thronk
Asked: 2013-03-20 06:30:10 +0800 CST2013-03-20 06:30:10 +0800 CST 2013-03-20 06:30:10 +0800 CST

Em que tipo de dados devo armazenar um endereço de e-mail no banco de dados?

  • 772

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?

database-design datatypes
  • 7 7 respostas
  • 178261 Views

7 respostas

  • Voted
  1. Best Answer
    Aaron Bertrand
    2013-03-20T06:59:27+08:002013-03-20T06:59:27+08:00

    Eu sempre usei varchar(320), mas na verdade provavelmente deveria ser varchar(319). Aqui está o porquê. A norma impõe as seguintes limitações:

    • 64 caracteres para a "parte local" (nome de usuário).
    • 1 caractere para o @símbolo.
    • 254 caracteres para o nome de domínio (sempre acreditei em 255, mas estava errado de acordo com esta errata - na verdade são 256 menos os <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.com15 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:

    • Armazenando endereços de e-mail com mais eficiência no SQL Server
    • Armazenando endereços de email com mais eficiência no SQL Server - Parte 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 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:

    queria adicionar isso para postgres, não use varchar(n) wiki.postgresql.org/wiki/…

    talvez você possa usar uma restrição de verificação na coluna de email

    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 maxtipos ou memória desperdiçada devido a varchar/nvarchardeclaraçõ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).

    • 57
  2. Thomas Stringer
    2013-03-20T06:45:45+08:002013-03-20T06:45:45+08:00

    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:

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

    Só assim 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.

    • 7
  3. avakharia
    2013-03-20T06:58:57+08:002013-03-20T06:58:57+08:00

    RFC 5321 (a especificação SMTP atual, obsoleta 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, 64 + 255 + sinal @ implica VARCHAR(320). Você provavelmente nunca precisará de tanto, mas é seguro tê-lo, apenas no caso.

    • 5
  4. Greenstone Walker
    2013-03-20T22:46:31+08:002013-03-20T22:46:31+08:00

    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 produto do 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 varchar(320)em vez de varchar(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. :-)

    • 3
  5. DocSalvager
    2013-03-28T00:59:05+08:002013-03-28T00:59:05+08:00

    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.

    • 2
  6. Kin Shah
    2013-03-20T06:47:17+08:002013-03-20T06:47:17+08:00

    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

    • 1
  7. Evan Carroll
    2017-03-03T08:21:41+08:002017-03-03T08:21:41+08:00

    Usando SQLDOMAIN

    Se você estiver usando um servidor Enterprise Database, deve haver alguma maneira de armazenar um endereço de e-mail 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 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..

    • Crie um personalizado DOMAINsobre a especificação HTML5 de e-mail.
    • Ou, sobre as especificações de e-mail RFC822, RFC2822, RFC5322.
    • Crie um personalizado DOMAINque 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

    • 1

relate perguntas

  • Qual é a diferença entre os tipos de dados MySQL VARCHAR e TEXT?

  • INT(5) vs SMALLINT(5): números entre parênteses após o tipo numérico

  • É melhor armazenar os valores calculados ou recalculá-los a pedido? [duplicado]

  • Armazenar vs calcular valores agregados

  • Quais são algumas maneiras de implementar um relacionamento muitos-para-muitos em um data warehouse?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Conceder acesso a todas as tabelas para um usuário

    • 5 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    pedrosanta Listar os privilégios do banco de dados usando o psql 2011-08-04 11:01:21 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve