FORUM : permission particulière sur une catégorie... - PHP - Programmation
Marsh Posté le 16-05-2003 à 17:05:34
C'est une entité qui associe 2 autres entités :
Tu fais une table qui contient la clé etrangère du membre et la clé étrangère de la catégorie.
Marsh Posté le 16-05-2003 à 17:18:13
Merci c'est très intéressant, mais je dois dire que je n'ai jamais utilisé ce genre de méthode. Pourrais-tu rentrer un tout petit peu plus dans le détail STP ? Je suis en train de regarder ce qui concerne les clés étrangères dans le manuel de mysql et je dois sire que je comprends pas tout.
Marsh Posté le 16-05-2003 à 17:26:27
En fait, j'aimerais mieux ne pas utiliser de clé étrangère. Ya pas une autre solution ?
Parce que voilà ce que dit le manuel :
Citation : |
Marsh Posté le 16-05-2003 à 17:28:47
Ben tu crées une table qui contient 2 champs :
* 1 champ est du même type que la clé primaire du membre
* 1 champ est du même type que la clé primaire de la catégorie
Quand un membre X a le droit d'accéder à une catégorie Y, tu insères une entrée (X, Y)
Tu peux aussi rajouter un 3ième champ pour le niveau d'accès (lecture seule, poster, etc...)
Et si tu utilisais un vrai SGBD, tu peux même rajouter des contraintes pour assurer l'intégrité.
Marsh Posté le 16-05-2003 à 17:32:07
Tetragrammaton IHVH a écrit : Ben tu crées une table qui contient 2 champs : |
merci, c'est tout con, mais faut encore pouvoir y penser. J'étais bloqué parce que je ne voyais pas d'autres solutions qu'avoir un champ contenant le membre et en face les diverses cats auxquelles il a accès. Or, le membre peut très bien apparaitre autant de fois qu'il y a de cat différentes. C'est en effet bcp plus facile à gérer. Merci bcp !!
Marsh Posté le 16-05-2003 à 19:05:06
Est-ce vraiment indispensable de créer un table pour ca
Un simple champ énuméré dans la table des membres pourrait suffire
Ou tout simplement, un masque binaire.
Marsh Posté le 16-05-2003 à 19:19:47
mrBebert a écrit : Est-ce vraiment indispensable de créer un table pour ca |
précise ta pensée STP. Un champ énuméré, tu veux dire des n° de membres dans un champ séparé par un séparateur ? Mais ensuite, je devrais traiter ce champ, tu ne crois pas que ce sera plus lourd au final ?
Sinon, pour le masque binaire, je ne comprends pas ce que tu veux dire... Explique, ça m'intéresse bcp.
EDIT : effectivement, je viens de regarder le type ENUM et c'est vrai que cela peut être intéressant en stockant le numéro du membre dans un champ ENUM pour une autorisation.
D'après toi, ce sera plus léger au final qu'une requête à part dans une table réservée à cet effet ? Je demande ça, parce que je recherche l'optimisation à tout prix. Merci.
Marsh Posté le 16-05-2003 à 19:31:18
Un masuqe binaire, c'est un nom compliqué pour dire que tu utilises les bits d'un entier pour stocker un booléen.
Ensuite, tu utilises les opération binaires pour récupérer l'info. Pour savoir si un membre a le droit d'accéder à la catégorie "1", il suffit de regarder la valeur de 'acces & 1' (acces, c'est le nom de la variable.
Bon, pour t'y retrouver, tu définis des constantes dans tes scripts
Ca permet de stocker l'info de manière efficace, rapide et facile d'accès
Sinon, mysql a un type ENUM pour gérer ca automatiquement
Edit : oui, ce sera nettement plus rapide que de passer une nouvelle requête dans une table
Marsh Posté le 16-05-2003 à 19:35:03
mrBebert a écrit : Un masuqe binaire, c'est un nom compliqué pour dire que tu utilises les bits d'un entier pour stocker un booléen. |
Justement le type ENUM n'intéresse, mais je me demande si au moment de l'unique requête, ce ne sera pas plus lourd de vérifier que le membre a l'autorisation par rapport à une simple requête dans une table à 2 champs. Si tu me dis qu'une unique requête pour faire apparaitre les catégories dans la page index du forum avec la solution de l'ENUM est plus optimisée, j'opterai pour cette proposition.
EDIT : j'avais pas vu que tu avais édité.
MERCI !! Je vais faire comme ça alors.
Marsh Posté le 16-05-2003 à 19:38:49
Vérifier le droit, c'est juste faire un & binaire entre 2 entiers. Difficile de faire plus rapide
Si tu accèdes déja à l'enregistrement de la table membre pour une raison ou une autre, ca n'apporte aucune complexité supplémentaire.
Comme c'est une donnée qui varie peu, tu peux même la stocker dans la session si tu en as une
Marsh Posté le 16-05-2003 à 19:42:33
mrBebert a écrit : Vérifier le droit, c'est juste faire un & binaire entre 2 entiers. Difficile de faire plus rapide |
ok
Marsh Posté le 16-05-2003 à 20:09:43
mrBebert a écrit : Est-ce vraiment indispensable de créer un table pour ca |
Oui : la table est indispensable vu que c'est une relation n-n
Tout est dit.
Marsh Posté le 16-05-2003 à 20:23:41
Table de la cat :
Un ID allant de 0 à x, si possible sans trou.
Dans la table des utilisateurs, un champ "access" de type entier, initialisé à 0.
Ensuite, tu donnes les droits aux users de façon binaire :
0000000000000 = 0 : auucn accès
0000000000001 = 1 = 2^0 : accès à la cat 0
0000000000010 = 2 = 2^1 : accès à la cat 1
0000000000011 = 3 = 2^0 + 2^1 : accès aux cat 0 et 1
etc.
Lors de l'accès à une cat, t'as juste à tester si :
SELECT NULL FROM cat, user where cat.id = 5 and pow(2, cat.ID) & user.ACCESS > 0
-> Si ça retourne une ligne, alors l'utilisateur a accès à la cat 5 sinon il n'y a pas accès
Marsh Posté le 16-05-2003 à 20:24:05
Tetragrammaton IHVH a écrit : |
Non, cf ma solution qui est 1000 fois pus rapide et énormément moins gourmande
Marsh Posté le 16-05-2003 à 20:26:15
MagicBuzz a écrit : Table de la cat : |
Vive les modèles de données de porc :
le jour où il a besoin de plus de 32 cat, il est dans une merde pas croyable...
Ce genre de magouille est à proscrire car il y a des hypothèses cachées.
En plus, il n'est pas possible de mettre des contraintes référentielles. Bref, rien à voir avec l'utilisation saine d'un SGBD...
Marsh Posté le 16-05-2003 à 20:26:56
MagicBuzz a écrit : |
et ultra limitée et pas évolutive, super...
Marsh Posté le 16-05-2003 à 20:32:22
Tetragrammaton IHVH a écrit : |
Excuse-moi, mais le type number monte jusqu'à 17 bytes (number(38), alors pour la limitation en nombre de cats on en reparlera, ça laisse quand même 136 cats, je connais pas des masses de forum qui en ont autant.
Et ce système à l'avantage d'être des milliers de fois plus rapide qu'une table de jointure.
Sur un forum, c'est plus la rapidité d'éxécution qu'on privilégie que la propreté du modèle.
Marsh Posté le 16-05-2003 à 20:33:28
Tetragrammaton IHVH a écrit : |
Sur un vrai SGBD y'a un truc qui s'appelle des trigger, ça marche très bien si t'as vraiment besoin de vérifier l'intégrité des données...
Marsh Posté le 16-05-2003 à 20:34:18
MagicBuzz a écrit : |
C'est ta vision des choses. Continue à coder comme un porc si ça te convient...
Marsh Posté le 16-05-2003 à 20:35:10
quand aux contraintes d'intégrité, on en reparlera pour un système rapide...
je bosse sur gros systèmes (ERP) et j'ai jamais vu une clé étrangère, y'a pas mieu pour effondrer un serveur et rendre inévolutif l'applicatif et le modèle.
Marsh Posté le 16-05-2003 à 20:36:07
MagicBuzz a écrit : quand aux contraintes d'intégrité, on en reparlera pour un système rapide... |
Le débat est clos, "nous n'avons pas les mêmes valeurs", comme on dit
Marsh Posté le 16-05-2003 à 20:36:16
Tetragrammaton IHVH a écrit : |
chacun à sa vision de la porcherie, moi une requête nécessitant une relation entre 3 tables là où tu peux gérer la même chose avec deux tables, j'appelle ça un truc de porc non optimisé et mal pensé.
Marsh Posté le 16-05-2003 à 20:38:18
MagicBuzz a écrit : |
Celle là, je la quote tellement elle est
Marsh Posté le 16-05-2003 à 21:25:28
Bon, je trouve ce débat très intéressant. Je me doutais bien en posant la question (sachant que mysql ne supporte pas les requêtes imbriquées) que ça sentait le souffre...
Juste une question Magic, ton idée est très intéressante, mais il y a une chose que je ne comprend pas très bien :
Au moment d'afficher les catégories dans la page index, je dois tester en fait pour chaque catégorie si elle a le "droit" de s'afficher ou non. Il faudra donc quoi qu'il arrive faire une requête en ce sens non ? Je vais pas pouvoir en une requête afficher la catégorie + les infos associées et vérifier les droits sur CETTE catégorie. Il faudra donc pour la vérif, que je fasse comme tu l'as très bien indiqué.
Quelle différence donc entre ta méthode et celle de Tetragrammaton ? Avec sa solution il y a également 2 requêtes non ? Une requête de vérif avec la table dédiée pour cela et la requête liée à l'affichage.
Peut-être que je n'ai pas tout saisi, c'est bien possible car pour le moment j'avoue que je me suis contenté de trucs assez basiques avec mysql.
Sinon merci à tous les deux pour vos précisions.
Marsh Posté le 16-05-2003 à 21:29:31
SELECT cat.name FROM cat, user where user.login = 'MagicBuzz' and pow(2, cat.ID) & user.ACCESS > 0
et zou
Marsh Posté le 16-05-2003 à 21:30:29
ps: je sais pas si la fonction puissance de mysql s'écrit "pow" et je ne sais pas non plus si c'est le "&" l'oppérateur and booléen de mysql, à toi de trouver comment ça s'écrit pour chaque sgbd
Marsh Posté le 16-05-2003 à 21:34:25
Tetragrammaton IHVH a écrit : |
Toi tu es un adepte de Merise et des MCD, me trompe-je ?
Marsh Posté le 16-05-2003 à 21:49:55
MagicBuzz a écrit : SELECT cat.name FROM cat, user where user.login = 'MagicBuzz' and pow(2, cat.ID) & user.ACCESS > 0 |
ok, je vais faire des tests en ce sens, merci bien. Je testerai également l'autre méthode.
Marsh Posté le 16-05-2003 à 22:13:07
ReplyMarsh Posté le 16-05-2003 à 22:19:12
MagicBuzz a écrit : |
Ben c le con du n,n => Table de swap qui fait tilter, j'ai appris ça aussi.
C'est la methode la plus sure et qui permet une integrite parfaite de la base sachant que tu mets uen clef primaire pour le couple de clefs dans la table de swap.
Helas niveau performance c pas ça et pour un forum qui se trouvera certainement sur un petit ordinateur Intel monoprocesseur ce n'est pas du tout approprié
Marsh Posté le 16-05-2003 à 23:30:00
Tetragrammaton IHVH a écrit : Tu fais une table qui contient la clé etrangère du membre et la clé étrangère de la catégorie. |
C'est la seule solution propre. Ce genre de problèmes se retrouve très souvent un peu partout : en objet, qui dérive de qui, qui intègre quelles données comment, qui référence qui ... La solution adaptée est de séparer. Une relation entre 2 objets n'a rien à faire dans l'un ou l'autre, donc -> ailleurs.
Quant à la rapidité, où est le problème ? Organisation des données et vitesse sont deux choses bien différentes. On organise correctement, ensuite on rapidifie la chose. Pour rapidifier, il suffit de cacher la liste des cats auxquelles l'utilisateur a accès (eg à côté de l'endroit où tu stockes les trucs comme les préférences d'affichage).
(À noter qu'une table de ce genre peut servir à stocker d'autres relations, comme les droits d'accès à un thread privé : chaque membre a une entrée(sonid, idduthread)).
Marsh Posté le 17-05-2003 à 12:50:47
samuelp a écrit : |
Tu trompes totalement, j'utilise plutôt UML
Point de vue performance, une simple jointure n'est pas la mort (surtout pour un forum où on récupère des messages de plusieurs kilo... ). Et il n'y a rien d'étonnant que la doc MySQL déconseille l'utilisation saine d'un SGBD : ce n'est pas un vrai SGBD
Et quand tu sortiras de ton école rempli de tes idéaux pour découvrir le monde travail en équipe, tu changeras d'avis à propos de ce genre de magouille de porcasse
Marsh Posté le 17-05-2003 à 12:54:10
Tetragrammaton IHVH a écrit : |
Ben saches que je bosse deja
Et que l'on est pas obligé de faire des jointures pour adopter cette modelisation
D'autre part j'utilise ce procede n,n dans une application professionnelle pour decideurs vachement pressés pour un gain de propreté (et je travail en equipe, de 2 il est vrai )
Mais je sais ce qu'il y a derriere : Bi pro Xeon avec 1 Go de memoire et j'utilise Postgres...
Marsh Posté le 17-05-2003 à 12:57:18
samuelp a écrit : |
Et bien, on dirait pas
Marsh Posté le 17-05-2003 à 13:00:01
Tetragrammaton IHVH a écrit : |
Ah oui pourquoi ?
Je ne suis peut etre pas un crack en informatique mais j'ai une culture generale a faire palir Julien Lepers
Marsh Posté le 17-05-2003 à 15:06:24
Hermes le Messager a écrit : Bon, je trouve ce débat très intéressant. Je me doutais bien en posant la question (sachant que mysql ne supporte pas les requêtes imbriquées) que ça sentait le souffre... |
mysql les supporte avec la version 4.1
Marsh Posté le 17-05-2003 à 15:07:07
Tetragrammaton IHVH a écrit : |
arguments ?
Marsh Posté le 17-05-2003 à 15:31:23
Tetragrammaton IHVH a écrit : |
Je te trouve bien insolant mon gars.
Je commence à avoir un peu de mal à rester calme face à tes propos. Tu n'es pas le seul à avoir un boulot, comme tu vois, moi et samuelp nous bossons aussi. Tu n'es pas le seul à bosser en équipe, tu n'es pas le seul à avoir fait des études non plus.
Arrête de te prendre pour le messie de l'informatique, ce que tu dis est vrai en théorie, absoluement faux en pratique. Pour gérer ta bibliothèque sous Access, un modèle parfait avec contraintes d'intégrités, clés primaires et autres joyeusetés, c'est très bien. Pour un gros système ce n'est même pas catastrophique, la garantie que ça ne marchera pas.
Pourquoi les clé externes ne sont jamais utilisées :
- Lors de l'insertion d'une données, le SGBD doit faire une vérification de l'existance de l'entrée dans la table externe. A première vue, ça n'ajoute qu'une lecture dans un index ce qui est très rapide, mais pourtant, pas du tout, les effets de bord sont énormes :
Principe d'un insert :
-> Lock de tous les indexes de la table et sur certains SGBD, de la table elle-même.
-> Lecture de tous les indexes uniques et vérification qu'on ajoute pas un doublon.
-> Insertion de la ligne.
-> Mise à jour des indexes.
-> Unlock des différents éléments.
C'est extrêment rapide.
Avec une clé externe :
-> Lock de tous les indexes de la table et sur certains SGBD, de la table elle-même.
-> Lecture de tous les indexes uniques et vérification qu'on ajoute pas un doublon.
-> Attente de l'unlock de l'index de jointure, c'est à dire que si la table de jointure est en court de moficiation, on doit attendre la fin des modifications
-> Lock de l'index de jointure, c'est à dire que la table servant à la jointure devient non-modifiable/non-lisible pour certains SGBD à partir de maintenant
-> Insertion de la ligne.
-> Mise à jour des indexes.
-> Mise à jour de l'index de jointure
-> Unlock des différents éléments.
Les parties en rouge baissent catastrophiquement les performances de la requête elle-même, mais surtout celles de toute la base de données, puis qu'on fait un lock sur un élément supplémentaire, qu'on doit en plus attendre au cas où il est en cours d'utilisation.
Pour une base de données, volumineuse, avec des accès nombreux (un ERP est le meilleur exemple) avec les clés étrangères activées, même en doublant les performances du serveur tu à une chutte de performances notable, conduisant à l'apparition de nombreux bugs à cause de timeout. (sans parler du mécontentement des utilisateurs qui attendent 20 seconde devant chaque écran, et qui s'éxitent en appuyant 10 fois sur les boutons).
D'autres raison pour laquelle les clés étrangères sont déconseillées :
-> Lors de requêtes de type SELECT, elles n'apportent rien au niveau performance.
-> D'autres contraintes d'intégrités telles que les relations cycliques ou conditionnelles ne peuvent pas être gérées par un SGBD-R, à ce moment, c'est l'applicatif qui s'en charge. Hors, la première règle pour un développement propre et maintenable, c'est la centralisation des traîtements. Donc si on fait certaines contraintes dans la bases et d'autres dans le programme, c'est un joyeux bordel.
Je pourrais en parler des heures, moi aussi j'ai été jeune à vouloir mettre des clés partout, des trigger à gogo, et des tables de jointures à plus savoir comment les nommer. Et puis le travail d'équipe, avec des personnes compétentes m'a permis de voir que Merise ou Uml c'est très bien pour la fac, très bien pour débrouissailler un problème, mais en aucun cas il faut en tenir compte pour la version finale du modèle des données.
Marsh Posté le 17-05-2003 à 15:34:52
ceci les locks des jointures ne sont pas si emmerdant si le handle fait du row locking au lieu de faire du table locking
Marsh Posté le 16-05-2003 à 17:02:28
Toujours dans le cadre du forum que je suis en train de faire :
Je cherche à offrir la possibilité de créer des catégories privées. Quelle est d'après vous la meilleure organisation ? Sachant que je ne veux pas un code secret pour accéder à une catégorie, mais je veux pouvoir "autoriser" les membres individuellement à accéder à telle ou telle catégorie.
J'ai bien pensé à faire un champ TEXT dans la table des cats avec le nom des membres autorisés et séparés par des séparators. Mais cela me semble très lourd à gérer par la suite (surtout pour les perfs). En fait l'idéal serait dans mon cas une table "membres autorisés" à l'intérieur d'un champ "membres autorisés" dans la table des Cats. Qu'en pensez-vous/que feriez-vous dans mon cas ?
Merci.