2012-01-07 35 views
0

我有三个表我想加入一个MySQL查询来检查用户是否有权下载照片。每张照片都有自己的访问权限,可以是以下任一权限。加入三个表来创建一个访问授权列表

一级 - 任何用户都可以下载照片。
二级 - 只有有权访问的用户才能下载照片。

表1:FILES

FILE_ID is AUTO_INCREMENT 
USER_ID is the identifier of the user that owns the file. 
FILE_NAME is just the name of the photo. 
FILE_ACCESS is the access rights to the 2 levels noted above. 

FILE_ID | USER_ID | FILE_NAME | FILE_ACCESS 
1 | 3 | 1279141923.jpg | 1 
2 | 3 | 1279141925.jpg | 1 
3 | 3 | 1279141927.jpg | 2 
4 | 4 | 1279141929.jpg | 1 
5 | 4 | 1279141931.jpg | 2 
6 | 3 | 1279141933.jpg | 2 

表2:用户

USER_ID is AUTO_INCREMENT 
USER_NAME is just the name of the file owner. 

USER_ID | USER_NAME 
1 | jack 
2 | jill 
3 | john 
4 | mike 

表3:ACCESS

ACCESS_ID is AUTO_INCREMENT 
USER_ID is the identifier of the user that owns the file. 
ALLOW_ID is the identifier of the user that has access all the file uploaded by user. 

ACCESS_ID | USER_ID | ALLOW_ID 
1 | 3 | 1 
2 | 3 | 4 

用户杰克访问下载照片1279141923.jpg1279141925.jpg1279141927.jpg那John已经上传,而Jill只能访问1279141923.jpg1279141925.jpg

Jack可以访问所有三个文件,因为文件1和2具有访问级别1,同时他还可以访问下载文件3,看到John已授予他完全访问John上传的所有文件的权限。

SELECT a.file_name, b.user_name FROM files AS a 
    JOIN users AS b ON a.user_id = b.user_id 
    WHERE a.file_access = '1' 

这MySQL查询给了我当吉尔签署以下。

1279141923.jpg, john (owner name) 
1279141925.jpg, john 
1279141929.jpg, mike 

我现在正在引进的访问表到这个查询,因此,如果吉尔在她签显示如果杰克签字,他的结果与上面相同,他会得到以下结果。

1279141923.jpg, john (owner name) 
1279141925.jpg, john 
1279141927.jpg, john 
1279141929.jpg, mike 
1279141933.jpg, john 

我希望我解释这个权利,因为我确实需要帮助最后一部分。我不太清楚如何将其添加到当前的查询中。我可以使用多个查询来做到这一点 - 但我更喜欢如果可能的话将它作为一个整体。

+0

感谢您的清理。这看起来更容易阅读。 – Tim 2012-01-07 22:21:17

回答

0
SELECT DISTINCT(F.id), F.filename 
FROM files F, ACCESS A 
WHERE F.flie_access=1 
OR (F.user_id=2) 
OR (F.user_id = A.user_id AND A.allow_id=2); 

所以,你可以,如果它是访问该文件:

1级(即公众) 或者您是所有者 或你在“访问”表中的匹配访问入口。

您似乎已将所有用户文件授予其他用户,您可能需要考虑使用“USER_ACCESS”和“FILE_ACCESS”表来授予其他人访问所有文件或特定文件的权限。

+0

我想我明白了,如果我打算有很多文件和用户将这个易于管理?我不得不做一些研究,因为我的SQL不匹配。 – Tim 2012-01-08 02:52:21

+0

昨晚我再次尝试了您的查询。我删除了第一个OR(F.user_id = 2),我得到了我期待的结果。我必须用不同的符号进行更多的测试才能确定。 – Tim 2012-01-08 13:25:28

0

添,这里是修改后的查询......

SELECT F.file_name, U.user_name 
FROM files AS F 
    INNER JOIN users AS U USING (user_id) 
    LEFT OUTER JOIN access AS A USING (user_id) 
WHERE (A.allow_id = 1 AND F.file_access IN (1, 2)) 
     OR (A.allow_id IS NULL AND F.file_access = 1) 
ORDER BY F.file_id 

随着多表连接,你必须要小心,因为这样的连接操作的内存占用量都显著大,特别是如果表很大 - 我假设他们是(或者将尽快您的应用程序拿起大量的用户流量)。有时,分离查询并不是一件坏事。

只是我的2美分...HTH

Ashwin

+0

我试过你的查询,它只会提出所有访问级别为二的文件。我正在查找所有文件访问权限,如果您授予权限,则需要访问两个文件。我添加了更多的数据,希望能够更加明白我在找什么。至于这些名称是正确的,他们将显示每个文件的所有者的名称。 – Tim 2012-01-08 02:47:39

+0

Tim,请使用新的查询查看我更新的答案。它正是你正在寻找的东西。添加的数据很有帮助。 – 2012-01-08 06:19:38

+0

谢谢,我也会试试这个。我确实运行了我得到的另一个解决方案,并删除了第一个OR,并获得了结果。还想尝试这一个,以及更快。要回答你关于内存占用问题,我确实有缓存设置,这应该有所帮助。 – Tim 2012-01-08 13:28:23