Symfony框架;存储用户角色的惯用方法

时间:2012-03-06 12:06:05

标签: php symfony doctrine-orm authorization idiomatic

在我的Symfony 2应用程序中,我想使用标准的用户和角色授权系统(http://symfony.com/doc/2.0/book/security.html)

我的用户是存储在具有doctrine(实现用户界面)的数据库中的实体。我的系统中将有5个预定义角色,每个用户可能有多个角色。

最实用的方法是什么?我正在考虑以下三种解决方案。

  1. 创建一个单独的Role实体并与用户实体建立多对多关系

    • Plus:轻松获得具有特定角色的所有用户
    • Con:资源密集型? (始终需要双重连接才能获得用户的所有角色)
    • 骗局:不是自我?角色的数量(及其名称)永远不会改变,将它作为单独的实体存储在数据库中是否有意义?
  2. 在用户中有一个字段,它是一个以逗号分隔的已排序的角色列表,getRoles()实现为explode(',',this.all_roles)

    • 加:计算成本不高
    • Con:很难让所有具有特定角色的用户
    • Con:像这样的数据库字段让小猫哭(normalizaition和stuff)
  3. 每个角色的用户实体中有5个二进制字段

    • 加:计算成本不高
    • Plus:轻松获得具有特定角色的所有用户
    • Con:这仍然感觉不太好
  4. 实施此系统的最常用方法是什么?

1 个答案:

答案 0 :(得分:12)

当然,答案很大程度上取决于您的要求,但我会尽量在全球范围内回答。

选项1:关系方式

从纯关系的角度来看,您希望数据库规范化,这将导致您的第一个选项:与您的用户表具有m:n关系的角色的表。这有一些优点:

  • 嗯,这是人们期望你的数据库工作的方式,所以没有隐藏在你的实体中的功能。
  • 没办法搞砸了(就像你有一个varchar字段,并希望它有某种格式,比如昏迷分离)
  • 只有一种方法可以做事

关于角色永远不会改变的顾虑:存储数据关系不是关于它改变的频率。人们应该永远记住要求的变化。你现在以优化的名义陷入困境的次数越多,以后当需要更多角色更频繁地改变时,你就会越努力。

当然,您可能会遇到性能问题,尤其是遇到某种急切加载问题或者您没有缓存内容并且必须在每个页面加载时重新加载角色时。但是,关系数据库再次被设计为支持这些东西,所以这里应该是优化查询的方法。

选项2:黑客

您的第二个选项,只是将所有角色存储到varchar中,在性能方面会更好。只加载一个文本字段,一些PHP处理就完成了。另一方面,您可能会遇到几个问题:

  • 您无法控制varchar字段,因此一个故障脚本可能会损害您的整个应用程序(这非常糟糕,但根据您的项目,如果您是唯一的开发人员而且您知道自己在做什么,那么它可能会孔)
  • 对一个数据集的更新要困难得多,因为您必须提取所有角色,更新相关数据并存储回来
  • 查询具有特定角色的所有用户要困难得多
  • 删除角色要困难得多

选项3:务实的解决方案

每个角色有5个布尔值的第三个选项位于中间:没有办法搞砸它,性能应该不是问题。更新很容易,也可以删除角色或添加新角色。很清楚这些领域是做什么的,所以这方面也没有坏处。它使你的实体和数据库看起来更难看,你也可以在你的用户模型中使用角色名称来将真/假字段映射到正确的角色名称,这可能有点令人困惑。

<强>结果

考虑到这一切,我会选择选项1.人们可能会认为表现是一个问题,但除非我证明了这一点,否则我不会考虑这些问题。最后,当你真正遇到真正的性能问题时,你会怎么做?您可以添加一些额外的硬件,优化dbms,优化查询,或者使用具有更多性能构建的dbms(Hello Oracle!)。

如果您因为角色表而证明您的应用程序很慢,那么您以后可以随时使用选项3。您只需更改用户实体并拥有一个提取角色的查询,并为每个用户设置正确的true / false组合。如果该软件是干净的,这是一个小时的问题,所以现在不需要在性能可能不好的想法上这样做。