web-dev-qa-db-fra.com

Dans quel type de données dois-je stocker une adresse e-mail dans la base de données?

Je comprends qu'une adresse e-mail de 254 caractères est valide, mais les implémentations que j'ai recherchées ont tendance à utiliser un varchar (60) à varchar (80) ou équivalent. Par exemple: cette recommandation SQL Server utilise varchar (80) ou cet exemple Oracle

Y a-t-il une raison pour ne pas utiliser le maximum de 254 caractères maximum? Un varchar, par définition, n'utilise-t-il pas autant de stockage que nécessaire pour contenir les données?

Y a-t-il des implications/compromis significatifs en termes de performances qui font que tant d'implémentations utilisent moins que les 254 caractères possibles?

47
Thronk

J'ai toujours utilisé VARCHAR(320). Voici pourquoi. La norme impose les limitations suivantes:

  • 64 caractères pour la "partie locale" (nom d'utilisateur).
  • 1 caractère pour le @ symbole.
  • 255 caractères pour le nom de domaine.

Maintenant, certaines personnes diront que vous devez soutenir plus que cela. Certaines personnes diront également que vous devez prendre en charge Unicode pour les noms de domaine (ce qui signifie que vous devez passer à NVARCHAR). Bien que la norme puisse changer entre-temps (cela fait un moment que je n'ai pas de skin dans le jeu), je suis assez confiant qu'à l'heure actuelle, la plupart des serveurs dans le monde n'accepteront pas les adresses e-mail Unicode, et je suis sûr de nombreux serveurs auront des problèmes pour créer et/ou accepter des adresses avec> 320 caractères.

Cela dit, vous pouvez vous préparer au pire maintenant, si vous le souhaitez (et si vous utilisez la compression de données dans SQL Server 2008 R2 ou mieux, vous bénéficierez de la compression Unicode, ce qui signifie que vous ne payez que la pénalité de 2 octets pour les caractères qui ont réellement besoin il). De cette façon, vous pouvez rendre votre colonne aussi large que vous le souhaitez, et vous pouvez laisser les gens y fourrer des ordures trop longues qu'ils veulent - ils ne recevront pas d'e-mail s'ils vous donnent des ordures comme ils ne le feront pas recevoir un e-mail si l'insertion échoue. Le problème est que si vous laissez des fichiers indésirables non valides, vous devez y faire face. Et quelle que soit la taille que vous créez - si quelqu'un essaie de mettre 400 caractères dans une colonne de 320 caractères, quelqu'un essaiera de mettre 1025 caractères dans une colonne de 1024 caractères. Il n'y a aucune raison pour qu'une personne sensée ait une adresse e-mail> 320 caractères à moins qu'elle ne l'utilise pour tester explicitement les limites du système.

Mais arrêtez de demander opinions à ce sujet - et arrêtez de regarder d'autres implémentations pour vous guider (il se trouve que dans ce cas, celles que vous avez mentionnées n'ont pas pris la peine de faire leurs propres devoirs et ont juste choisi des nombres hors de leur, eh bien, vous savez). Vous avez un accès direct à la norme - assurez-vous de consulter la version la plus récente, de la prendre en charge au minimum et de rester au top de la norme afin de vous adapter aux changements de spécifications.


[~ # ~] éditez [~ # ~] grâce à @ypercube pour le ping dans le chat.

En passant, vous ne voulez peut-être pas d'abord vider l'adresse entière dans une seule colonne. La normalisation peut suggérer que vous ne souhaitez pas stocker @hotmail.com 15 millions de fois où un FK int plus fin fonctionnerait très bien et n'aurait pas la surcharge supplémentaire des colonnes de longueur variable. Vous pouvez également normaliser le nom d'utilisateur, comme [email protected] et [email protected] partagent un nom d'utilisateur commun - ils ne se connaissent pas mais votre base de données s'en fiche.

J'en ai parlé ici:

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/

Cela introduit cependant des défis pour la limite de 254 caractères ci-dessus, car il ne semble pas y avoir de consensus sur ce qui se passe lorsqu'un domaine de 255 caractères valide est combiné avec une partie locale de 1 caractère valide. Cela devrait être accepté par la plupart des serveurs à travers le monde mais semble violer cette limite de 254 caractères. Créez donc une table Domains qui a une restriction artificiellement inférieure sur la longueur des adresses e-mail, lorsque le domaine pourrait être réutilisé comme URL valide de 255 caractères ?

49
Aaron Bertrand

Il y a quelques considérations avec cette décision. Il s'agit avant tout d'utiliser les prévisions actuelles et futures des limitations nécessaires auxquelles les données devront se conformer. Il y a une raison pour laquelle vous ne voulez pas définir chaque type de données de colonne de chaîne sur varchar(1024) lorsque vous stockez simplement une chaîne que ne devrait pas dépasse 32 caractères (l'accent sur le mot-clé doit ).

Si vous avez une sorte de vulnérabilité dans laquelle les e-mails sont tous modifiés pour devenir 255 caractères, vous pouvez potentiellement avoir un impact long sur les performances des fractionnements de page. Cela peut sembler inhabituel, et c'est probablement le cas, mais vous devez dimensionner vos données en fonction des besoins de l'entreprise. Tout comme la contrainte séculaire du débat entre la base de données et les applications, je suis fermement convaincu que les limitations de type de données et les valeurs autorisées doivent également être appliquées au niveau des données.

Ce qui m'amène à mon prochain point. La base de données n'est probablement que le niveau de données. À quoi sert le niveau d'application? Par exemple, si vous avez une application où vous ne pouvez saisir que 80 caractères pour une adresse e-mail, pourquoi voudriez-vous que le type de données soit plus grand? Les entreprises doivent répondre à deux questions:

  1. Qu'est-ce que cela peut-il être?
  2. Quel devrait-il être?

Alors seulement, vous aurez votre réponse.

Un varchar, par définition, n'utilise-t-il pas autant de stockage que nécessaire pour contenir les données?

Oui et non. Il va y avoir une sorte de décalage pour les données de longueur variable pour en enregistrer la longueur.

5
Thomas Stringer

RFC 5321 (la spécification SMTP actuelle, obsolète RFC2821) indique:

La longueur totale maximale d'un nom d'utilisateur ou d'une autre partie locale est de 64 octets. La longueur totale maximale d'un nom de domaine ou d'un numéro est de 255 octets

Le signe 64 + 255 + @ implique donc VARCHAR (320). Vous n'en aurez probablement jamais besoin autant, mais il est sûr de l'avoir, juste au cas où.

3
avakharia

Toute variation de VARCHAR utilise uniquement autant d'espace dans le bloc de données que nécessaire. Les octets supplémentaires pour stocker la longueur sont triviaux par rapport à l'espace qui serait gaspillé en utilisant un CHAR de longueur fixe à la place.

Étant donné qu'une longueur de colonne VARCHAR est vraiment une "longueur maximale", elle doit être définie plus grande que la longueur maximale possible en toutes circonstances. Seul l'espace nécessaire à chaque ligne sera utilisé. Les programmes d'application doivent ensuite être conçus avec des champs de défilement ou tout ce qui a du sens sur la base de valeurs typiques.

Une conception de base de données est comme une feuille de papier physique en ce qu'elle définit les limites strictes de la taille. Une page papier ne peut pas être agrandie. Dans cette analogie, le programme d'application est comme un formulaire imprimé sur la page. Il y a beaucoup à faire pour ajuster la quantité de données que nous pouvons contenir dans le formulaire.

Bien que la commande pour augmenter une taille VARCHAR puisse sembler simple et s'exécuter instantanément sur une petite table, le faire sur une table avec des milliers de lignes ou plus va probablement nécessiter une sorte de mise au repos de la base de données lors de la régénération de toutes les données et des blocs d'index. Une façon consiste à tout copier dans un nouveau tableau avec les colonnes les plus grandes. Quelle que soit la technique utilisée, c'est un gros problème poilu. Par conséquent, vous devez considérer la taille de la colonne VARCHAR largement immuable une fois qu'une table de production est chargée.

1
DocSalvager

En commentaire des excellentes réponses déjà ici:

Tout d'abord, si vous avez créé le champ en tant que varchar(240) et que vous souhaitez le modifier ultérieurement en un champ plus long, par exemple varchar(320), cette modification doit être une opération triviale sur le serveur de base de données - selon , bien sûr, sur votre produit de base de données.

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

Deuxièmement, selon la taille moyenne des lignes et la taille de la page, l'utilisation de varchar(320) au lieu de varchar(240) peut ne pas modifier le nombre de pages allouées (l'espace disque réellement occupé par la table).

Troisièmement, quelqu'un ci-dessus a parlé de valider une adresse e-mail. Je soutiens qu'il n'y a qu'un seul moyen sûr de valider une adresse e-mail et c'est de lui envoyer un e-mail. :-)

1
Greenstone Walker

Utilisation de SQL DOMAIN

Si vous utilisez un serveur de base de données d'entreprise, il devrait y avoir un moyen de stocker une adresse e-mail en tant que DOMAIN avec un certain niveau de validité. Les domaines sont spécifiés dans la spécification SQL

Un domaine est un objet défini par l'utilisateur nommé qui peut être spécifié comme alternative à un type de données à certains endroits où un type de données peut être spécifié. Un domaine se compose d'un type de données, éventuellement une option par défaut, et de zéro ou plusieurs contraintes (domaine).

Par exemple, PostgreSQL gratuit et open source le supporte, sauf limitation dans votre implémentation de la spécification, la colonne elle-même contient un email valide. Vous pouvez par exemple ..

  • Créez un DOMAIN personnalisé sur la spécification HTML5 de l'e-mail.
  • Ou, sur les spécifications de courrier électronique RFC822, RFC2822, RFC5322.
  • Créez un DOMAIN personnalisé qui vérifie le serveur pour un enregistrement MX au moment de la vérification.

J'évalue ces options dans cette réponse qui est spécifique à PostgreSQL

0
Evan Carroll

VARCHAR est le meilleur type de données à utiliser pour les adresses e-mail, car les e-mails varient beaucoup en fonction de leur longueur. NVARCHAR est également une alternative, mais je recommanderais de l'utiliser uniquement si l'adresse e-mail contient des caractères étendus et gardez à l'esprit qu'elle nécessite une double quantité d'espace de stockage par rapport à VARCHAR.

Dans mon environnement, nous utilisons varchar (70) car les plus longues que j'ai rencontrées mesurent 60 à 70 caractères, mais cela dépend également de la clientèle de votre entreprise. En outre, en guise de remarque, assurez-vous que vous avez une vérification de validation des e-mails en place pour la validité des adresses e-mail. Comme l'utilisation des contraintes de vérification ou CHARINDEX

0
Kin Shah