2012-03-06 6 views
8

utilisateur Dans mon application Symfony 2 Je veux utiliser le système standard d'autorisation des utilisateurs et des rôles (http://symfony.com/doc/2.0/book/security.html)Cadre Symfony; idiomatiques façon de stocker le rôle

Mon L'utilisateur est une entité stockée dans une base de données avec doctrine (implémentation de l'interface utilisateur). Je vais avoir 5 rôles prédéfinis dans mon système, chaque utilisateur ayant peut-être plusieurs de ces rôles.

Quelle serait la manière la plus idiomatique de mettre en œuvre ceci? Je pense aux trois solutions suivantes.

  1. Faire une entité distincte de rôle et de créer un grand nombre à plusieurs relations avec l'entité utilisatrice

    • Plus: Facile d'accès à tous les utilisateurs ayant un rôle spécifique
    • Con: Ressource intensive? (Toujours besoin d'une double jointure pour obtenir tous les rôles pour un utilisateur)
    • Con: Non idomatique? Le nombre de rôles (et leurs noms) ne change jamais, il est donc logique de le stocker dans la base de données en tant qu'entité séparée.
  2. ont un champ à l'intérieur de l'utilisateur qui est une liste triée, seperated par des virgules des rôles et getRoles() est mis en œuvre comme explode(',',this.all_roles)

    • Plus: Non informatiquement cher
    • Con: Difficile à obtenir tous les utilisateurs ayant un rôle spécifique
    • Con: champs de base de données comme celui-ci font pleurer les chatons (normalizaition et trucs)
  3. ont 5 champs binaires dans l'entité utilisatrice pour chaque rôle

    • Plus: Non informatiquement cher
    • Plus: Facile d'accès à tous les utilisateurs ayant un rôle spécifique
    • Con: Cela ne se sent toujours pas bon

Quelle est la manière la plus idiomatiques de mettre en œuvre ce système?

+0

Comment puis-je corriger l'espacement autour de mes sous-éléments? –

+1

L'option 1 est bien sûr la voie sûre.Si vous avez besoin d'accrocher des relations supplémentaires sur vos rôles (permissions, etc.), alors vous serez tous configurés. L'option 2 fonctionnera probablement très bien. Peut-être utiliser un nombre entier avec le mappage de bits pour stocker les rôles? Soyez un peu plus propre, extensible et interrogeable. Ne laissez pas les chatons le voir. – Cerad

+0

Pourriez-vous ne pas utiliser [FOSUserBundle] (https://github.com/FriendsOfSymfony/FOSUserBundle) pour cela? – Flukey

Répondre

12

Bien sûr, une réponse dépend fortement de vos besoins, mais je vais essayer d'y répondre aussi globalement que possible.

Option 1: La façon relationnelle

D'un pur point de vue relationnel, vous voulez que votre base de données normalisée qui conduirait à votre première option: Une table pour les rôles avec h: n par rapport à votre utilisateur table. Ceci a quelques avantages:

  • Eh bien, c'est la façon dont on s'attendrait à ce que votre base de données fonctionne, donc pas de fonctionnalité cachée dans vos entités.
  • Pas moyen de vis les choses (comme lorsque vous avez un champ varchar et attendez d'avoir une sorte de format comme coma seperation)
  • Une seule façon de faire les choses

En ce qui concerne votre préoccupation les rôles ne changent jamais: le stockage des données relationnelles ne dépend pas de la fréquence à laquelle elles changent. Et il faut toujours se rappeler que les exigences changent. Plus vous vous trompez en ce moment au nom de l'optimisation, plus vous luttez plus tard quand il y a besoin de plus de rôles qui changent plus souvent. Bien sûr, vous pouvez avoir des problèmes de performances, surtout si vous rencontrez un problème de chargement passionnant ou si vous ne mettez pas en cache des éléments et que vous devez recharger des rôles à chaque chargement de page. Mais encore une fois, les bases de données relationnelles sont conçues pour prendre en charge ce genre de choses, donc il devrait y avoir des façons d'optimiser les requêtes.

Option 2: Le hack

Votre deuxième option, simplement stocker tous les rôles dans un varchar, serait beaucoup plus agréable en termes de performance. Un seul champ de texte à charger, du traitement PHP et vous avez terminé. D'autre part, vous pouvez rencontrer plusieurs problèmes:

  • Vous avez aucun contrôle sur le champ varchar donc un scénario dysfonctionnement peut compromettre votre application entière (Ceci est vraiment mauvais, mais en fonction de votre projet, si vous êtes le seul développeur et vous savez ce que vous faites, il pourrait bien aller)
  • Une mise à jour d'un ensemble de données est beaucoup plus difficile, car vous devez extraire tous les rôles, mettre à jour ceux en question, et stocker
  • pour tous les utilisateurs avec un rôle spécifique est beaucoup plus difficile
  • La suppression d'un rôle est beaucoup plus difficile

Option 3: La solution pragmatique

La troisième option avec 5 booléens pour chaque rôle est au milieu: Il n'y a aucun moyen de le visser et la performance ne devrait pas être un problème. La mise à jour est facile, tout comme la suppression d'un rôle ou l'ajout d'un nouveau rôle. C'est assez clair ce que les champs font, donc pas de mal de ce côté non plus. Cela rend votre entité et votre base de données un peu plus laides et vous auriez les noms de rôle dans votre modèle utilisateur pour mapper les champs true/false aux noms de rôles corrects, ce qui pourrait être un peu déroutant.

Résultat

Tout cela à l'esprit, j'aller avec l'option 1. On peut supposer que la performance est un problème, mais à moins d'avoir la preuve de cela, je ne pense pas à ce genre de choses. En fin de compte, que faites-vous quand vous avez vraiment un problème de performance réel? Vous pouvez ajouter du matériel supplémentaire, optimiser vos dbms, optimiser les requêtes ou peut-être utiliser un dbms avec plus de performances intégrées (Hello Oracle!).

Et vous pouvez toujours utiliser l'option 3 plus tard si vous avez prouvé que votre application est lente à cause de la table de rôles. Vous devrez simplement changer votre entité utilisateur et avoir une requête qui extrait les rôles et définit les combinaisons vrai/faux correctes pour chaque utilisateur. Si le logiciel est propre, c'est une question d'heures, donc pas besoin de le faire maintenant sur l'idée que la performance pourrait être mauvaise.

+0

+1 Une réponse géniale. FOSUserBundle stocke les rôles dans un tableau. Serait-il possible d'avoir votre opinion d'expert à ce sujet? Merci beaucoup @Sgoettschkes. – Mick

Questions connexes