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


44

Je comprends qu’une adresse électronique de 254 caractères est valide, mais les applications que j’ai étudiées ont tendance à utiliser varchar (60) à varchar (80) ou l’é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? Un varchar, par définition, n’utilise-t-il pas la quantité de mémoire nécessaire pour stocker les données?

Existe-t-il des implications / compromis importants en termes de performances qui font que de nombreuses implémentations utilisent moins que les 254 caractères possibles?

Réponses:


45

J'ai toujours utilisé VARCHAR(320). Voici pourquoi. La norme dicte 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 davantage que cela. Certaines personnes diront également que vous devez prendre en charge Unicode pour les noms de domaine (ce qui signifie que vous devez basculer vers NVARCHAR). Bien que la norme puisse changer entre-temps (cela fait un moment que je n'ai plus de skin dans le jeu), je suis assez confiant pour le moment. La plupart des serveurs dans le monde n'accepteront pas les adresses de messagerie Unicode. de nombreux serveurs auront des problèmes pour créer et / ou accepter des adresses avec plus de 320 caractères.

Cela dit, vous pouvez vous préparer au pire maintenant (et si vous utilisez la compression de données dans SQL Server 2008 R2 ou une version supérieure, 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 en ont réellement besoin. il). De cette façon, vous pouvez créer une colonne aussi large que vous le souhaitez et laisser les gens y insérer les fichiers inutiles: ils ne recevront pas d'e-mail s'ils vous envoient des messages tout comme ils ne le feront pas. recevoir un e-mail si l'insertion échoue. Le problème, c’est que si vous laissiez entrer des fichiers non valides, vousavoir à faire avec. Et quelle que soit la taille de votre choix - si quelqu'un essaie de placer 400 caractères dans une colonne de 320 caractères, il essaiera de placer 1025 caractères dans une colonne de 1024 caractères. Il n’ya aucune raison pour que toute personne sensée ait une adresse électronique> 320 caractères à moins de l’utiliser pour tester explicitement les limites du système.

Mais arrêtez de demander des avis à ce sujet - et arrêtez de regarder les autres implémentations pour vous guider (il se trouve que dans ce cas, celles que vous avez mentionnées ne se donnaient pas la peine de faire leurs propres devoirs et choisissaient juste des chiffres, eh bien, vous savez) . Vous avez un accès direct à la norme - veillez à consulter la version la plus récente, à la gérer au minimum, et à rester au-dessus de la norme pour pouvoir vous adapter aux modifications de spécifications.


EDIT grâce à @ypercube pour le ping en chat.

En passant, vous ne voulez peut-être pas vider toute l'adresse dans une seule colonne. La normalisation peut laisser penser que vous ne voulez pas stocker @hotmail.com15 millions de fois lorsqu'un FK int beaucoup plus maigre fonctionnerait très bien sans les frais généraux supplémentaires des colonnes de longueur variable. Vous pouvez également normaliser le nom d'utilisateur, john.smith@hotmail.comet john.smith@gmail.compartager un nom d'utilisateur commun - ils ne se connaissent pas, mais votre base de données s'en fiche.

J'ai parlé de certaines de ces choses 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 toutefois des défis à la limite de 254 caractères ci-dessus, car il ne semble pas y avoir de consensus sur ce qui se produit lorsqu'un domaine valide de 255 caractères est combiné à une partie locale valide à 1 caractère. Cela devrait être accepté par la plupart des serveurs du monde entier mais semble violer cette limite de 254 caractères. Alors, créez-vous une Domainstable dont la longueur des adresses de messagerie est restreinte artificiellement, lorsque le domaine peut être réutilisé en tant qu'URL valide de 255 caractères?


J'aime cette approche, mais qu'en est-il de l'unicité du courrier électronique? Comment est-ce géré?
Roberto Rizzi

2
@RobertoRizzi Une contrainte unique ou une clé primaire sur la combinaison de DomainID + LocalPart ou inversement.
Aaron Bertrand

5

Il y a quelques considérations avec cette décision. Tout d’abord, il faut 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 souhaitez pas définir chaque type de données de colonne de chaîne sur varchar(1024)lorsque vous stockez une chaîne qui ne doit pas dépasser 32 caractères (accent mis sur le mot-clé should ).

