2008-11-17 173 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字符串更容易閱讀。