2008-11-17 131 views
0

是否有任何已知的模式/算法如何以正确的方式执行排序或筛选记录列表(从数据库)?我目前的尝试涉及使用提供一些过滤和排序选项的表单,然后将这些条件和排序算法附加到我现有的SQL。但是,我发现它很容易被滥用,用户可能会得到他们无法看到的结果。排序和筛选记录

我正在构建的应用程序是一个调度程序,用于将所有事件存储在数据库表中。然后根据用户的级别/角色/权限显示不同的数据子集。所以我的查询可以那样复杂

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' 

正如我对服务的信息的正确子集更值得关注,表现不是目前的主要问题(如提到的SQL由脚本,条款所产生的条款)。我正在考虑将所有这些复杂的SQL语句转换为视图,因此生成的SQL不适用的可能性会降低。

回答

0

这是很难理解的查询,因为我有大量滚动,因为我不知道数据库...

但如果privilegues是“一维”,例如管理员可以看到的一切,电力用户可以看到比管理员少,客人可以看到比电力用户等少:你很可能实现privilegues在这两个事件和用户的整数,然后

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

如果你可以将权限值设置为10000(高/管理),5000,1(最低/客户),你可以稍后添加更多级别而不更改所有代码。

+0

这里的标准并不是真正的主要问题,我正在寻找一种更好的方法来做过滤和排序....在sql查询中,它实际上考虑用户是否可以读取他/她的记录,是记录在正确的类别中,正确的状态等。 – Jeffrey04 2008-11-17 08:54:56

0

使用ORM工具或使用参数,如:

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

首先,这个查询将外观和性能更好,如果你使用的联接:

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' 
     ) 

这是一个良好的开端保持复杂了。然后,如果您想直接向SQL添加其他过滤器,则可以在最后附加更多“AND ...”语句。由于所有标准都与AND连接(OR安全地包含在圆括号内),因此在某些标准取消了上述标准之后,不可能有人添加标准 - 也就是说,一旦您限制了结果的一部分子句,如果它与AND一起串联,则不能用后面的子句“解除”它。 (当然,如果这些附加子句放在用户文本输入附近的任何地方,则必须对它们进行清理以防止SQL注入攻击。)

数据库可以比其他任何层更快地过滤,因为一般情况下,因为使用WHERE子句数据库通常会允许数据库避免从磁盘读取不必要的记录,这比使用CPU所能做的任何事情都要慢几个数量级。数据库中的排序通常也会更快,因为数据库通常可以按照您希望的顺序对记录进行排序的方式进行连接。所以,性能方面,如果你可以在数据库上做到这一点,那就更好了。

你说性能在这里并不是真正的关键,因此,在业务逻辑中以编程方式添加过滤器对你来说可能没有问题,而且比读取SQL字符串更容易阅读。