You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

权限系统两种数据库表设计方案:哪种实现更高效?

两种权限设计方案的效率对比

作为在权限系统上踩过不少坑的开发者,我来聊聊这两种方案在效率层面的差异——其实没有绝对的优劣,得看你的业务场景。先明确下两种模式的叫法,方便后面讨论:

  • 宽表权限模式:就是你最开始用的,每个权限对应表的一列,用0/1标识是否开启
    id|name|can_do_this|can_do_that
    1|admin|1|1
    2|manager|1|0
    3|user|0|0
    
  • EAV(实体-属性-值)权限模式:教授推荐的,每条记录对应一个用户的单个权限状态
    id|user_id|privilege|active
    1|1|can_do_this|1
    2|1|can_do_that|1
    3|2|can_do_this|1
    4|2|can_do_that|0
    

查询效率:宽表完胜常规场景

如果你的业务经常需要一次性获取某个用户的所有权限,宽表的效率要高得多:

  • 只需要一次SELECT * FROM roles WHERE id = ?就能拿到所有权限列,直接返回结果,应用层不用做额外处理。
  • 而EAV模式得先查SELECT privilege, active FROM user_privileges WHERE user_id = ?,然后还要在应用层把零散的行转换成键值对(比如把can_do_this:1这种记录拼成一个权限对象),多了一层处理开销;要是同时检查多个权限,还得写复杂的条件或者聚合查询,性能肯定不如宽表直接取列判断。

当然,如果你的业务大部分场景只需要检查单个权限,那两者的查询效率差距不大,但现实中多数系统都是需要批量获取权限的。

写入/更新效率:各有胜负

  • 批量设置权限:宽表更高效。比如给一个用户配置10个权限,宽表只需要一次UPDATE语句修改10列;EAV模式则得执行10条INSERT/UPDATE(就算用批量插入,也比单条UPDATE繁琐)。
  • 单个权限更新:两者差距极小。EAV模式改单条记录,宽表改单列,在现代数据库里这点差异几乎可以忽略,除非你的权限数量多到宽表的行数据特别大,才会有轻微的IO差距。

存储效率:宽表更紧凑

  • 宽表的每条记录把所有权限存在一起,没有冗余字段(比如EAV里重复出现的user_id和privilege字符串),权限数量固定的话,存储占用更小。
  • EAV模式每条记录都要重复存储用户ID和权限名称,当用户数、权限数变多的时候,存储量会显著膨胀,而且索引开销也更大(比如user_id+privilege的联合索引,数据量比宽表的主键索引大很多)。

扩展效率:EAV模式碾压

这也是你教授强调的核心优势:

  • 宽表新增权限必须执行ALTER TABLE ADD COLUMN,这个操作在大表上特别耗时(甚至会锁表导致业务中断),而且权限越多表结构越臃肿,后续维护成本极高。
  • EAV模式新增权限只需要插入新的记录,完全不用改表结构,对于快速迭代的项目来说,灵活性拉满。

总结:根据业务场景选

  • 如果你的权限体系非常稳定,几乎不会新增权限,而且需要频繁批量查询权限,那宽表模式在效率上更优。
  • 如果你的权限体系经常变动,需要快速新增权限,哪怕牺牲一点查询和存储效率,EAV模式(或者它的变种,比如加个权限组表做关联)会更适合长期维护。

另外给你个折中方案参考:可以用权限组+用户权限覆盖的模式——先建一个权限组表(用宽表模式),再建一个用户权限表(用EAV模式),用户的最终权限优先取用户权限表的设置,没有的话继承组权限。这样既兼顾了查询效率(大部分用户用组权限,一次查询搞定),又保留了扩展灵活性(新增权限改组表,或者用户单独设置权限用EAV)。

内容的提问来源于stack exchange,提问作者Tarek Sawah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:12:59