Séparer la table utilisateur de la table personnes dans une base de données relationnelle

StackOverflow https://stackoverflow.com/questions/92894

  •  01-07-2019
  •  | 
  •  

Question

J'ai créé de nombreuses applications Web pour lesquelles la première chose à faire est de créer une table d'utilisateurs avec les noms d'utilisateur, mots de passe, noms, courriers électroniques et tous les autres messages flotsam habituels. Mon projet actuel présente une situation dans laquelle les enregistrements de non-utilisateurs doivent fonctionner de la même manière que les utilisateurs, mais n'ont pas besoin d'être un utilisateur de premier ordre.

Est-il raisonnable de créer une deuxième table, people_tb , qui est la table relationnelle principale et le magasin de données, et d'utiliser uniquement le users_tb pour l'authentification? La séparation de user_tb de people_tb pose-t-elle des problèmes? Si cela se fait couramment, quelles sont certaines stratégies et solutions ainsi que des inconvénients?

Était-ce utile?

La solution

C’est certainement une bonne idée, car vous normalisez la base de données. J'ai créé un concept similaire dans une application que je suis en train d'écrire, où j'ai une table des employés et une table des utilisateurs. Les utilisateurs peuvent provenir d’une entreprise externe ou d’un employé. Par conséquent, j’ai des tables séparées car un employé est toujours un utilisateur, mais un utilisateur ne peut pas être un employé.

Le problème que vous allez rencontrer est que, chaque fois que vous utilisez la table user, vous souhaiterez presque toujours que la table person reçoive le nom ou d'autres attributs communs que vous souhaitez afficher.

Du point de vue du codage, si vous utilisez du SQL pur, l’analyse mentale de l’instruction select demandera un peu plus. Cela peut être un peu plus compliqué si vous utilisez une bibliothèque ORM. Je n'ai pas assez d'expérience avec ceux-là.

Dans mon application, je l'écris dans Ruby on Rails, je fais donc constamment des choses comme employee.user.name, où si je les gardais ensemble, ce serait juste employee.name ou user.name.

Du point de vue des performances, vous utilisez deux tables au lieu d’une, mais si l’index est correct, il devrait être négligeable. Si vous aviez un index contenant la clé primaire et le nom de la personne, par exemple, la base de données atteindrait la table user, puis l'index de la table person (avec un hit presque direct), de sorte que les performances seraient presque identiques à avoir une table.

Vous pouvez également créer une vue dans la base de données pour que les deux tables soient jointes afin d’améliorer les performances. Je sais que dans les dernières versions d'Oracle, vous pouvez même mettre un index sur une vue si nécessaire pour améliorer les performances.

Autres conseils

Je le fais régulièrement parce que, pour moi, le concept de "utilisateur" (nom d'utilisateur, mot de passe, date de création, date de la dernière connexion) est différent de " personne " (nom, adresse, téléphone, email). L’un des inconvénients que vous pouvez constater est que vos requêtes nécessiteront souvent plus de jointures pour obtenir les informations que vous recherchez. Si tout ce que vous avez est un nom de connexion, vous devez rejoindre le groupe "Personnes". table pour obtenir le prénom et le nom par exemple. Si vous basez tout sur la clé primaire de l'ID utilisateur, ceci est un peu atténué, mais reste affiché.

Si user_tb a des informations d'authentification, je le garderais bien distinct de people_tb. Je voudrais cependant garder une relation entre les deux, et la plupart des informations des utilisateurs seraient stockées dans people_tb, à l'exception de toutes les informations nécessaires à l'authentification (qui, je suppose, ne seront pas utilisées pour autre chose). C'est un bon compromis entre design et efficacité. penser.

J'essaie toujours d'éviter autant que possible la répétition de données. Si toutes les personnes n'ont pas besoin de se connecter, vous pouvez avoir une table générique personnes avec les informations qui s'appliquent à la fois aux personnes et aux utilisateurs (par exemple, prénom, nom, etc.).

Ensuite, pour les personnes qui se connectent, vous pouvez avoir une table utilisateurs qui a une relation à 1 ~ 1 avec personnes . Cette table peut stocker le nom d'utilisateur et le mot de passe.

Je dirais qu’il faut opter pour la conception normalisée (deux tables) et ne dénormaliser que (descendre à une table utilisateur / personne) si cela vous simplifie vraiment la vie. Cependant, si pratiquement toutes les personnes sont également des utilisateurs, il peut être plus simple de dénormaliser au préalable. C'est à vous; J'ai utilisé l'approche normalisée sans problèmes.

Très raisonnable.

Par exemple, consultez les tables de services aspnet_ * ici .

Leur schéma intégré comporte aspnet_Users et aspnet_Membership , la table la plus récente comportant des informations plus étendues sur un utilisateur donné (mots de passe hachés, etc.), mais aspnet_User .UserID est utilisé dans les autres parties du schéma pour l'intégrité référentielle, etc.

En bout de ligne, il est très courant, avec une bonne conception, d’avoir des attributs dans un tableau séparé s’il s’agit d’entités différentes, comme dans votre cas.

C’est définitivement ce que nous faisons, car nous avons des millions d’enregistrements de personnes et seulement des milliers d’utilisateurs. Nous séparons également les adresses, les téléphones et les courriels en tables relationnelles, car beaucoup de personnes possèdent plus d'une de ces choses. Il est essentiel de ne pas compter sur le nom car l'identifiant en tant que nom n'est pas unique. Assurez-vous que les tables sont jointes par un type de clé de substitution (un entier ou un GUID est préférable) et non par nom.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top