6
votes

Vérification sur plusieurs tables dans MySQL

Question:

Je suis assez nouveau à MySQL et je ne sais même pas où commencer avec cela. Je veux savoir comment écrire une fonction simple qui renvoie true ou false en fonction des valeurs qui sont étalées sur de nombreuses tables. P>

Détails: h1>

Voici les parties pertinentes de mes tables (Tous les moteurs sont innodb code>). Au fur et à mesure que vous le lisez, vous verrez que la base de données ne stocke que des utilisateurs, des groupes, des fichiers et des autorisations pour ces fichiers pour ces utilisateurs / groupes. P>

Table utilisateur forte>:

SELECT hasPermission( 123, 456)


4 commentaires

Si seulement tous les nouveaux arrivants à MySQL écriraient des questions comme celle-ci. +1


Ce n'est pas une réponse, mais je envisagerais de passer à PostgreSQL, si vous voulez un dB "propre". MySQL peut être vraiment ennuyeux pour des trucs avancés. J'ai changé et je ne reviens jamais.


@Davidhalter i en fait "appris" postgregesql un moment de retour, mais j'ai tout oublié tout. Maintenant, j'ai commencé avec mysql ... j'espère vraiment que tu es tort = p


@puk: hehe, c'est juste une question de savoir ce que vous voulez: MySQL est rapide et sale, Postgres est propre et la voie Unix ...


3 Réponses :


2
votes
  1. Vérifiez si le fichier 123 est lisible par Autre code> strong> p>

    Vous avez dit que cela est assez trivial, mais pour la complétude: p>

    SELECT
       (SELECT READ FROM FILE WHERE ID = 123)
    OR (SELECT READ FROM FILEUSERPERMISSIONS WHERE FILEID = 123 AND USERID = 456)
    OR (SELECT READ FROM FILEGROUPPERMISSIONS JOIN GROUPMEMBERSHIP USING (GROUPID)
        WHERE FILEID = 123 AND USERID = 456);
    
  2. Vérifiez si l'utilisateur 456 a lu les autorisations sur le fichier 123 strong> p>

    Vous pouvez le faire avec une recherche similaire dans la table FileUserMissions Code> Table: P>

    SELECT READ
    FROM FILEGROUPPERMISSIONS JOIN GROUPMEMBERSHIP USING (GROUPID)
    WHERE FILEID = 123 AND USERID = 456;
    
  3. Vérifiez si l'utilisateur 456 est dans un groupe qui a lu des autorisations de lecture sur fichier 123 forte> p>

    Pour accomplir cela, vous devez Rejoindre le Adhésion de groupe Code> et Autorisations de groupe de fichiers Code> Tables: P>

    SELECT READ
    FROM FILEUSERPERMISSIONS
    WHERE FILEID = 123 AND USERID = 456;
    


9 commentaires

Comment aurais-je ou ces trois ensemble? Aurais-je besoin de DÉCLARE VARIABLES DEFORMER ALORS SELEZ UNE SELECT SELECT LIRE IN , puis utilisez une instruction IF pour retourner true ou false? Merci


Il existe de nombreuses manières différentes ... vous pouvez construire une seule question Sélectionner qui combine chacune de ces valeurs avec le ou opérateur ; Vous pouvez utiliser un si instruction < / a> qui place un tel opérateur entre des requêtes séparées; Vous pouvez imbriquer les requêtes dans leur propre si déclarations; Ou oui, comme vous le suggérez, vous pourriez Sélectionnez. .. dans variables et faites ce qui précède sur ceux-ci.


@puk: voir ci-dessus pour une suggestion.


Merci. Merveilleusement expliqué.


Merci pour la grande réponse, je choisirai l'un de ces deux comme une réponse dès que je parviende à mettre en œuvre les deux et à tester le meilleur. Acclamations.


Restructuration toujours de l'ensemble de mon DB (devez ajouter des vues, puis les utilisateurs, puis testez ceci) d'où je n'ai pas sélectionné de réponse ici. Je vais aussi vite que je peux =)


J'ai eu une question rapide (je suis prêt à la poster comme une toute nouvelle si vous aimez), mais si ma sous-requête appelle à nouveau la même table, c'est-à-dire Créer une vue x comme sélectionnez * de y où (sélectionnez un De z joindre y sur z.y_id = y.id où yb = b) . Je veux fondamentalement savoir quelle est la portée du B est ici. Y a-t-il un moyen de y référer à l'extérieur?


@puk: Votre requête n'a pas beaucoup de sens ... où (sélectionnez un ...) ? Je ne sais pas ce que vous essayez d'atteindre. Peut-être mieux comme une nouvelle question, si rien d'autre parce que l'espace supplémentaire d'explication?


Merci de votre aide. J'ai finalement choisi la réponse d'Arion lorsque j'ai utilisé sa suggestion de "valoriser ma fonction" en retournant une table de tous les fichiers.



2
votes

Pour vérifier le droit pour un fichier. Je le ferais probablement comme ceci: xxx

mais si vous voulez vraiment valoriser votre fonction. Je suggérerais d'utiliser une fonction de table et de fournir simplement le userid . Afin que vous puissiez obtenir tous les fichiers que l'utilisateur a accès à. Cela ressemblera à quelque chose comme ceci: xxx

et d'ailleurs. La question était bonne. Cela devrait être un exemple de comment poser une question


3 commentaires

Merci pour la réponse et les louanges. Cependant, être complètement honnête, ce n'est pas ma première question.


Merci pour la grande réponse, je choisirai l'un de ces deux comme une réponse dès que je parviende à mettre en œuvre les deux et à tester le meilleur. Acclamations.


En regardant votre deuxième suggestion, il y a beaucoup de choses que je ne comprends pas: qu'est-ce que où existe ? Qu'est-ce que Sélectionnez NULL ? Que se passe-t-il dans joindre si des tableaux ont des colonnes avec le même nom (c.-à-d. creation_date )? Pourquoi avez-vous et toutes les conditions ensemble, si certaines d'entre elles ne sont pas ou ? Pourquoi y a-t-il un deuxième clause?



0
votes

Pour complétude, je pose également ma solution sur la manière dont j'ai résolu ce problème. Ma motivation initiale consistait à créer une fonction pour voir si un utilisateur Linux (c.-à-d. user1 ) a accès à un autre utilisateur de Linux (c.-à-d. user2 ) dossier home (c.-à-d. Si user1 a des autorisations de lecture sur / home / user2 ). J'utiliserais alors cette fonction lors de la construction d'une vue pour chaque utilisateur MySQL à l'aide de la fonction utilisateur () (en supposant que les noms d'utilisateur MySQL et les noms d'utilisateur Linux soient un à un). Grâce à la suggestion d'Arion, je crée à la place une vue en utilisant des jointures à la place.

Remarque, aux fins de cet exemple, le dossier est stocké dans la table .

user_View Voir: < / strong> xxx

edit: Je crois au lieu d'émettre une commande comme xxx

Je peux juste faire xxx

qui est accompli en pratique si vous souhaitez copier 10 colonnes


0 commentaires