Je crée un système de menus en PHP et MySQL. J'aurai plusieurs menus différents et chaque menu aura un ensemble d'éléments de menu qui lui seront connectés.
Sur le site, j'ai également différentes autorisations d'utilisateur, certains utilisateurs peuvent voir tous les éléments de menu et certains éléments sont cachés à certains utilisateurs. Je suis curieux de savoir comment je pourrais gérer les autorisations d'une manière propre qui permettra d'ajouter plus de types d'utilisateurs à l'avenir.
Ce que j'ai jusqu'à présent est quelque chose comme ceci:
-------------------
|Menus
-------------------
|id| |display name|
-------------------
----------------------------------------------------------
|Menu items
----------------------------------------------------------
|id| |menu_id| |label| |link| |parent| |sort| |permission|
----------------------------------------------------------
Je pense que la permission
colonne peut être une chaîne séparée par des virgules que je peux comparer à l'ID d'autorisation de l'utilisateur actuel. Il peut également s'agir d'une référence à un autre tableau qui définit toutes les combinaisons possibles des autorisations existantes.
Une solution pourrait également être de simplement stocker plusieurs éléments de menu où la seule différence est la permission, bien que cela conduirait à un stockage en double et peut-être une douleur à administrer.
J'aimerais entendre une réflexion sur la façon de structurer cela et ce qui pourrait être considéré comme propre, dynamique et merdique.
Merci.
la source
Réponses:
Je vais le modéliser à l'aide d'un diagramme ER.
PERMISSION
est l'accès accordé à unROLE
sur un donnéMENU_ITEM
.USER
peut avoir plusieurs ROLE accordés.Ensuite, vous pouvez créer une vue pour ne pas avoir à écrire les jointures à chaque fois:
Ensuite, chaque fois que vous voulez savoir à quels éléments de menu un utilisateur a accès, vous pouvez l'interroger:
ÉDITER:
Puisqu'un utilisateur peut se voir attribuer plusieurs rôles, les autorisations des rôles peuvent se chevaucher, c'est-à-dire que deux rôles distincts peuvent avoir accès au même élément de menu. Lorsque vous définissez un rôle, vous ne savez pas au préalable s'il aura des autorisations en commun avec d'autres rôles. Mais puisqu'il s'agit de l'union d'ensembles, il importe seulement qu'une autorisation donnée fasse partie de l'ensemble, pas le nombre de fois où elle apparaît, d'où la
distinct
clause dans la vue.la source
Avoir une liste séparée par des virgules signifie faire une comparaison de sous-chaîne chaque fois que vous effectuez une requête sur le menu. C'est loin d'être idéal.
Vous devez normaliser le tableau:
Si vous voulez toujours la liste séparée par des virgules (pour une raison quelconque), vous pouvez la retirer avec des choses comme
group_concat
dans mysqlwm_concat
dans oracle ou des fonctions similaires dans d'autres langues.L'avantage est multiple.
Tout d'abord, il y a l'aspect pratique de l'appel. Faire une sous-chaîne par rapport à une chaîne arbitrairement grande (si vous corrigez la taille, vous pouvez avoir des problèmes plus tard avec le remplissage de la chaîne afin que vous commenciez à obtenir des autorisations comme
a
au lieu deanother_permission
) signifie analyser la chaîne sur chaque ligne. Ce n'est pas quelque chose pour lequel les bases de données sont optimisées.Deuxièmement, la requête que vous écrivez devient beaucoup plus simple. Pour déterminer si l'autorisation «foo» existe dans une liste séparée par des virgules, vous devez vérifier «foo».
Cependant, cela donnera un faux positif si vous avez également l'autorisation «foobar». Alors maintenant, vous devez avoir un test comme
mais cela donnera un faux négatif si 'foo' est au début ou à la fin de la chaîne. Cela mène à quelque chose comme
Vous noterez qu'il est très probable que vous devrez effectuer plusieurs analyses de la chaîne. Cette voie mène à la folie.
Notez qu'avec tout cela, vous n'avez pas la capacité pratique de faire la liaison de paramètres (toujours possible, devient encore plus laid).
La normalisation du champ vous donne beaucoup plus de flexibilité et de lisibilité dans votre base de données. Vous ne le regretterez pas.
la source
Cette approche classique de ceci est
User -> UserGroup
puis associée aMenu -> MenuItem -> UserGroup
. Utilisation d'une valeur entière pour peser le niveau d'autorisation.Lorsque vous devez afficher un menu pour l'utilisateur actuel. Vous pouvez interroger la base de données comme ceci.
Cela ne sélectionnera que les menus visibles par l'utilisateur actuel en fonction de la condition pour
option1
.Sinon, si vous stockez les détails du groupe de l'utilisateur actuel dans la session en cours, aucune jointure n'est requise.
Lorsque vous parlez de vouloir stocker plusieurs autorisations par élément de menu. Je ferais attention de ne pas confondre les rôles utilisateur et la logique métier.
la source