假设我有两张桌子:
--------------------------------
| user_id | permissions |
---------------------------------
| 1 | ['perm1', 'perm2'] |
---------------------------------
| 2 | ['perm1'] |
---------------------------------
----------------------------------------
| integration_id | permissions_required |
-----------------------------------------
| 1 | ['perm1'] |
-----------------------------------------
| 2 | ['perm2'] |
-----------------------------------------
| 3 | ['perm1', 'perm2'] |
------------------------------------------
我希望能够查询特定用户有权访问的所有集成。我一直在寻找一段时间,但我在这方面使用mysql相当新。
如何查询这些表以查找用户具有所有必需权限的所有集成?
编辑:我意识到我没有提到权限& permissions_required列是JSON列。基于接受的答案,我将提出重构我们的数据库权限的主题,以使用传统的多个 - >多个而不是数组答案 0 :(得分:0)
这是一个明显的例子,说明为什么在单个列中存储逗号分隔值是个坏主意。根据您的设计,您将需要拆分字符串(MySQL甚至没有内置函数),然后根据拆分结果连接表。
在正确设计的表架构上,您想要完成的任务会非常容易。
从头开始,您的实体为user
,integration
和permission
,因此您需要为每个实体提供一个表格。
User: id, name, whatever_else
Integration: id, description, whatever_else
Permission: id, description, whatever_else
user
和permission
之间的关系为many-to-many
,因为每个user
可以有多个permissions
,每个permission
都可以多个users
:你想用另一个表建模这个
UserPermission: userID, permissionID
同样适用于permission
和integration
之间的关系:每个integration
可能需要多个permissions
,每个permission
可能需要多个integrations
}}
IntegrationPermission: integrationID, permissionID
您的样本数据将如下所示
User
id | name
1 | User1
2 | User2
Permission
id | desc
1 | Perm1
2 | Perm2
UserPermission
userID | permissionID
1 | 1
1 | 2
2 | 1
Integration
id | desc
1 | Integration1
2 | Integration2
3 | Integration3
IntegrationPermission
integrationID | permissionID
1 | 1
2 | 2
3 | 1
3 | 2
现在查询:棘手的部分是让拥有集成所需权限的用户。让我们分几步建立这个。
首先,我们将两个关系表结合起来,以获得用户,集成以及用户对该集成的权限数量
select t1.userID,
t2.integrationID,
count(distinct t2.permissionID) as userIntegrationPermissions
from userPermission t1
join integrationPermission t2
on t1.permissionID = t2.permissionID
group by t1.userID, t2.integrationID
然后,我们需要计算每次集成所需的权限
select integrationID,
count(permissionID) permCount
from integrationPermission
group by integrationID
最后,我们加入这两个,添加用户和集成表来获取描述(当然这是可选的)
select tt3.id, tt3.name, tt4.id, tt4.desc
from (
select t1.userID,
t2.integrationID,
count(distinct t2.permissionID) as userIntegrationPermissions
from UserPermission t1
join IntegrationPermission t2
on t1.permissionID = t2.permissionID
group by t1.userID, t2.integrationID
) tt1
join (
select integrationID,
count(permissionID) permCount
from IntegrationPermission
group by integrationID
) tt2
on tt1.integrationID = tt2.integrationID and
tt1.userIntegrationPermissions = tt2.permCount
join User tt3
on tt1.userID = tt3.id
join Integration tt4
on tt1.integrationID = tt4.id
order by 1, 3
处理它