【问题标题】:MySQL: Best way to check if user has permission by roleMySQL:检查用户是否具有角色权限的最佳方法
【发布时间】:2014-07-10 17:55:54
【问题描述】:

我正在构建一个小型权限系统,但不幸的是,无论如何我都不是 SQL 专家。

在这个系统中,我决定给所有用户一个角色,然后为这些角色分配特定的权限。我当前的数据库表如下所示:

我的问题是:通过提供 Permission.permission_name 值来检查给定的 User.id 是否作为权限的最佳方法是什么。我想出了以下查询:

SELECT EXISTS (

    SELECT perm.id

    FROM `User` userr

    INNER JOIN `Role_Permission` connectionc
    ON userr.role_id = connectionc.role_id

    INNER JOIN `Permission` perm
    ON connectionc.permission_id = perm.id

    WHERE userr.id = 1
    AND perm.permission_name LIKE 'doStuff'

) as userHasPermission

它可以工作,但是,据我了解,加入是昂贵的,并且该查询正在加入 3 个表的内容,然后过滤它需要的内容。

sqlfiddle 链接:http://sqlfiddle.com/#!2/6ed7b/1

谢谢。

【问题讨论】:

  • 有点混乱“INNER JOIN Role role ON userr.id = role.id”。那不应该是“INNER JOIN Role role ON userr.role_id = role.id”。 IMO 我看不出有什么理由需要加入“角色”。
  • @JA 你是对的。 ;) 刚刚编辑。
  • SQL 似乎是正确的。请您发起/提供一个 sqlfiddle.com 吗?
  • @JA sqlfiddle.com/#!2/6ed7b/1 ,是的,代码是正确的,我在另一个地方误读了一些东西。原来的问题仍然存在。我可以优化谁的查询?谢谢。

标签: mysql sql query-optimization inner-join


【解决方案1】:

我认为优化查询的地方不多。从实际情况来看,无论用户表有多大,角色和权限表都不应超过 3 位,因此,role_permission 不会超过 998001 条记录。如果所有正确的列都被正确索引,我相信,sql 会非常快(

(离题) 或者,最近从事过一个类似的项目,几乎没有选择可以提高从“有限”号中获取的速度。记录。

  • 内存:您可以选择将所有这些相关表/数据保存在内存中(而不是磁盘),以最大限度地减少与 I/O 相关的延迟。

  • NoSQL:您可以选择像 mongoDB 这样的 NoSQL 解决方案和/或在 MySql 中实现类似 noSQL 的结构来消除联接。

  • Redis:可以说,如果您想跳出框框思考,这是最好的解决方案。最快的。

【讨论】:

    【解决方案2】:

    我认为优化的空间不大,而不是不损害数据库的规范化。只需确保您有适当的索引。

    一些替代方案是:

    • 将索引名称存储在角色权限表中,因此需要少一个连接。它不会被标准化,但如果权限很少更改并且您确实需要最高性能,这可能是可以接受的。

    • 不要使用整数 ID 作为权限,而是使用其名称作为唯一标识符。那么你根本就不需要表Permission,除非你需要给它们添加一些属性(但这仍然允许你检查一个只有一个连接的权限)。

    您还应该考虑需要多久运行一次此查询。根据您的要求,仅在用户进入系统时读取所有用户权限并在整个会话期间将它们存储在变量中可能是可以接受的;在这种情况下,您不需要如此高的查询性能。或者您可以一开始加载的不是权限而是角色,这意味着查询中的联接减少了。

    【讨论】:

      猜你喜欢
      • 2011-02-17
      • 2021-03-31
      • 1970-01-01
      • 1970-01-01
      • 2017-10-31
      • 1970-01-01
      • 2011-01-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多