web-dev-qa-db-fra.com

Utiliser une adresse email comme clé primaire?

L'adresse électronique est-elle un mauvais candidat pour le primaire par rapport aux numéros à incrémentation automatique?

Notre application Web nécessite que l'adresse électronique soit unique dans le système. J'ai donc pensé à utiliser une adresse électronique comme clé primaire. Toutefois, mon collègue suggère que la comparaison de chaînes sera plus lente que la comparaison d'entiers. 

Est-ce une raison valable de ne pas utiliser le courrier électronique comme clé primaire?

Nous utilisons PostgreSQL.

216
robert

La comparaison de chaînes est plus lente que la comparaison int. Cependant, peu importe si vous récupérez simplement un utilisateur de la base de données à l'aide de l'adresse de messagerie. Peu importe si vous avez des requêtes complexes avec plusieurs jointures.

Si vous stockez des informations sur les utilisateurs dans plusieurs tables, les clés étrangères de la table users seront l'adresse de messagerie. Cela signifie que vous stockez l'adresse électronique plusieurs fois.

272
Sjoerd

Je tiens également à souligner que la messagerie électronique est un mauvais choix pour créer un champ unique. Certaines personnes et même de petites entreprises partagent une adresse électronique. Et comme les numéros de téléphone, emails peuvent être réutilisés. [email protected] peut facilement appartenir à John Smith un an et à Julia Smith deux ans plus tard.

Un autre problème avec les emails est qu'ils changent fréquemment. Si vous vous joignez à d'autres tables dont la clé est la clé, vous devrez également mettre à jour les autres tables, ce qui peut être très pénalisant en termes de performances lorsqu'une entreprise cliente entière modifie ses courriels (ce que j'ai vu se produire.)

171
HLGEM

la clé primaire doit être unique etconstante

les adresses email changent comme les saisons. Utile comme clé secondaire pour la recherche, mais un mauvais choix pour la clé primaire.

95
Steven A. Lowe

Inconvénients de l'utilisation d'une adresse électronique comme clé primaire:

  1. Plus lent quand on fait des jointures.

  2. Tout autre enregistrement avec une clé étrangère enregistrée a maintenant une valeur plus grande, occupant plus d'espace disque. (Compte tenu du coût actuel de l'espace disque, il s'agit probablement d'un problème trivial, sauf dans la mesure où la lecture de l'enregistrement prend plus de temps. Voir le paragraphe 1.)

  3. Une adresse électronique peut changer, ce qui oblige tous les enregistrements utilisant cette clé étrangère à être mis à jour. Comme l'adresse électronique ne change pas très souvent, le problème de performance est probablement mineur. Le plus gros problème est que vous devez vous assurer de le faire. Si vous devez écrire le code, cela représente plus de travail et introduit la possibilité de bogues. Si votre moteur de base de données prend en charge "en cascade de mises à jour", il s'agit d'un problème mineur.

Avantages de l'utilisation d'une adresse électronique en tant que clé primaire:

  1. Vous pourrez peut-être éliminer complètement certaines jointures. Si tout ce dont vous avez besoin dans "l'enregistrement principal" est une adresse e-mail, alors avec une clé entière abstraite, vous devrez créer une jointure pour la récupérer. Si la clé est l'adresse e-mail, vous l'avez déjà et la jointure est inutile. Que cela vous aide ou non dépend de la fréquence à laquelle cette situation se présente.

  2. Lorsque vous effectuez des requêtes ad hoc, il est facile pour un être humain de voir quelle fiche est référencée. Cela peut être d'une grande aide lorsque vous essayez de localiser des problèmes de données.

  3. De toute façon, vous aurez presque certainement besoin d’un index sur l’adresse e-mail. Par conséquent, la clé primaire élimine un index, ce qui améliore les performances des insertions car elles n’ont plus qu’un index à mettre à jour.

À mon humble avis, ce n'est pas un slam-dunk de toute façon. J'ai tendance à préférer utiliser des clés naturelles lorsque vous en avez une pratique, car elles sont tout simplement plus faciles à utiliser et les inconvénients ont peu d'importance dans la plupart des cas.

61
Jay

C'est pas mal. Supposons qu'un fournisseur de messagerie électronique ferme ses portes. Les utilisateurs voudront alors changer leur adresse électronique. Si vous avez utilisé le courrier électronique comme clé primaire, toutes les clés étrangères des utilisateurs le dupliqueront, ce qui le rendra extrêmement difficile à modifier ...

... et je n'ai même pas commencé à parler de considérations de performance.

11
meriton

