当前位置: 首页 > news >正文

多租户字典管理系统完整设计

多租户字典管理系统

一、完整数据库设计

1. 核心表结构

租户表
CREATE TABLE `sys_tenant` (`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',`tenant_code` varchar(64) NOT NULL COMMENT '租户编码',`tenant_name` varchar(128) NOT NULL COMMENT '租户名称',`status` tinyint(1) DEFAULT '1' COMMENT '状态(0:禁用,1:启用)',`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',PRIMARY KEY (`id`),UNIQUE KEY `uk_tenant_code` (`tenant_code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='租户信息表';
字典类型表
CREATE TABLE `sys_dict_type` (`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',`tenant_id` bigint(20) NOT NULL COMMENT '租户ID',`type_code` varchar(64) NOT NULL COMMENT '字典类型编码',`type_name` varchar(128) NOT NULL COMMENT '字典类型名称',`is_system` tinyint(1) DEFAULT '0' COMMENT '是否系统字典(0:否,1:是)',`is_shared` tinyint(1) DEFAULT '0' COMMENT '是否共享(0:否,1:是)',`status` tinyint(1) DEFAULT '1' COMMENT '状态(0:禁用,1:启用)',`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',PRIMARY KEY (`id`),UNIQUE KEY `uk_tenant_type_code` (`tenant_id`,`type_code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='字典类型表';
字典数据表
CREATE TABLE `sys_dict_data` (`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',`tenant_id` bigint(20) NOT NULL COMMENT '租户ID',`type_id` bigint(20) NOT NULL COMMENT '字典类型ID',`parent_id` bigint(20) DEFAULT '0' COMMENT '父级ID',`data_code` varchar(64) NOT NULL COMMENT '字典项编码',`data_name` varchar(128) NOT NULL COMMENT '字典项名称',`data_value` varchar(512) DEFAULT NULL COMMENT '字典项值',`path` varchar(255) DEFAULT NULL COMMENT '树路径(如:1.2.3)',`level` int(11) DEFAULT '1' COMMENT '层级深度',`sort` int(11) DEFAULT '0' COMMENT '排序',`status` tinyint(1) DEFAULT '1' COMMENT '状态(0:禁用,1:启用)',`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',PRIMARY KEY (`id`),UNIQUE KEY `uk_type_data_code` (`type_id`,`data_code`),KEY `idx_parent_id` (`parent_id`),KEY `idx_path` (`path`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='字典数据表';

2. 扩展表结构

字典扩展字段定义表
CREATE TABLE `sys_dict_extend_define` (`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',`tenant_id` bigint(20) NOT NULL COMMENT '租户ID',`type_id` bigint(20) NOT NULL COMMENT '字典类型ID',`field_code` varchar(64) NOT NULL COMMENT '字段编码',`field_name` varchar(128) NOT NULL COMMENT '字段名称',`field_type` varchar(20) NOT NULL COMMENT '字段类型(string/number/boolean/date/json)',`default_value` varchar(512) DEFAULT NULL COMMENT '默认值',`is_required` tinyint(1) DEFAULT '0' COMMENT '是否必填(0:否,1:是)',`status` tinyint(1) DEFAULT '1' COMMENT '状态(0:禁用,1:启用)',`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',PRIMARY KEY (`id`),UNIQUE KEY `uk_type_field_code` (`type_id`,`field_code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='字典扩展字段定义表';
字典扩展字段值表
CREATE TABLE `sys_dict_extend_value` (`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',`tenant_id` bigint(20) NOT NULL COMMENT '租户ID',`data_id` bigint(20) NOT NULL COMMENT '字典数据ID',`field_id` bigint(20) NOT NULL COMMENT '字段定义ID',`string_value` varchar(512) DEFAULT NULL COMMENT '字符串值',`number_value` decimal(20,6) DEFAULT NULL COMMENT '数值',`boolean_value` tinyint(1) DEFAULT NULL COMMENT '布尔值',`date_value` datetime DEFAULT NULL COMMENT '日期值',`json_value` json DEFAULT NULL COMMENT 'JSON值',`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',PRIMARY KEY (`id`),UNIQUE KEY `uk_data_field` (`data_id`,`field_id`),KEY `idx_field_id` (`field_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='字典扩展字段值表';
字典扩展字段历史表
CREATE TABLE `sys_dict_extend_history` (`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',`value_id` bigint(20) NOT NULL COMMENT '字段值ID',`before_value` json DEFAULT NULL COMMENT '修改前值',`after_value` json DEFAULT NULL COMMENT '修改后值',`operation_type` varchar(20) NOT NULL COMMENT '操作类型(CREATE/UPDATE/DELETE)',`operator` varchar(64) NOT NULL COMMENT '操作人',`operation_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '操作时间',PRIMARY KEY (`id`),KEY `idx_value_id` (`value_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='字典扩展字段历史表';

二、领域模型设计

// 字典类型实体
public class DictType {private Long id;private Long tenantId;private String typeCode;private String typeName;private Boolean isSystem;private Boolean isShared;private List<DictExtendDefine> extendDefines;// 其他字段...
}// 字典数据实体
public class DictData {private Long id;private Long tenantId;private Long typeId;private Long parentId;private String dataCode;private String dataName;private String dataValue;private String path;private Integer level;private Map<String, DictExtendValue> extendValues;// 其他字段...
}// 字典扩展字段定义
public class DictExtendDefine {private Long id;private Long tenantId;private Long typeId;private String fieldCode;private String fieldName;private String fieldType;private Object defaultValue;// 其他字段...
}// 字典扩展字段值
public class DictExtendValue {private Long id;private Long dataId;private Long fieldId;private Object value;// 其他字段...
}

三、核心流程图

1. 字典项创建流程

客户端接口层服务层持久层缓存提交字典项数据参数校验开启事务插入主表数据批量插入扩展字段值记录扩展字段历史返回事务结果清除相关缓存返回操作结果返回成功响应客户端接口层服务层持久层缓存

2. 字典树查询流程

缓存逻辑
缓存命中
缓存未命中
直接返回缓存
缓存处理
写入缓存后返回
开始
查询字典主数据
查询扩展字段定义
批量查询扩展字段值
构建字典项完整数据
组装树形结构
返回结果

四、扩展字段管理API设计

1. 扩展字段定义接口

POST   /api/dict/extend/define       # 创建扩展字段定义
PUT    /api/dict/extend/define/{id}  # 更新扩展字段定义
DELETE /api/dict/extend/define/{id}  # 删除扩展字段定义
GET    /api/dict/extend/define       # 获取字典类型的扩展字段定义

2. 扩展字段值接口

POST   /api/dict/data/{dataId}/extend  # 批量设置扩展字段值
GET    /api/dict/data/{dataId}/extend  # 获取字典项的所有扩展字段值
PATCH  /api/dict/extend/value/{id}     # 更新单个扩展字段值

五、设计优势说明

  1. 灵活扩展
    • 支持按字典类型动态定义字段
    • 多种数据类型支持(字符串、数字、布尔值、日期、JSON)
    • 不影响主表结构的情况下实现扩展
  2. 数据完整
    • 扩展字段定义与值分离
    • 通过外键约束保证数据一致性
    • 完整的历史变更记录
  3. 查询高效
    • 扩展字段值表建立合适索引
    • 批量查询避免N+1问题
    • 支持缓存扩展字段定义
  4. 多租户支持
    • 所有扩展表包含tenant_id
    • 共享字典的扩展字段可继承
    • 租户间扩展字段定义隔离

六、典型使用场景示例

场景1:地区字典扩展经纬度

// 1. 定义扩展字段
POST /api/dict/extend/define
{"typeId": 5,"fieldCode": "longitude","fieldName": "经度","fieldType": "number"
}// 2. 设置扩展值
POST /api/dict/data/123/extend
[{"fieldCode": "longitude","numberValue": 116.404
}]

场景2:产品分类扩展图片和描述

// 批量定义扩展字段
POST /api/dict/extend/define/batch
[{"typeId": 8,"fieldCode": "image_url","fieldName": "分类图片","fieldType": "string"
},{"typeId": 8,"fieldCode": "description","fieldName": "分类描述","fieldType": "string"
}]

此设计完整实现了多租户环境下字典系统的扩展字段需求,既保持了核心字典功能的简洁性,又提供了强大的扩展能力,适合需要高度定制化字典项的业务场景。

多租户字典表设计理念与流程图

一、表设计理念

1. 核心设计原则

  1. 多租户隔离性

    • 所有表都包含tenant_id字段,确保数据天然隔离
    • 通过数据库中间件自动注入租户条件
    • 共享数据通过显式的关联表控制
  2. 树形结构优化

    • 采用邻接表+路径枚举混合模型
    parent_id BIGINT COMMENT '直接父节点',
    path VARCHAR(255) COMMENT '完整路径(如1.3.5)', 
    level INT COMMENT '层级深度'
    
    • 平衡查询效率与更新复杂度
  3. 扩展性设计

    • 垂直拆分:核心字段与扩展字段分离
    • 动态字段:通过扩展定义表+扩展值表实现
    • 多语言支持:独立的多语言表结构
  4. 数据一致性

    • 重要业务操作使用事务
    @Transactional
    public void saveDictWithExtend(DictData data, List<ExtendValue> values) {// 保存主表dictMapper.insert(data);// 批量保存扩展值extendMapper.batchInsert(values);
    }
    
    • 通过外键约束保证引用完整性

2. 表关系设计

tenantdict_typedict_dataextend_defineextend_valueextend_history1:N1:N自关联1:N1:N1:N

二、核心流程图解

1. 字典项创建流程

开始
校验租户权限
验证字典类型
是否包含父项?
验证父项有效性
设置根路径
计算树路径
插入主表数据
是否有扩展字段?
验证扩展字段定义
校验扩展字段值类型
保存扩展字段值
更新缓存
返回创建结果

2. 字典树查询流程

客户端控制器服务层缓存数据库GET /dict/tree?type=region携带租户上下文查询缓存key=dict:tree:{tenant}:region返回缓存数据查询字典主数据返回平铺列表批量查询扩展字段值返回扩展值构建树形结构写入缓存alt[缓存命中][缓存未命中]返回完整树形数据返回200响应客户端控制器服务层缓存数据库

3. 扩展字段更新流程

获取当前版本
值非空校验
验证字段类型匹配
开启事务
更新核心字段
保存扩展字段值
记录变更历史
提交事务
版本检查
值校验
类型检查
事务处理
主表更新
扩展表更新
历史记录
缓存失效

三、表操作流程图

1. 字典数据移动(含子树处理)

事务回滚
异常
回滚事务
开启事务
记录错误日志
开始
获取当前节点
获取新父节点
是否跨类型?
返回错误
计算新path
更新当前节点path
查询所有子节点
批量更新子path
更新扩展表租户标记
提交事务
清除缓存
返回成功

2. 扩展字段值批量更新

开始
校验字段定义
分组字段值-按类型
字符串类型处理
数字类型处理
JSON类型处理
生成批量SQL
执行批量更新
记录修改历史
返回操作结果

四、设计亮点说明

  1. 高效树查询

    /* 查询子树(利用path字段) */
    SELECT * FROM dict_data 
    WHERE path LIKE '1.3.%' 
    AND tenant_id = 123
    ORDER BY path;/* 查询路径(利用path解析) */
    SELECT * FROM dict_data
    WHERE id IN (SELECT SUBSTRING_INDEX(path, '.', 1) FROM dict_data WHERE id = 5)
    ORDER BY level;
    
  2. 扩展字段动态处理

    // 扩展字段值转换逻辑
    public Object convertValue(ExtendDefine define, String input) {switch (define.getFieldType()) {case "number":return NumberUtils.parseDouble(input);case "boolean":return BooleanUtils.toBoolean(input);case "json":return JSON.parse(input);default:return input;}
    }
    
  3. 缓存策略

    // 多级缓存Key生成策略
    public String buildCacheKey(Long tenantId, String typeCode) {return String.format("dict:%d:%s", tenantId, typeCode);
    }// 缓存数据结构示例
    {"dict:123:region": {"lastUpdated": "2023-07-20T08:00:00Z","data": [{"id": 1,"name": "华东","extend": {"area_code": "0086","timezone": "UTC+8"}}]}
    }
    

这套设计通过清晰的表结构划分和流程图解,完整展现了:

  1. 多租户数据隔离的实现方式
  2. 树形字典的高效存储与查询
  3. 动态扩展字段的管理机制
  4. 保证数据一致性的技术方案
  5. 高性能访问的缓存策略
http://www.xdnf.cn/news/1240669.html

相关文章:

  • TCP 协议的“无消息边界”(No Message Boundaries)特性
  • shell脚本tcpdump抓取数据解析执行关机指令
  • PyCharm代码规范与代码格式化插件安装与使用:pylint和autopep8
  • 质押和抵押有什么区别
  • 【Java】一篇详解HashMap的扩容机制!!
  • 2025年8月4日私鱼创作平台v1.0.4公测版更新发布-完成大部分功能包含关注创作者以及发布作品及合集功能优雅草科技
  • 音视频学习笔记
  • 深入解析 Apache Tomcat 配置文件
  • Planner 5D v2.29.0 安卓高级解锁版,手机3D家装,全套家具免费
  • 鸿蒙开发-端云一体化--云数据库
  • [spring-cloud: 负载均衡]-源码分析
  • Nginx服务做负载均衡网关
  • 【项目实践】在系统接入天气api,根据当前天气提醒,做好plan
  • 基于Java的AI工具和框架
  • 【异常案例分析】使用空指针调用函数(非虚函数)时,没有崩溃在函数调用处,而是崩在被调用函数内部
  • Android Telephony 框架与横向支撑层
  • Android JUnit 测试框架详解:从基础到高级实践
  • Flask + HTML 项目开发思路
  • 开源的现代数据探索和可视化平台:Apache Superset 快速指南 Quickstart
  • Android的UI View是如何最终绘制成一帧显示在手机屏幕上?
  • 阿里云-通义灵码:解锁云原生智能开发新能力,让云开发更“灵”~
  • 福彩双色球第2025089期篮球号码分析
  • 理解 JavaScript 中的“ / ”:路径、资源与目录、nginx配置、请求、转义的那些事
  • 超急评估:用提前计算分摊性能成本
  • go学习笔记:panic是什么含义
  • 工作流绑定卡片优化用户体验-练习我要找工作智能体
  • 豆包1.6+PromptPilot实战:构建智能品牌评价情感分类系统的技术探索
  • 基于Spring Cloud Gateway和Resilience4j的微服务容错与流量控制实战经验分享
  • Solidity智能合约开发全攻略
  • 电商系统想撑住大流量?ZKmall开源商城靠微服务 + Spring Boot3 解决单体架构难题