0

我在加入 sql 时遇到问题。我有 3 张桌子。

1: Lists the user details
2: Lists the permissions the user group has
3: Lists the page that that group can access

 

   Table1 users :
   ****************************************
   username |  group
   ****************************************
   admin    |  administrator 


   Table2 groups :
   *********************************************
   user_group    | create | view | system_admin
   *********************************************
   administrator |   1    |   0  |      1


   Table3 urls:
   *********************************************
   create     |  view      | system_admin
   *********************************************
   create.php |  view.php  |  system.php

(为我的表格图道歉)

我正在通过 php 做的是获取他们所属的 user_group。然后我需要检查他们是否可以访问他们刚刚点击的页面或将他们重定向回来。

我可以通过连接的方式使用当前的表格布局来实现这一点吗?或者我应该重新设计这些表格,因为它们对于这种事情并不直观。

4

3 回答 3

2

实际上,我可能会重新设计表格以使它们更易于查询:

create table users
(
    id int,
    username varchar(10),
    groupid int
);
insert into users values (1, 'admin', 1);

create table groups
(
    groupid int,
    groupname varchar(20)
);
insert into groups values (1, 'administrator');

create table permissions
(
    permissionid int,
    permissionname varchar(20)
);
insert into permissions values (1, 'create');
insert into permissions values (2, 'view');
insert into permissions values (3, 'system_admin');

create table urls
(
    urlid int,
    name varchar(10)
);
insert into urls values(1, 'create.php');
insert into urls values(2, 'view.php');
insert into urls values(3, 'system.php');

create table group_permission_urls
(
    groupid int,
    permissionid int,
    urlid int
);
insert into group_permission_urls values(1, 1, 1);
insert into group_permission_urls values(1, 0, 2);
insert into group_permission_urls values(1, 3, 3);

那么您的查询将与此类似:

select *
from users us
left join groups g
  on us.groupid = g.groupid
left join group_permission_urls gpu
  on us.groupid = gpu.groupid
left join permissions p
  on gpu.permissionid = p.permissionid
left join urls u
  on gpu.urlid = u.urlid

SQL Fiddle with Demo

于 2012-09-12T16:42:26.670 回答
0

通过将$current_page与子查询的结果进行比较IN(),您可以在一个查询中执行此操作。如果页面与用户有权访问的列中列出的任何内容匹配,则将返回一行。如果允许的列中没有匹配项,则不应返回任何行。

SELECT
  groups.create,
  groups.view, 
  groups.system_admin,
  1 AS can_access
FROM 
  users
  JOIN groups ON users.group = groups.user_group 
WHERE 
  users.username = '$some_username'
  AND (
    /* Substitute the current page. Better, use a prepared statement placeholder if your API supports it */
    (groups.create = 1 AND '$current_page' IN (SELECT DISTINCT create FROM urls))
    OR 
    (groups.view = 1 AND '$current_page' IN (SELECT DISTINCT view FROM urls))
    OR 
    (groups.system_admin = 1 AND '$current_page' IN (SELECT DISTINCT system_admin FROM urls))
  )

这通过将 与$current_page您的 3 列中的每一列中的不同的可能值集进行比较来工作。如果它匹配列并且用户的组对该类型具有权限,则返回一行。

于 2012-09-12T16:37:50.257 回答
0
select case when count(1) > 0 then 'come in' else 'go away' end 
from users, groups, urls
where 
users.username = '$username' and
users.user_group = groups.user_group and
  ((urls.create = '$url' and groups.create = 1) or 
   (urls.view = '$url' and groups.view = 1) or 
   (urls.system_admin = '$url' and groups.system_admin = 1))
于 2012-09-12T16:39:33.993 回答