Si vous avez une sorte de vulnérabilité dans laquelle les courriels sont tous modifiés pour devenir 255 caractères, vous pourriez potentiellement avoir un impact à long terme sur les performances des fractionnements de pages. Cela peut sembler inhabituel, mais vous devez adapter vos données à vos besoins professionnels . Tout comme la contrainte séculaire entre le débat sur la base de données et les applications, je suis fermement convaincu que les limitations de types 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 ne concerne probablement que le niveau de données. Qu'est-ce que le niveau d'application utilise? Par exemple, si vous avez une application dans laquelle vous ne pouvez entrer que 80 caractères pour une adresse électronique, pourquoi voudriez-vous que le type de données soit plus volumineux? Les entreprises doivent répondre à deux questions:

  1. Que peut- il être?
  2. Que devrait- il être?

Alors seulement, vous aurez votre réponse.

Un varchar, par définition, n’utilise-t-il pas la quantité de mémoire nécessaire pour stocker les données?

Oui et non. Il y aura une sorte de décalage pour que les données de longueur variable en enregistrent la longueur.


3

Le RFC 5321 (la spécification SMTP actuelle, obsolète le RFC2821) déclare:

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

Donc, 64 + 255 + signe @ implique VARCHAR (320). Vous n'aurez probablement jamais besoin de cela, mais vous pouvez le faire en toute sécurité, juste au cas où.



1

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

Dans la mesure où une longueur de colonne VARCHAR est en réalité une "longueur maximale", elle doit être définie sur une longueur supérieure à la longueur maximale possible en toutes circonstances. Seul l'espace nécessaire à chaque ligne sera utilisé. Les programmes d’application doivent alors être conçus avec des champs de défilement ou tout autre choix logique en fonction de valeurs typiques.

Une conception de base de données est comme un morceau de papier physique dans la mesure où elle établit les limites strictes en matière de taille. Une page de papier ne peut pas être agrandie. Dans cette analogie, le programme d'application ressemble à 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 la taille de VARCHAR puisse sembler simple et s’exécuter instantanément sur une petite table, le faire sur une table comportant des milliers de lignes ou plus nécessitera probablement une sorte de repos de la base de données lors de la régénération de tous les blocs de données et d’index. Une solution consiste à tout copier dans une nouvelle table avec les plus grandes colonnes. Quelle que soit la technique utilisée, il s'agit d'un gros problème. Ainsi, vous devriez considérer la taille de la colonne VARCHAR en grande partie immuable une fois qu'une table de production est chargée.


1

Voici un commentaire sur les excellentes réponses:

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 devrait être une opération triviale sur le serveur de base de données - en fonction, bien entendu, de votre produit de base de données.

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

Deuxièmement, en fonction de la taille moyenne des lignes et de la taille de la page, utiliser à la varchar(320)place de varchar(240)ne risque pas de changer 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 électronique. Je soutiens qu’il n’ya qu’un moyen sûr de valider une adresse électronique, c’est d’envoyer un courrier électronique. :-)


0

VARCHAR est le meilleur type de données à utiliser pour les adresses électroniques, car leur longueur varie beaucoup. NVARCHAR est également une alternative, mais je recommanderais de l’utiliser uniquement si l’adresse e-mail contient des caractères étendus et n’oubliez pas qu’elle nécessite deux fois plus d’espace de stockage que VARCHAR.

Dans mon environnement, nous utilisons varchar (70), car les plus longs que j'ai rencontrés mesurent de 60 à 70 caractères, mais cela dépend également de la clientèle de votre entreprise. En outre, vous devez également vérifier que la validité des adresses e-mail est vérifiée sur place, comme si vous utilisiez des contraintes de vérification ou CHARINDEX.


0

Utiliser SQL DOMAIN

Si vous utilisez un serveur de base de données d'entreprise, il devrait être possible de stocker une adresse électronique DOMAINavec 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 emplacements où un type de données peut être spécifié. Un domaine est constitué d'un type de données, éventuellement d'une option par défaut, et de zéro ou plusieurs contraintes (domaine).

Par exemple, PostgreSQL, un logiciel libre et à code source ouvert, prend en charge cette fonctionnalité, à moins que votre implémentation de la spécification ne soit limitée, la colonne elle-même contient un courrier électronique valide. Vous pouvez par exemple ..

  • Créez une personnalisation DOMAINsur la spécification HTML5 du courrier électronique.
  • Ou, via les spécifications RFC822, RFC2822, RFC5322 du courrier électronique.
  • Créez une coutume DOMAINqui recherche sur le serveur un enregistrement MX au moment de la vérification.

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

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.