Je ne sais pas si cela pourrait poser un problème dans votre configuration, mais en fonction de votre SGBDR, les valeurs d'une colonne peuvent être sensibles à la casse . La documentation PostgreSQL ™ dit: "Si vous déclarez une colonne comme UNIQUE ou PRIMARY KEY, l'index généré implicitement est sensible à la casse". En d'autres termes, si vous acceptez la saisie de l'utilisateur pour une recherche dans une table avec une adresse électronique comme clé primaire et que l'utilisateur fournit "[email protected]", vous ne trouverez pas "[email protected]".

11
xlttj

Personne ne semble avoir mentionné un problème possible selon lequel les adresses électroniques pourraient être considérées comme privées. Si l'adresse électronique est la clé primaire, l'URL d'une page de profil ressemblera probablement à quelque chose comme ..../Users/[email protected]. Et si vous ne voulez pas révéler l'adresse email de l'utilisateur? Vous devez trouver un autre moyen d’identifier l’utilisateur, éventuellement en utilisant une valeur entière unique pour créer des URL telles que ..../Users/1. Vous vous retrouveriez alors avec une valeur entière unique.

10
Simen Echholt

Au niveau logique , le courrier électronique est la clé naturelle. Au niveau physical, étant donné que vous utilisez une base de données relationnelle, la clé naturelle ne correspond pas bien à la clé primaire. La raison en est principalement les problèmes de performance mentionnés par d'autres.

Pour cette raison, le design peut être adapté. La clé naturelle devient la clé alternative (UNIQUE, PAS NULL), et vous utilisez une clé clé de substitution/artificielle/technique } comme clé primaire, qui peut être une incrémentation automatique Cas. 

systempuntoout demandé,

Et si quelqu'un veut changer son adresse email? Allez-vous changer toutes les clés étrangères aussi?

C'est à cela que (cascading } _ est destiné.

Une autre raison d'utiliser une clé de substitution numérique en tant que clé primaire est liée au fonctionnement de l'indexation sur votre plate-forme. Dans InnoDB de MySQL, par exemple, la clé primaire est préfixée à tous les index d'une table. Vous voulez donc que la PK soit aussi petite que possible (pour des raisons de rapidité et de taille). Également lié à cela, InnoDB est plus rapide lorsque la clé primaire est stockée en séquence, et une chaîne n'y aiderait pas.

