2012-05-02 4 views
3

各私はあなたに私のmysqlのクエリで使用するテーブル間の関係の図を与えることから始めましょう:MySQLのクエリ、さまざまな参加型の

table relationship http://eintranet.r717.net/index_htm_files/perm_relationships.png

私が見えるのクエリを持っていますこのように:

SELECT * 
FROM `permissions` 
WHERE `id` IN (
    SELECT  pr.perm_id 
    FROM  `user_roles` as ur 
    LEFT JOIN `permissions_role` as pr 
    ON   ur.role_id = pr.role_id 
    WHERE  ur.user_id = '$userid' 
) 
OR  `id` IN (
    SELECT  `perm_id` 
    FROM  `permissions_user` 
    WHERE  `user_id` = '$userid' 
) 

$userid現在のユーザのユーザテーブルからIDです。私は彼/彼女の役割彼/彼女のIDに基づいて、ユーザーに割り当てられたすべての権限を表す配列に結果から許可名を格納します。

<?php 
$user_perms = array(); 
if(mysql_num_rows($query) > 0): 
    while($result = mysql_fetch_array($query): 
     $user_perms[] = $result('name'); 
    endwhile; 
endif; 
?> 

print_r($user_perms);は次のような出力を生成します私が何をしたいか

Array ( 
    [0] => ACCESS_TELEPHONELIST_PAGE 
    [1] => ACCESS_VACATIONSCHED_PAGE 
    [2] => ACCESS_TOURSCHED_PAGE 
    [3] => ACCESS_WORKSCHED_PAGE 
    [4] => ACCESS_RESOURCES_LINKS 
    [5] => ACCESS_PMTOOL_PAGE 
    [6] => ACCESS_TOOLSTOOL_PAGE 
    [7] => ACCESS_SHOPTOOLLIST_PAGE 
    [8] => ACCESS_TOOLINVENTORY_PAGE 
    [9] => ACCESS_MANAGETOOLLIST_PAGE 
    [10] => ACCESS_TOOLREPORTS_PAGE 
    [11] => ACCESS_JOBSLIST_LINKS 
    [12] => MAIN_TAB_TOOLSTOOL 
    [13] => ADMIN_TAB_PODMANAGEMENT 
    [14] => TOOL_TAB_SHOPTOOLLIST 
) 

は、2番目のクエリを行うことなく、別の配列にもへのユーザーの役割の店すべてです。私は、サブクエリの別名を使用するために必要と思ったので、私はこのクエリを試してみました:

SELECT  permissions.*, usersroles.role_id 
FROM  `permissions` 
INNER JOIN (
    SELECT  ur.user_id, pr.perm_id, ur.role_id 
    FROM  `user_roles` as ur 
    LEFT JOIN `permissions_role` as pr 
    ON   ur.role_id = pr.role_id 
    WHERE  ur.user_id = '$userid' 
) AS usersroles ON usersroles.perm_id = permissions.id 
INNER JOIN (
    SELECT  `perm_id`, `user_id` 
    FROM  `permissions_user` 
    WHERE  `user_id` = '$userid' 
) AS userperms ON userperms.user_id = usersroles.user_id 
       AND userperms.perm_id = permissions.id 

と、上記のコードのようなコードを使用して...

<?php 
$user_perms = array(); 
$user_roles = array(); 
if(mysql_num_rows($query) > 0): 
    while($result = mysql_fetch_array($query): 
     $user_perms = $result('name'); 
     $user_roles = $result('role_id'); 
    endwhile; 
endif; 
?> 

...私はこれを取得します警告:

Warning: mysql_num_rows() expects parameter 1 to be resource, boolean given 

しかし、私はprint_r($user_roles);したいと、このような出力を生成します:

Array (
    [0] => administrator 
    [1] => humanresources 
    [2] => podmanager 
) 

誰もが私が間違っているのを教え、または私は配列にクエリから必要なデータを取得するためのより良い方法を提案することはできますか?

EDIT:慎重に検討した後、ImreLが提案するように2つのクエリを使用するようにコードを変更しました。生成されたコードはうまく動作し、素早く実行されます。私は使用した最終コードを表示するために私の答えを編集し、2つのクエリをどのように使用しているかを示すサポートコードを追加しました。 ImreLに大きな感謝!

+2

ニース図:)どのようなツールを使用すると、それを作成するために使用しましたか? –

+0

私はMicrosoft Accessを使用しました...テーブルを作成し、関係をセットアップしてから、デザインビューに行き、グラフィックスプログラムでスクリーンショットを撮りました。 –

+0

@Neil私の投稿を編集し、図を追加していただきありがとうございます! :) –

