2008-11-17 6 views
0

est-il un motif connu/algorithme sur la façon d'effectuer le tri ou le filtrage d'une liste d'enregistrements (de base) de la manière correcte? Ma tentative actuelle implique l'utilisation d'un formulaire qui fournit des options de filtrage et de tri, puis j'ajoute ces critères et l'algorithme de tri à mon SQL existant. Cependant, je trouve qu'il peut être facilement abusé que les utilisateurs peuvent obtenir des résultats qu'ils ne sont pas censés voir.tri et le filtrage Documents

L'application que je suis bâtiment est un planificateur où je stocke tous les événements dans une table de base de données. Ensuite, en fonction du niveau/rôle/privilège de l'utilisateur, un sous-ensemble de données différent sera affiché. Par conséquent, ma requête peut être aussi compliqué que

SELECT * 
FROM app_event._event_view 
WHERE ((class_id = (SELECT class_id FROM app_event._ical_class WHERE name = 'PUBLIC') AND class_id != (SELECT class_id FROM app_event._ical_class WHERE name = 'PRIVATE') AND class_id != (SELECT class_id FROM app_event._ical_class WHERE name = 'CONFIDENTIAL')) OR user_id = '1') 
     AND calendar_id IN (SELECT calendar_id FROM app_event.calendar WHERE is_personal = 't') 
     AND calendar_id = (SELECT calendar_id FROM app_event.calendar WHERE name = 'personal') 
     AND state_id IN (1,2,3,4,5,6) AND EXTRACT(year FROM dtstart) = '2008' 
     AND EXTRACT(month FROM dtstart) = '11' 

Comme je suis plus préoccupé de servir le sous-ensemble correct de l'information, les performances ne sont pas une préoccupation majeure au moment (comme sql mentionné a été généré par le script, clause par clause). Je pense à transformer toutes ces instructions SQL compliquées en vues, donc il y aura moins de chances que le SQL généré soit inapproprié.

Répondre

0

Il est difficile de comprendre cette requête, parce que je dois faire défiler massivement et depuis que je ne connais pas la base de données ...

Mais si les privilegues sont « unidimensionnelle », par exemple admins peuvent tout voir, les utilisateurs de puissance peuvent voir moins admins, les clients peuvent voir moins que les utilisateurs de puissance, etc .: vous pourriez probablement mettre en œuvre les privilegues comme un entier dans l'événement et l'utilisateur, puis

select from event where conditions AND event.privilegue <= user.privilegue 

Si vous définissez les valeurs de privilège quelque chose comme 10 000 (haut/admin), 5000, 1 (plus bas/invité), vous pouvez ajouter plus de niveaux entre les deux sans changer tout votre code.

+0

les critères ne sont pas vraiment un problème majeur ici, je suis à la recherche d'une meilleure façon de faire filtrer et trier .... sur la requête SQL, il considère en fait que l'utilisateur peut lire ses/ses dossiers, est le enregistrer dans la catégorie correcte, l'état correct, etc. – Jeffrey04

+0

Je ne pense pas que je comprends ce que vous entendez par filtrage, alors ... S'il vous plaît expliquer. –

0

Utilisez les paramètres de l'outil ORM ou utiliser comme:

SELECT * 
FROM app_event._event_view 
WHERE 
    (
     :p_start_year is null or 
     (state_id IN (1,2,3,4,5,6) AND EXTRACT(year FROM dtstart) = :p_start_year) 
    ) 
    and 
    (
     :p_date_start is null or 
     AND EXTRACT(month FROM dtstart) = :p_date_start 
    ) 
1

Tout d'abord, cette requête va chercher et obtenir de meilleurs résultats si vous utilisez Jointures:

SELECT * 
    FROM  
    app_event._event_view EV 
    INNER JOIN app_event.calendar C 
     ON EV.calendar_id = C.calendar.id 
    INNER JOIN app_event._ical_class IC 
     ON C.class_id = EV.class_id 
    WHERE 
    C.is_personal = 't' 
    AND C.name = 'personal' 
    AND state_id IN (1,2,3,4,5,6) 
    AND EXTRACT(year FROM dtstart) = '2008' 
    AND EXTRACT(month FROM dtstart) = '11' 
    AND (
     IC.name = 'PUBLIC' -- other two are redundant 
     OR user_id = '1' 
     ) 

C'est un bon début pour garder la complexité vers le bas. Ensuite, si vous souhaitez ajouter des filtres supplémentaires directement au SQL, vous pouvez ajouter d'autres instructions "AND ..." à la fin. Étant donné que tous les critères sont liés à ET (OU est en toute sécurité se trouve entre parenthèses), il n'y a aucune possibilité de quelqu'un d'ajouter un critère après ceux-ci qui annule en quelque sorte ceux ci-dessus - ce qui est, une fois que vous avez limité les résultats avec une partie d'un clause, vous ne pouvez pas la "dé-restreindre" avec une clause ultérieure si elle est liée avec des AND. (Bien sûr, si ces clauses supplémentaires se trouvent à proximité des entrées de texte utilisateur, vous devez les nettoyer pour éviter les attaques par injection SQL.)

La base de données peut filtrer plus rapidement que tout autre niveau, en général, car l'utilisation d'une clause WHERE sur la base de données permet souvent à la base de données d'éviter même de lire les enregistrements inutiles sur le disque, ce qui est de plusieurs ordres de grandeur plus lent que tout ce que vous pouvez faire avec le CPU. Le tri est également plus rapide sur la base de données, car la base de données peut souvent effectuer les jointures de telle sorte que les enregistrements sont déjà triés dans l'ordre souhaité. Donc, la performance sage, si vous pouvez le faire sur la DB, tant mieux.

Vous avez dit la performance n'est pas vraiment la clé ici, cependant, si l'ajout de filtres dans la logique programatically d'affaires pourrait être bien pour vous, et plus facile à lire que de jouer avec des chaînes SQL.