Une autre chose à prendre en compte lors de l'utilisation d'une chaîne en tant que clé alternative est que l'utilisation d'un hachage de la chaîne réelle que vous souhaitez peut être plus rapide, en sautant des choses comme les majuscules et les minuscules de certaines lettres. (J'ai effectivement atterri ici en cherchant une référence pour confirmer ce que je viens de dire; toujours à la recherche ...)

8
Rafa

Oui, c'est une clé primaire incorrecte car vos utilisateurs voudront mettre à jour leurs adresses électroniques.

4
Bryan Legend

oui, il vaut mieux utiliser un entier à la place. vous pouvez également définir votre colonne email comme contrainte unique.

comme ça:

CREATE TABLE myTable(
    id integer primary key,
    email text UNIQUE
);
4
ibram

Une autre raison pour laquelle la clé primaire entière est meilleure est lorsque vous faites référence à une adresse électronique dans une table différente. Si l'adresse elle-même est une clé primaire, vous devez l'utiliser dans une autre table. Donc, vous stockez les adresses e-mail plusieurs fois.

3
klew

Je ne connais pas trop Postgres. Les clés primaires est un sujet important. J'ai vu d'excellentes questions et réponses sur ce site (stackoverflow.com).

Je pense que vous pouvez obtenir de meilleures performances en utilisant une clé primaire numérique et en utilisant un INDEX UNIQUE dans la colonne email. Les e-mails ont tendance à varier en longueur et peuvent ne pas être appropriés pour l'index de clé primaire.

certains lisent ici et ici.

3
Saif Khan

Je sais qu’il s’agit d’une entrée tardive, mais j’aimerais ajouter que les gens abandonnent les comptes de messagerie et que les fournisseurs de services récupèrent l’adresse permettant à une autre personne de l’utiliser.

Comme @HLGEM l'a souligné, "[email protected] peut facilement appartenir à John Smith un an et à Julia Smith deux ans plus tard". dans ce cas, si John Smith souhaite votre service, vous devez soit refuser d'utiliser son adresse électronique, soit supprimer tous vos enregistrements concernant Julia Smith.

Si vous devez supprimer des enregistrements liés aux antécédents financiers de l’entreprise, en fonction de la législation en vigueur, vous risquez de vous retrouver dans l’eau chaude.

Donc, je n'utiliserais jamais des données telles que des adresses électroniques, des plaques d'immatriculation, etc. comme clés primaires, car peu importe leur apparence, elles sont hors de votre contrôle et peuvent fournir des défis intéressants que vous n'avez peut-être pas le temps de traiter.

2
Robert

Utilisez un GUID comme clé primaire ... de cette façon, vous pouvez le générer à partir de votre programme lorsque vous effectuez une INSERTION et vous n'avez pas besoin d'obtenir une réponse du serveur pour connaître la nature de la clé primaire. Elle sera également unique dans les tables et les bases de données et vous n’aurez pas à vous inquiéter de ce qui se passera si vous tronquez la table un jour et que l’incrémentation automatique est réinitialisée à 1.

2
JoelFan

Personnellement, je n'utilise aucune information pour la clé primaire lors de la conception de la base de données, car il est très probable que je devrais éventuellement modifier des informations ultérieurement. La seule raison pour laquelle je fournis une clé primaire est qu'il est pratique d'effectuer la plupart des opérations SQL du côté client et mon choix a toujours été de type entier à incrémentation automatique.

2
tia

Votre collègue a raison: utilisez un entier auto-incrémenté pour votre clé primaire.

Vous pouvez implémenter l'unicité du courrier électronique au niveau de l'application ou vous pouvez marquer votre colonne d'adresse électronique comme unique et ajouter un index sur cette colonne.

L'ajout du champ comme unique coûtera une comparaison de chaîne uniquement lors de l'insertion dans cette table, et non lors de l'exécution de vérifications de jointures et de contraintes de clé étrangère. 

Bien entendu, vous devez noter que le fait d'ajouter des contraintes à votre application au niveau de la base de données peut rendre votre application inflexible. Prenez toujours toutes les précautions nécessaires avant de rendre un champ "unique" ou "non nul" simplement parce que votre application a besoin qu'il soit unique ou non vide.

2
jrharshath

la clé primaire doit être un attribut statique. Comme les adresses électroniques ne sont pas statiques et peuvent être partagées par plusieurs candidats, il n’est donc pas judicieux de les utiliser comme clé primaire. De plus, les adresses e-mail sont des chaînes d'une longueur généralement supérieure à l'identifiant unique que nous aimerions utiliser [len (email_address)> len (unique_id)] ​​afin de nécessiter plus d'espace et même pire, elles sont stockées plusieurs fois en tant que clé étrangère . Et par conséquent, cela conduira à dégrader la performance.

1
user2719152

vous pouvez augmenter les performances en utilisant une clé primaire entière.

1
xport

Si vous avez une valeur non int en tant que clé primaire, les insertions et les extractions seront très lentes pour les données volumineuses. 

1
Amareswar

vous devriez utiliser une clé primaire entière. si vous avez besoin que la colonne email soit unique, pourquoi ne pas simplement définir un index unique sur cette colonne?

1
oezi

Cela dépend de la table. Si les lignes de votre table représentent des adresses e-mail, e-mail est alors le meilleur identifiant. Sinon, le courrier électronique n'est pas un bon identifiant.

0
Lajos Arpad

L'e-mail est un bon candidat unique pour l'index, mais pas pour la clé primaire. S'il s'agit d'une clé primaire, vous ne pourrez pas modifier l'adresse e-mail du contact, par exemple ... Je pense que vos requêtes de jointure seront également plus lentes.

0
Chocolim

S'il s'agit simplement d'exiger que le courrier électronique soit unique, vous pouvez simplement créer un index unique avec cette colonne.

0
Micah

Vous devrez peut-être examiner toute législation applicable en matière de réglementation des données. Les courriers électroniques sont des informations personnelles. Si vos utilisateurs sont citoyens de l'UE, par exemple, ils peuvent, dans le cadre du RGPD, vous demander de supprimer leurs informations de vos dossiers (rappelez-vous que cela s'applique quel que soit le pays où vous êtes basé).

Si vous devez conserver la notice elle-même dans la base de données pour des raisons d’intégrité référentielle ou d’historique, telle que l’audit, l’utilisation d’une clé de substitution vous permettrait de NULL tout le champ de données personnelles. Ce n'est évidemment pas aussi facile si leurs données personnelles sont la clé primaire 

0
Stuart Parker

ne pas utiliser l'adresse électronique comme clé primaire, conserver le courrier électronique comme unique mais ne pas l'utiliser comme clé primaire, utiliser l'ID utilisateur ou le nom d'utilisateur comme clé primaire

0
Nikki