1

私は自分でこの答えを見つけようとしてきましたが、それにはあまりにも悪いので、あなたが私を助けてくれることを願ってここに来ました.

次のデータベース テーブルがあります。

user(
    int unsigned id,
    varchar      login
)
group(
    int unsigned id,
    varchar      label
)
right(
    int unsigned id,
    varchar      label
)
user_group(
    int unsigned userId,
    int unsigned groupId
)
user_right(
    int unsigned userId,
    int unsigned rightId,
    boolean      granted
)
group_right(
    int unsigned groupId,
    int unsigned rightId,
    boolean      granted
)

および 3 つの構成パラメーター (PHP が定義) :

  • GRANTED_BY_DEFAULTTRUEまたはにすることができますFALSE。グループまたはユーザーに対して権限が指定されていない (関連付けテーブルにない) 場合に、権限が付与されているかどうかを示します。

  • RESULTING_RIGHTSMIN_RIGHTSまたはにすることができますMAX_RIGHTS。結果として生じる権利を決定する際に、「AND」または「OR」演算子を使用するかどうかを示します。たとえば、権限 "r1" に対して、グループ "g1" が TRUE で、グループ "g2" と "g3" が FALSE の場合、"MIN_RIGHTS" で FALSE、"MAX_RIGHTS" で TRUE になります。

  • RIGHTS_PRIORITYUSER_OVER_GROUPまたはにすることができますGROUP_OVER_USER。ユーザー自身の権限がグループの権限をオーバーライドするか、グループの権限がユーザー自身の権限をオーバーライドするかを示します。

これらの 3 つのパラメーターとそのグループを考慮して、ユーザーが実際に持っている権利を見つける単一のクエリを作成したいと思いますが、その方法については本当にわかりません。複数のクエリを作成し、PHP 側で作業の一部を行うこともできますが、AJAX オートコンプリートやその他のものに対してアプリを十分に高速にしたいので、多くのクエリを実行する必要は避けたいと思います。

誰も私を助けたくない、または時間がない場合は理解できます:p読んでくれてありがとう。

EDIT:いくつかのサンプルデータ:

user (id, login) :
1 "Admin"

group (id, label) :
1 "g1"
2 "g2"
3 "g3"

right (id, label) :
1 "r1"
2 "r2"
3 "r3"

user_group (userId, groupId) :
1 1
1 2

user_right (userId, rightId) :
1 1 true
1 2 false

group_rights (groupId, rightId) :
1 1 true
1 2 false
2 1 false
2 3 true

出力は、パラメーターと他のテーブルの行に応じて (right_id, right_label) 行のリストになります。

ユーザー ID および / またはログインは、権限を取得する際に既知のものと見なされます。

4

1 に答える 1

2
DECLARE @USERID INT = 1,
        @GRANTED_BY_DEFAULT INT = 0,
        @RESULTING_RIGHTS VARCHAR(20) = 'MIN_RIGHTS',
        @RIGHTS_PRIORITY VARCHAR(20) = 'USER_OVER_GROUP'

SELECT 
    R.ID,
    R.NAME,
    CASE
        WHEN MAX(UR.Value) IS NULL AND MAX(GR.Value) IS NULL THEN
            @GRANTED_BY_DEFAULT
        WHEN MAX(UR.Value) IS NOT NULL AND MAX(GR.Value) IS NOT NULL THEN
            CASE
                WHEN @RIGHTS_PRIORITY = 'USER_OVER_GROUP' THEN
                    MAX(UR.Value)
                ELSE
                    CASE 
                        WHEN @RESULTING_RIGHTS = 'MIN_RIGHTS' THEN
                            MIN(GR.Value)
                        ELSE
                            MAX(GR.Value)
                    END
            END
        WHEN MAX(GR.Value) IS NULL THEN
            MAX(UR.Value)
        ELSE
            CASE
                WHEN @RESULTING_RIGHTS = 'MIN_RIGHTS' THEN
                    MIN(GR.Value)
                ELSE
                    MAX(GR.Value)
            END
    END VALUE
FROM
    [Right] R
    CROSS JOIN [User] U
    LEFT JOIN [User_Right] UR
        ON R.ID = UR.RightID
        AND UR.UserID = U.ID
    LEFT JOIN [User_Group] UG
        ON UG.UserID = U.ID
    LEFT JOIN [Group_Right] GR
        ON UG.GroupID = GR.GroupID 
        AND GR.RightID = R.ID
WHERE
    U.ID = @USERID
GROUP BY 
    R.ID,
    R.NAME

ここに SQL フィドルの例があります SQL フィドル

于 2012-11-13T16:21:27.670 に答える