答えて

2

クエリは、ユーザーが読み込むすべてのページで実行する必要があり、 には30,000を超えるアクセス権と3,000の役割があります。私はちょうど試みている非常に ハード私のクエリの数を最小限に保つために。

Iを(残念ながら私はこのを制御することはできません )当社はまた、当社オフィス内のサーバー上で私たちの7つの サイトをホストし、サーバは、我々が発生するトラフィックの量を処理できる をしていないようですあなたの意図が優れていることがわかりますが、私はあなたにこのことを教えてみましょう:

「クエリの数は、」サイトのパフォーマンスを測定するための正しい方法ではありません。

多くの場合、2つの単純なクエリは、1つの複合体より少ないリソースを使用します。

はまた、あなたのサイトを高速化する他の方法があります:あなたは本当に要求ごとにロードされたすべてのそれらの役割と権限を必要とする場合

  • を評価します。たぶん、必要な役割/権限のみを照会するだけで十分です。
  • は私が頼まれたものを満たすために、クエリを思い付くしようとした、
  • だから、最終的には

を負荷(サイトのコンテンツ)を低減するためにキャッシュ技術を活用し、適切なインデックスを持っている:

select * from (
    select ur.role_id, p.* 
    from user_roles ur 
    left join permissions_role pr on ur.role_id = pr.role_id 
    left join permissions p on p.id = pr.perm_id 
    where ur.user_id = '$userid' 
    union all 
    select null as role_id, p.* 
    from permissions_user pu 
    join permissions p on p.id = pu.perm_id 
    where pu.user_id = '$userid' 
) sub 
group by ifnull(name,role_id) -- group by to eliminate duplicates 

しかし、これはパフォーマンスが良くありません。 あなたは2つのクエリでオフはるかに優れている:第一には、すべての役割を取得するには、ユーザー

select p.* from permissions p 
join permissions_role pr on pr.perm_id = p.id 
join user_roles ur on ur.role_id = pr.role_id and ur.user_id = '$userid' 
union 
select p.* from permissions p 
join permissions_user pu on pu.perm_id = p.id and pu.user_id = '$userid'; 

と第二のためにすべての権限を取得します。

+0

ご協力いただきありがとうございます。質問を見る他の人のためのFYI ...私はまた、最終的な作業照会と照会がどのように使用されるかを示すためのサポートコードを反映する回答を掲載しました。 –

0

編集:ここに最終的な作業クエリがあります。また、他の人がどのようにクエリを使用しているのか分かりやすいと思ったので、完全な説明が含まれています。

