poo*_*eck 5 sql database-design user-permissions
用户可以在组中.并为项目/产品分配可以查看该项目的组.如果项目位于其中一个已分配的组中,则用户可以看到该项目.
我既不希望公开(没有组中的匿名用户)也不希望无组用户(不在任何组中的登录用户)查看该项目.但我希望界面允许为项目分配"所有/任何组"属性,以便任何组中的用户都可以看到该项目.
我应该在哪里/如何存储此作业?
ps我希望该技术也可以扩展到其他实体,例如我将文件分配给一个类别,并将组链接到类别.因此,当"全部/任何类别"将文件标记为可见时,如果用户(通过组和组类别)链接到至少一个类别,则该文件对他们可见.
决定:
似乎选择是在实体组表中实现一行还是在实体表中实现.选择的答案使用了前者.
并在表中管理组成员身份或添加JOIN条件.选择的答案使用前者,但我将使用后者.我在查询和使用之间存在间接性,因此,如果(何时)性能是一个问题,我应该能够在不改变使用情况的情况下更改为下面的托管表(如建议的那样).
我还有其他特殊群体,例如"管理员","用户"等,它们也可以比每个实体的特殊和可变字段处理更容易适应相同的概念(基础只是一个群组列表).
谢谢大家.
正如 Martin Smith 和 Mikael Eriksson 所提到的,将其作为实体的属性是一种非常简洁且直接的方法。纯粹就数据表示而言,这给人一种非常好的感觉。
然而,我也会考虑您可能对数据进行的查询。例如,根据您的描述,您似乎最有可能进行从单个用户开始的查询,找到他们所属的组,然后找到他们关联的实体。可能是这样的事情...
SELECT DISTINCT -- If both user and entity relate to multiple groups, de-dupe them
entity.*
FROM
user
INNER JOIN
user_link_group
ON user.id = user_link_group.user_id
INNER JOIN
group_link_entity
ON group_link_entity.group_id = user_link_group.group_id
INNER JOIN
entity
ON entity.id = group_link_entity.entity_id
WHERE
user.id = @user_id
Run Code Online (Sandbox Code Playgroud)
如果您要使用这种格式以及实体表中的属性的想法,您将需要一些不太优雅的东西,我认为以下 UNION 方法可能是最有效的......
<ORIGINAL QUERY>
UNION -- Not UNION ALL, as the next query may duplicate results from above
SELECT
entity.*
FROM
entity
WHERE
EXISTS (SELECT * FROM user_link_group WHERE user_id = @user_id)
AND isVisibleToAllGroups != 0
-- NOTE: This also implies the need for an additional index on [isVisibleToAllGroups]
Run Code Online (Sandbox Code Playgroud)
它不是在“我可以看到什么实体”查询中创建极端情况,而是在链接表的维护中创建极端情况的选项......
这样,原来的简单查询就可以不用修改了。这意味着不需要 UNION,它会带来排序和重复数据删除的开销,也不需要 isVisibleToAllGroups 上的 INDEX。相反,开销转移到维护用户链接到哪些组;相反,一次性开销。
这假设“我可以看到什么实体”这个问题比更改组更常见。它还添加了由数据而不是架构定义的行为,这需要良好的文档和理解。因此,我确实认为这是一种强大的优化类型,但我也将其视为一种需要在数据库设计中考虑的权衡类型的妥协。
| 归档时间: |
|
| 查看次数: |
105 次 |
| 最近记录: |