2009-07-01 130 views
2

我在web應用中實施家庭釀造ACL系統,它給我很難。我相信這是微不足道的,只是無法擺脫它。加入查詢時遇到問題

我有一個3個表一對多的關係:
resourceperms_groupperms_users 其中perms_group是一個關鍵的表,而如果需要perms_users allowes我每用戶的基礎上微調訪問(這加起來perms_users或者只是簡單地覆蓋它,兩個表將權限作爲布爾值存儲在單獨的列中)。

我想從資源的東西,以及獲取權限在單一的查詢:

SELECT * 
FROM resource 
LEFT OUTER JOIN perms_groups ON resource.id = perms_group.res_id 
LEFT OUTER JOIN perms_users ON resource.id = perms_users.res_id 
WHERE resource.id = 1 
    AND perms_group.group_id = 2 
    AND perms_users.user_id = 3 

現在的麻煩是,用戶精細的權限將被設置很少或以上的查詢將返回在這樣的0行案件。我想說的是讓我回到組2和3用戶3 ,如果有任何設置。基本上我缺少AND_IF_EXISTS運算符;)。我可以很容易地在兩個查詢中分解它,但是因爲它會在每次頁面刷新時運行,所以我需要儘可能精簡它。目前我正在使用MySQL,但稍後想要切換到PostgreSQL,所以理想的解決方案將獨立於數據庫。有任何想法嗎?

感謝

回答

4
SELECT * 
FROM resource 
LEFT OUTER JOIN perms_groups ON resource.id = perms_group.res_id 
          AND perms_group.group_id = 2 
LEFT OUTER JOIN perms_users ON resource.id = perms_users.res_id 
          AND perms_users.user_id = 3 
WHERE resource.id = 1 

事實上,左外連接是無用的,如果你寫在桌子上的情況,當你不知道你是否有數據。

0

如果您將您的權限連接(左外連接)爲一行,則可以使用CASECOALESCE來實現您所需的內容。

1

你可以嘗試在WHERE子句移動到一起,爲用戶&組...

SELECT * 
FROM resource 
     LEFT OUTER JOIN perms_groups ON resource.id = perms_group.res_id AND perms_group.group_id = 2 
     LEFT OUTER JOIN perms_users ON resource.id = perms_users.res_id AND perms_users.user_id = 3 
WHERE resource.id = 1  
0

如果您的用戶權限覆蓋組的權限,使用此:

SELECT permission 
FROM resource 
JOIN perms_users 
ON  perms_users.res_id = resource.id 
WHERE resource.id = 1 
     AND user_id = 3 
UNION ALL 
SELECT permission 
FROM resource 
LEFT JOIN 
     perms_groups 
ON  perms_group.res_id = resource.id 
     AND group_id = 2 
WHERE resource.id = 1 
LIMIT 1 

這將效率更高,因爲如果該查詢在perms_users中找到記錄,它甚至不會查看perms_groups