数据库对象访问细粒度授权:特定领域模型场景的最佳架构方案咨询
针对你提到的公司、部门、职位三层实体的权限继承场景,我整理了一套经过实践验证的最佳架构方案,兼顾规则满足、性能和扩展性:
核心架构设计思路
整体采用直接权限存储+动态规则计算的模式,既保留权限授予的明确性,又能灵活实现继承逻辑。
1. 权限数据存储设计
将用户的直接授予权限和继承权限分离,只持久化直接权限,继承权限通过规则动态计算:
- 创建一张
user_entity_permissions表,字段包括:user_id、entity_type(枚举:company/department/position)、entity_id、permission_level(枚举:Admin/Write/Read) - 这张表仅存储管理员主动赋予用户的权限,避免和动态计算的继承权限混淆,数据更干净,也方便后续追溯权限变更记录
2. 权限继承规则的实现逻辑
针对你提到的两种继承场景,实现递归式的权限计算逻辑,优先级为:直接权限 > 公司Admin全局继承 > 部门Write向下继承
伪代码示例(Python)
def get_effective_permission(user_id, entity_type, entity_id): # 第一步:检查用户是否有该实体的直接权限 direct_perm = get_direct_permission_from_db(user_id, entity_type, entity_id) if direct_perm == "Admin": return direct_perm # 第二步:处理公司Admin的全局继承规则 if entity_type == "department": company_id = get_company_id_by_dept(entity_id) company_direct_perm = get_direct_permission_from_db(user_id, "company", company_id) if company_direct_perm == "Admin": return "Admin" elif entity_type == "position": dept_id = get_dept_id_by_position(entity_id) company_id = get_company_id_by_dept(dept_id) company_direct_perm = get_direct_permission_from_db(user_id, "company", company_id) if company_direct_perm == "Admin": return "Admin" # 第三步:处理部门Write向下继承规则(仅针对职位) if entity_type == "position": dept_id = get_dept_id_by_position(entity_id) dept_effective_perm = get_effective_permission(user_id, "department", dept_id) # 仅当用户没有直接授予该职位权限时,才继承部门的Write权限 if dept_effective_perm == "Write" and not direct_perm: return "Write" # 最终返回:有直接权限则返回,无则默认Read(可根据业务调整为"无权限") return direct_perm or "Read"
3. 性能优化方案
为避免频繁递归查询和数据库交互,加入缓存层优化:
- 缓存实体层级关系:用Redis哈希表存储
company:{id}:departments、department:{id}:positions,避免每次查询都走数据库关联 - 缓存有效权限结果:对高频访问的用户-实体权限,缓存计算后的结果,当用户权限变更、实体层级调整时主动清空对应缓存
- 批量权限计算:如果需要同时检查多个实体权限,批量查询直接权限和层级关系,减少数据库交互次数
4. 扩展性考虑
为后续业务变化预留空间:
- 权限规则配置化:把继承规则抽象成可配置的规则引擎,比如用JSON存储规则逻辑,后续修改规则无需改动代码
[ { "trigger": "entity_type == 'department' && parent_company_permission == 'Admin'", "action": "set_permission to 'Admin'" }, { "trigger": "entity_type == 'position' && parent_dept_permission == 'Write' && direct_permission == null", "action": "set_permission to 'Write'" } ] - 权限级别枚举化:把Admin/Write/Read存在数据库枚举表中,新增权限级别时只需更新枚举表,无需修改硬编码
5. 业务接入方式
封装统一的权限验证服务,所有业务模块通过该服务检查权限:
// Java示例代码片段 public class PermissionChecker { private final PermissionService permissionService; private final PermissionLevelComparator levelComparator; public boolean hasPermission(String userId, String entityType, String entityId, String requiredPerm) { String effectivePerm = permissionService.getEffectivePermission(userId, entityType, entityId); return levelComparator.isHigherOrEqual(effectivePerm, requiredPerm); } }
其中PermissionLevelComparator定义权限优先级:Admin > Write > Read
这个方案既严格满足你描述的权限继承规则,又兼顾了系统性能和后续业务扩展的灵活性,在中大型企业权限系统中已经得到广泛应用。
内容的提问来源于stack exchange,提问作者Ivan
相关产品推荐
相关产品推荐

