我正在尝试为用户添加在合同/站点/实验中以给定角色进行授权的能力。
更具体地说,我希望用户能够在合同上拥有角色 A,但同时在同一合同的特定站点上拥有角色 B,并且可能在该站点的实验上拥有角色 C。
User
我的第一个想法是在和之间建立一个连接表,Role
其中第三列存储合同,站点或实验的 ID。
在我看来,这个解决方案有很多问题:
- 我需要一行来记录合同、每个授权站点和每个授权实验。它可以快速增长到很大。
- 缺乏完整性。可以引用不存在的合约
- 如果我想知道用户被授权的合同的所有站点和实验,我必须首先查询此合同的所有站点,然后查询这些站点的所有实验,然后找到引用这些 ID 的所有行。这似乎有点不靠谱。
我觉得这个解决方案可行,但我想知道是否还有其他方法?也许是一些我不知道的模式?
PS:我正在使用 MySQL v8
这可能是第一次向墙上扔湿面条的好方法。这里的 person_role 表有点奇怪。contract_id、site_id 和 experiment_id 可空,应该有一个检查约束来确保其中只有一个不为空。有了这个,您可以使用级联方法。如果一个人正在做实验,但在该实验中没有为他明确设置任何权限,那么他将使用他在站点级别的权限。合同也是如此。
在较低级别授予/拒绝的任何特权都会胜过较高级别的设置。
感谢@Doug Hills 的回答,我调整了我的初始模式并最终得到了这个模式
siteId
我用 3 个外键(并且可空)替换了多态列experimentId
,并从 role_privilege 中删除了拒绝/访问并将其添加autoGrantAccess
到 person_role。autoGrantAccess
是一个布尔值,如果为 true,则表示用户已获得所有子资源的授权,如果为 false,则表示子资源必须明确授权。这有点奇怪,但这是一种在用户获得父资源的授权后添加子资源的解决方案。如果用户在合同中除一个站点之外的所有站点上都获得了授权,则意味着添加 n-1 行,但在我的用例中,这种情况不应该经常发生。如果确实发生,我仍然可以
deny
向 中添加布尔值person_role
。