插件窝 干货文章 如何高效获取用户被授权的分级结构,包括 F、E、D 列表,其中 F 列表支持分页?

如何高效获取用户被授权的分级结构,包括 F、E、D 列表,其中 F 列表支持分页?

id 列表 user 获取 458    来源:    2025-03-31

获取用户授权分级结构的高效方案

问题理解

您需要获取用户被授权的分级结构,包括F、E、D三个层级的列表,其中F列表需要支持分页功能。

解决方案

1. 数据库设计优化

-- 用户授权表结构示例
CREATE TABLE user_authorizations (
    id BIGINT PRIMARY KEY,
    user_id BIGINT NOT NULL,
    f_id BIGINT NOT NULL,
    e_id BIGINT,
    d_id BIGINT,
    created_at TIMESTAMP,
    INDEX idx_user (user_id),
    INDEX idx_f (f_id),
    INDEX idx_e (e_id),
    INDEX idx_d (d_id)
);

2. API接口设计

GET /api/user/{userId}/authorizations

参数: - page (可选): F列表的页码,默认为1 - pageSize (可选): 每页数量,默认为20 - level (可选): 指定获取的层级(F/E/D)

3. 实现方案

方案一:单次查询+应用层处理

public AuthorizationHierarchy getUserAuthorizations(Long userId, Integer page, Integer pageSize) {
    // 获取F列表(分页)
    Page<FEntity> fList = fRepository.findByUserId(userId, PageRequest.of(page-1, pageSize));

    // 获取E列表(基于F列表)
    List<Long> fIds = fList.getContent().stream().map(FEntity::getId).collect(Collectors.toList());
    List<EEntity> eList = eRepository.findByFIdIn(fIds);

    // 获取D列表(基于E列表)
    List<Long> eIds = eList.stream().map(EEntity::getId).collect(Collectors.toList());
    List<DEntity> dList = dRepository.findByEIdIn(eIds);

    // 构建层级结构
    return buildHierarchy(fList, eList, dList);
}

方案二:数据库层JOIN查询(适合数据量较小情况)

SELECT f.id as f_id, f.name as f_name, 
       e.id as e_id, e.name as e_name,
       d.id as d_id, d.name as d_name
FROM user_authorizations ua
JOIN f ON ua.f_id = f.id
LEFT JOIN e ON ua.e_id = e.id
LEFT JOIN d ON ua.d_id = d.id
WHERE ua.user_id = :userId
LIMIT :pageSize OFFSET :offset

4. 性能优化建议

  1. 缓存策略:

    • 使用Redis缓存用户授权结构
    • 设置合理的TTL(如5分钟)
  2. 延迟加载:

    • 先返回F列表
    • 根据用户操作按需加载E/D列表
  3. 批量查询:

    • 使用IN查询替代多次单条查询
    • 考虑使用数据预取(pre-fetching)策略
  4. 索引优化:

    • 确保user_id、f_id、e_id、d_id都有索引
    • 考虑复合索引(user_id, f_id)等

分页实现细节

对于F列表的分页,建议:

  1. 使用数据库原生分页(如MySQL的LIMIT/OFFSET)
  2. 对于大数据量,考虑使用"游标分页"(基于最后一条记录的ID)
  3. 返回分页元数据:
{
  "f_list": [...],
  "pagination": {
    "page": 1,
    "pageSize": 20,
    "totalItems": 100,
    "totalPages": 5
  },
  "e_list": [...],
  "d_list": [...]
}

您需要根据实际数据量、访问频率和业务需求选择最适合的方案。如果需要更具体的实现,可以提供您的技术栈信息。