6.8 KiB
6.8 KiB
用户组织关系优化方案
概述
为了简化用户-组织关系查询,提高系统性能,决定对sys_user表结构进行扩充,添加冗余的组织信息字段,并建立相应的数据同步机制。
问题分析
当前问题
SysUser实体缺少orgId和组织相关字段- 查询用户组织信息需要多表关联,性能较差
- 健康数据处理时无法直接获取用户组织信息
- 组织相关的统计查询复杂度高
影响范围
- 健康基线生成服务
- 组织健康统计功能
- 用户管理相关查询
- 权限验证和数据过滤
解决方案
1. 数据库表结构扩充
1.1 修改sys_user表
添加以下字段:
org_idBIGINT - 组织IDorg_nameVARCHAR(100) - 组织名称(冗余存储,提高查询性能)
-- 扩充sys_user表结构
ALTER TABLE sys_user
ADD COLUMN org_id BIGINT COMMENT '组织ID',
ADD COLUMN org_name VARCHAR(100) COMMENT '组织名称';
-- 添加索引提高查询性能
CREATE INDEX idx_sys_user_org_id ON sys_user(org_id);
CREATE INDEX idx_sys_user_org_name ON sys_user(org_name);
1.2 创建或确保sys_org表存在
-- 创建组织表(如果不存在)
CREATE TABLE IF NOT EXISTS sys_org (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
org_name VARCHAR(100) NOT NULL COMMENT '组织名称',
parent_id BIGINT DEFAULT 0 COMMENT '父级组织ID',
org_code VARCHAR(50) COMMENT '组织编码',
sort_order INT DEFAULT 0 COMMENT '排序',
status TINYINT DEFAULT 1 COMMENT '状态(0:禁用,1:启用)',
is_deleted TINYINT DEFAULT 0 COMMENT '是否删除(0:否,1:是)',
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) COMMENT='组织机构表';
-- 添加索引
CREATE INDEX idx_sys_org_parent_id ON sys_org(parent_id);
CREATE INDEX idx_sys_org_code ON sys_org(org_code);
2. 实体类修改
2.1 SysUser实体类扩充
/**
* 组织ID
*/
@TableField("org_id")
private Long orgId;
/**
* 组织名称(冗余存储)
*/
@TableField("org_name")
private String orgName;
/**
* 生日(用于年龄计算)
*/
@TableField("birthday")
private LocalDate birthday;
2.2 创建SysOrg实体类
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
@TableName("sys_org")
public class SysOrg extends BaseEntity {
private String orgName;
private Long parentId;
private String orgCode;
private Integer sortOrder;
private String status;
private Integer isDeleted;
}
3. 数据同步机制
3.1 事件驱动同步
使用Spring事件机制在组织信息变更时自动同步用户表:
// 组织变更事件
@Component
public class OrgChangeEventListener {
@EventListener
@Async
public void handleOrgNameChange(OrgNameChangeEvent event) {
// 同步更新所有该组织用户的org_name
userService.updateOrgNameByOrgId(event.getOrgId(), event.getNewOrgName());
}
@EventListener
@Async
public void handleOrgDelete(OrgDeleteEvent event) {
// 清理被删除组织的用户关联
userService.clearOrgInfoByOrgId(event.getOrgId());
}
}
3.2 用户操作时同步
在用户新增、修改时自动设置组织信息:
@Service
public class SysUserService {
public void saveOrUpdateUser(SysUser user) {
if (user.getOrgId() != null) {
// 自动填充组织名称
SysOrg org = sysOrgService.getById(user.getOrgId());
if (org != null) {
user.setOrgName(org.getOrgName());
}
}
// 保存用户
saveOrUpdate(user);
}
}
4. 数据迁移策略
4.1 初始化现有数据
-- 如果已有用户数据,需要初始化组织信息
-- 假设通过其他表关联获取组织信息,这里需要根据实际情况调整
-- 示例:为现有用户设置默认组织
UPDATE sys_user SET
org_id = 1,
org_name = '默认组织'
WHERE org_id IS NULL;
-- 示例:从用户设备信息推断组织关系(如果存在相关表)
-- UPDATE sys_user u
-- JOIN user_device_mapping d ON u.device_sn = d.device_sn
-- JOIN device_org_mapping o ON d.org_id = o.org_id
-- SET u.org_id = o.org_id, u.org_name = o.org_name;
4.2 数据一致性检查
@Component
@Slf4j
public class UserOrgConsistencyChecker {
@Scheduled(cron = "0 0 2 * * ?") // 每天凌晨2点执行
public void checkUserOrgConsistency() {
// 检查用户表中org_name与org表是否一致
List<SysUser> inconsistentUsers = userService.findInconsistentOrgUsers();
for (SysUser user : inconsistentUsers) {
SysOrg org = sysOrgService.getById(user.getOrgId());
if (org != null && !org.getOrgName().equals(user.getOrgName())) {
user.setOrgName(org.getOrgName());
userService.updateById(user);
log.info("修复用户{}的组织名称不一致问题", user.getUserName());
}
}
}
}
实施步骤
第一阶段:数据库结构调整
- ✅ 扩充sys_user表结构
- ✅ 创建sys_org表
- ✅ 添加相关索引
- ✅ 初始化现有用户的组织信息
第二阶段:代码调整
- 修改SysUser实体类
- 创建SysOrg实体类和相关服务
- 实现数据同步机制
- 修改健康基线服务使用新字段
第三阶段:测试验证
- 单元测试覆盖
- 数据一致性验证
- 性能测试对比
- 功能回归测试
第四阶段:部署上线
- 生产环境数据备份
- 数据库结构变更
- 应用代码部署
- 数据一致性检查
风险评估与应对
潜在风险
- 数据不一致风险:冗余存储可能导致数据不一致
- 迁移风险:现有数据迁移可能出现问题
- 性能影响:表结构变更可能影响现有查询
应对措施
- 建立完善的数据同步机制和一致性检查
- 充分的测试验证和回滚预案
- 分阶段灰度发布,监控性能指标
预期收益
性能提升
- 用户组织查询性能提升80%+
- 减少复杂的多表关联查询
- 健康数据统计查询简化
开发效率
- 简化组织相关业务逻辑
- 降低代码复杂度
- 提高开发和维护效率
系统稳定性
- 减少数据库查询压力
- 提高系统响应速度
- 降低因复杂查询导致的故障风险
监控指标
数据质量指标
- 用户组织信息一致性比例
- 数据同步延迟时间
- 数据修复次数
性能指标
- 用户查询响应时间
- 组织统计查询响应时间
- 数据库连接池使用率
业务指标
- 健康基线生成成功率
- 组织健康统计准确性
- 用户管理操作效率
实施负责人: bruno.gao
预计完成时间: 2025-01-27
风险等级: 中等
优先级: 高