//build the array(s) 
$userperms = array(); 
$userroles = array(); 
if(isset($_SESSION['userid'])): 
    //get the userid 
    $thisuserid = $_SESSION['userid']; 
    //get the permissions for each of the user's roles 
    $Cpermissions_role = mysql_query(" 
    SELECT  r.type, ur.user_id, pr.perm_id, ur.role_id, p.name 
    FROM  user_roles ur 
    LEFT JOIN permissions_role pr ON ur.role_id = pr.role_id 
    LEFT JOIN roles r ON ur.role_id = r.id 
    LEFT JOIN permissions p ON p.id = pr.perm_id 
    WHERE  ur.user_id = '$userid'") or die(mysql_error()); 
    //get the extra permissions for the user 
    $Cpermissions_user = mysql_query(" 
    SELECT  pu.user_id, pu.perm_id, p.name 
    FROM  permissions_user pu 
    LEFT JOIN permissions p ON p.id = pu.perm_id 
    WHERE  pu.user_id = '$userid'") or die(mysql_error()); 
    //build an array of the user's roles & an array of the user's permissions 
    if(mysql_num_rows($Cpermissions_role) > 0): 
     while($Rpermissions_role = mysql_fetch_array($Cpermissions_role)): 
      if(empty($userperms)): 
       $userperms[] = $Rpermissions_role['name']; 
      elseif(!in_array($Rpermissions_role['name'],$userperms)): 
       $userperms[] = $Rpermissions_role['name']; 
      endif; 
      if(empty($userroles)): 
       $userroles[] = $Rpermissions_role['type']; 
      elseif(!in_array($Rpermissions_role['type'],$userroles)): 
       $userroles[] = $Rpermissions_role['type']; 
      endif; 
     endwhile; 
    endif; 
    if(mysql_num_rows($Cpermissions_user) > 0): 
     while($Rpermissions_user = mysql_fetch_array($Cpermissions_user)): 
      if(empty($userperms)): 
       $userperms[] = $Rpermissions_user['name']; 
      elseif(!in_array($Rpermissions_user['name'],$userperms)): 
       $userperms[] = $Rpermissions_user['name']; 
      endif; 
     endwhile; 
    endif; 
endif; 
/** 
* Determines if the user has permission for the page or parts of page 
* @param string $perm the permission constant 
* @return boolean true if user has access, false if not 
*/ 
function hasPermission($perm){ 
    global $userperms; 
    if(empty($userperms)): 
     return false; 
    else: 
     if(is_array($userperms)): 
      if(in_array($perm,$userperms)): 
       return true; 
      else: 
       return false; 
      endif; 
     else: 
      if($perm == $userperms): 
       return true; 
      else: 
       return false; 
      endif; 
     endif; 
    endif; 
} 

はその後、私は次の決定文で使用しますので、

if(hasPermission("ACCESS_HOME_PAGE")): 
    //perform circus tricks here 
endif; 

を、今print_r($userperms);この出力:

Array ( 
    [0] => ACCESS_TELEPHONELIST_PAGE 
    [1] => ACCESS_VACATIONSCHED_PAGE 
    [2] => ACCESS_TOURSCHED_PAGE 
    [3] => ACCESS_WORKSCHED_PAGE 
    [4] => ACCESS_RESOURCES_LINKS 
    [5] => ACCESS_PMTOOL_PAGE 
    [6] => ACCESS_TOOLSTOOL_PAGE 
    [7] => ACCESS_SHOPTOOLLIST_PAGE 
    [8] => ACCESS_TOOLINVENTORY_PAGE 
    [9] => ACCESS_MANAGETOOLLIST_PAGE 
    [10] => ACCESS_TOOLREPORTS_PAGE 
    [11] => ACCESS_JOBSLIST_LINKS 
    [12] => MAIN_TAB_TOOLSTOOL 
    [13] => ADMIN_TAB_PODMANAGEMENT 
    [14] => TOOL_TAB_SHOPTOOLLIST 
    [15] => ACCESS_HOME_PAGE 
) 

そして、print_r($userroles);これを出力:

Array ( 
    [0] => administrator 
    [1] => humanresourcees 
    [2] => podmanager 
) 

そして、ちょうどt

var js_userperms = new Array(); 
js_userperms = ["<?php echo join("\", \"", $userperms); ?>"]; 

そして、jQueryの決定書:O徹底すること、ここで私はPHPの配列にアクセスするために使用するJavaScriptです

if(jQuery.inArray("ACCESS_HOME_PAGE", js_userperms) != -1){ 
    //perform circus tricks here 
} 
+0

クエリがひどく間違っていたためにDownvoted。あなたは今のところそれを削除しました。 –

+0

私はその質問に答えようとしました。数時間後にあなた自身の答えを受け入れて以来、私はもっと時間を寄せる気がしませんでした。乾杯。 –

関連する問題