# Requirements - 数据库表结构设计和创建 ## 需求信息 - **需求名称**: 数据库表结构设计和创建 - **需求类型**: 数据需求 - **需求编号**: REQ-010-1 - **父需求**: REQ-010 - **创建日期**: 2026-01-17 - **需求版本**: v1.0.0 - **需求提出人**: 系统管理员 - **需求状态**: 已完成 ## 输入引用 引用相关的 docs 文档链接: - [REQ-010.md](REQ-010.md) - Salesforce元数据拉取和部署主需求文档 - [010-metadata-retrieve-deploy-sub-requirements.md](010-metadata-retrieve-deploy-sub-requirements.md) - REQ-010子需求拆分文档 - [001-元数据模块设计](../reference-code/metadata/001-元数据模块设计) - 数据库设计和模块架构 ## Context Maps 强制列出本次需求依赖的 Canvas 文件: - [Authentication.canvas](../Authentication.canvas) - 项目架构视觉化展示 - **相关节点**: [集成核心](node_integration_core) - 提供与Salesforce的各种连接方式 - **相关节点**: [集成Mapper](node_integration_mapper) - 处理集成相关数据的持久化操作 ## 需求目标 设计和创建Salesforce元数据拉取和部署系统所需的9张核心数据库表,为后续功能开发提供数据存储基础。 ## 需求描述 ### 概述 本需求旨在设计和创建Salesforce元数据拉取和部署系统所需的9张核心数据库表,包括组织配置表、元数据包定义明细表、元数据组件索引表、元数据版本内容表、任务定义表、作业执行流水表、作业详细日志表、部署历史表、部署组件结果明细表。 ### 技术规范参考 基于 `datai-salesforce-auth` 和 `datai-salesforce-metadata` 模块的实际实现,本项目遵循以下技术规范: #### 1. 命名规范 - **表名**: 使用 `datai_` 前缀,采用 snake_case 命名(如 `datai_sf_login_history`) - **字段名**: 采用 snake_case 命名(如 `org_config_id`, `create_time`) - **Java类名**: 采用 PascalCase 命名(如 `DataiMetaTask`, `DataiSfLoginHistory`) - **Java属性名**: 采用 camelCase 命名(如 `orgConfigId`, `createTime`) #### 2. 实体类设计规范 - 所有 Domain 实体类必须继承 `BaseEntity`(包含 `createBy`, `createTime`, `updateBy`, `updateTime`, `remark` 等公共字段) - 使用 Lombok 注解简化代码:`@Data`, `@Builder`, `@NoArgsConstructor`, `@AllArgsConstructor` - 使用 Swagger 注解提供 API 文档:`@Schema`, `@Schema(title="字段描述")` - 使用 Excel 注解支持数据导出:`@Excel(name="字段名称")` - 使用 `ToStringBuilder` 实现 `toString()` 方法 #### 3. Mapper 设计规范 - Mapper 接口定义标准的 CRUD 方法 - Mapper XML 使用表别名提高可读性(如 `dmt` 代表 `datai_meta_task`) - 使用 `` 定义结果映射 - 使用 `` 定义可重用的 SQL 片段 - 使用 `` 和 `` 实现动态 SQL - 使用 `useGeneratedKeys="true"` 和 `keyProperty="id"` 支持主键回填 #### 4. 数据库设计规范 - **字符集**: 使用 `utf8mb4` 字符集 - **排序规则**: 使用 `utf8mb4_general_ci` 或 `utf8mb4_unicode_ci` - **主键**: 使用 `BIGINT` 类型,自增或雪花算法 - **时间字段**: 使用 `DATETIME` 或 `TIMESTAMP` 类型 - **布尔字段**: 使用 `TINYINT(1)` 或 `BOOLEAN` 类型 - **部门隔离**: 所有表必须包含 `dept_id` 字段用于部门数据隔离 - **审计字段**: 继承 `BaseEntity` 的审计字段(创建人、创建时间、更新人、更新时间、备注) #### 5. 索引设计规范 - 主键自动创建索引 - 外键字段创建索引 - 常用查询条件字段创建索引 - 组合索引根据查询频率和选择性设计 - 索引命名规范:`idx_表名_字段名`(如 `idx_datai_meta_task_org_config_id`) ### 详细需求 #### 1. 数据库表结构设计 - **需求描述**: 设计9张核心数据库表的结构,包括字段定义、类型选择、索引设计、外键约束等 - **优先级**: 高 - **验收标准**: - 所有9张表的DDL脚本设计完成 - 表结构符合项目技术规范(参考 `datai-salesforce-auth` 和 `datai-salesforce-metadata` 模块) - 所有必需字段都包含在内 - 字段类型和长度合理 - 主键、外键、索引设计正确 - 考虑字符集和排序规则(utf8mb4) - 考虑分表分库的扩展性 - 所有表包含 `dept_id` 字段用于部门数据隔离 - 所有表继承 `BaseEntity` 的审计字段 - **依赖关系**: 无 - **实现建议**: - 参考现有模块的数据库设计规范 - 使用 MySQL DDL 语法创建表结构 - 遵循项目命名规范(表名、字段名、类名) - 参考现有实体类的设计模式(Lombok、Swagger、Excel 注解) - 参考现有 Mapper 的设计模式(XML 配置、动态 SQL) #### 2. 数据库表创建 - **需求描述**: 创建数据库表DDL脚本,并在MySQL中执行创建表 - **优先级**: 高 - **验收标准**: - DDL脚本创建成功 - DDL脚本可以在MySQL中成功执行 - 所有9张表创建成功 - 表结构符合设计规范 - 索引创建成功 - 外键约束创建成功 - 添加必要的注释说明 - 字符集和排序规则设置正确 - **依赖关系**: 依赖于数据库表结构设计 - **实现建议**: - 使用 MySQL 命令行或数据库管理工具执行 DDL 脚本 - 参考 `datai-salesforce-auth` 模块的表创建方式 - 确保 DDL 脚本可重复执行(使用 `IF NOT EXISTS`) #### 3. 新增表结构设计 基于参考资料 `005-源数据拉取数据库设计方案.md`,需要新增以下 3 张表: ##### 3.1 datai_meta_package_item (元数据包定义明细表) - **需求描述**: 为了避免手动拼写 `package.xml`,需要将"我要拉取什么"结构化存储。此表通常与 Task 或特定的"发布包"关联 - **优先级**: 高 - **验收标准**: - 表结构设计完成 - 包含所有必需字段(id、group_id、metadata_type、member_name、description) - 字段类型和长度合理 - 索引设计正确 - 包含 `dept_id` 字段用于部门数据隔离 - 继承 `BaseEntity` 的审计字段 - 创建对应的 Domain 实体类、Mapper 接口和 Mapper XML - **依赖关系**: 无 - **实现建议**: - 参考参考资料中的字段设计 - 参考 `DataiMetaTask` 的实体类设计模式 - 参考 `DataiMetaTaskMapper` 的 Mapper 设计模式 ##### 3.2 datai_meta_component_version (元数据版本内容表) - **需求描述**: 这是实现"Java 版 Git"的核心表。每次拉取如果内容发生变化,就在此增加一条记录 - **优先级**: 高 - **验收标准**: - 表结构设计完成 - 包含所有必需字段(id、component_id、version_number、content_hash、content_body、is_binary、commit_message、job_execution_id、created_at) - 字段类型和长度合理 - 索引设计正确 - content_hash 字段使用 VARCHAR 存储 SHA-256 哈希值 - content_body 字段使用 LONGTEXT 存储实际代码内容 - 包含 `dept_id` 字段用于部门数据隔离 - 继承 `BaseEntity` 的审计字段 - 创建对应的 Domain 实体类、Mapper 接口和 Mapper XML - **依赖关系**: 依赖于 datai_meta_component 表 - **实现建议**: - 参考参考资料中的字段设计 - 参考 `DataiMetaComponent` 的实体类设计模式 - 参考 `DataiMetaComponentMapper` 的 Mapper 设计模式 ##### 3.3 datai_meta_deploy_component_result (部署组件结果明细表) - **需求描述**: CI/CD 最重要的部分,告知用户具体哪个文件失败了 - **优先级**: 高 - **验收标准**: - 表结构设计完成 - 包含所有必需字段(id、deploy_history_id、component_name、component_type、file_name、is_success、is_changed、line_number、column_number、problem、problem_type) - 字段类型和长度合理 - 索引设计正确 - line_number 和 column_number 字段用于记录错误位置 - problem 字段使用 TEXT 存储具体报错信息 - 包含 `dept_id` 字段用于部门数据隔离 - 继承 `BaseEntity` 的审计字段 - 创建对应的 Domain 实体类、Mapper 接口和 Mapper XML - **依赖关系**: 依赖于 datai_meta_deploy_history 表 - **实现建议**: - 参考参考资料中的字段设计 - 参考 `DataiMetaDeployHistory` 的实体类设计模式 - 参考 `DataiMetaDeployHistoryMapper` 的 Mapper 设计模式 ## 约束 - **技术栈限制**: - 必须使用 MySQL 5.7 及以上版本 - 必须使用 MyBatis Plus 作为持久层框架 - 必须使用 Java 22 - 必须使用 Spring Boot 框架 - **数据库约束**: - 必须使用 `utf8mb4` 字符集 - 必须使用 `utf8mb4_general_ci` 或 `utf8mb4_unicode_ci` 排序规则 - 所有表必须包含 `dept_id` 字段用于部门数据隔离 - 所有表必须继承 `BaseEntity` 的审计字段 - **命名约束**: - 表名必须使用 `datai_` 前缀,采用 snake_case 命名 - 字段名必须采用 snake_case 命名 - Java 类名必须采用 PascalCase 命名 - Java 属性名必须采用 camelCase 命名 - **性能约束**: - 必须设计合理的索引以提高查询性能 - 主键使用 `BIGINT` 类型 - 时间字段使用 `DATETIME` 或 `TIMESTAMP` 类型 - 布尔字段使用 `TINYINT(1)` 或 `BOOLEAN` 类型 - **扩展性约束**: - 必须考虑分表分库的扩展性 - 表结构支持后续功能扩展 - 使用 `IF NOT EXISTS` 确保 DDL 脚本可重复执行 - **兼容性约束**: - 必须兼容 MySQL 5.7 及以上版本 - 必须兼容 MyBatis Plus 框架 - 必须兼容 Spring Boot 框架 - **代码规范约束**: - 实体类必须使用 Lombok 注解(`@Data`, `@Builder`, `@NoArgsConstructor`, `@AllArgsConstructor`) - 实体类必须使用 Swagger 注解(`@Schema`, `@Schema(title="字段描述")`) - 实体类必须使用 Excel 注解(`@Excel(name="字段名称")`) - 实体类必须使用 `ToStringBuilder` 实现 `toString()` 方法 - Mapper XML 必须使用表别名提高可读性 - Mapper XML 必须使用 `` 定义结果映射 - Mapper XML 必须使用 `` 定义可重用的 SQL 片段 - Mapper XML 必须使用 `` 和 `` 实现动态 SQL - Mapper XML 必须使用 `useGeneratedKeys="true"` 和 `keyProperty="id"` 支持主键回填 ## Rule Set "请严格参考 @Authentication.canvas 中的状态机转移逻辑,不要自行发挥。" **具体规则**: - 必须使用 Canvas 中定义的类名和方法名 - 必须遵循 Canvas 中定义的调用关系 - 必须参考 Canvas 中的流程图逻辑 ## 验收标准 - **功能完整性**: - 所有9张表的 DDL 脚本创建成功 - 表结构完整,包含所有必需字段 - 所有表包含 `dept_id` 字段用于部门数据隔离 - 所有表继承 `BaseEntity` 的审计字段 - **数据完整性**: - 表结构包含所有必需字段 - 字段类型合理,符合项目技术规范 - 字段长度设置合理,避免数据截断 - 字段命名符合 snake_case 规范 - 表命名符合 `datai_` 前缀 + snake_case 规范 - **性能指标**: - 索引设计合理,查询性能满足要求 - 主键使用 `BIGINT` 类型 - 外键字段创建索引 - 常用查询条件字段创建索引 - 组合索引根据查询频率和选择性设计 - **扩展性**: - 表结构支持后续功能扩展 - 考虑分表分库的扩展性 - 使用 `IF NOT EXISTS` 确保 DDL 脚本可重复执行 - 预留扩展字段 - **可维护性**: - DDL 脚本有清晰的注释,易于理解和维护 - 表和字段注释完整 - 索引命名规范(`idx_表名_字段名`) - 遵循项目命名规范 - **代码规范**: - 创建对应的 Domain 实体类,使用 Lombok 注解 - 创建对应的 Mapper 接口,定义标准的 CRUD 方法 - 创建对应的 Mapper XML,使用表别名、``、``、动态 SQL - 实体类使用 Swagger 注解和 Excel 注解 - 实体类使用 `ToStringBuilder` 实现 `toString()` 方法 - **兼容性**: - DDL 脚本可以在 MySQL 5.7 及以上版本成功执行 - 兼容 MyBatis Plus 框架 - 兼容 Spring Boot 框架 - 字符集和排序规则设置正确(`utf8mb4`) ## 风险 - **表结构设计风险**: - 表结构设计不合理可能导致后续扩展困难 - 字段类型选择不当可能导致数据丢失或性能问题 - 缺少 `dept_id` 字段可能导致部门数据隔离失败 - 缺少审计字段可能导致数据追溯困难 - **索引设计风险**: - 索引设计不当可能影响查询性能 - 过多的索引可能影响插入和更新性能 - 组合索引顺序不当可能导致索引失效 - 缺少必要的索引可能导致查询慢 - **字段类型风险**: - 字段类型选择不当可能导致数据丢失 - 字段长度设置过小可能导致数据截断 - 时间字段类型选择不当可能导致时区问题 - 布尔字段类型选择不当可能导致兼容性问题 - **外键约束风险**: - 外键约束可能影响数据插入性能 - 外键约束可能导致级联删除问题 - 外键约束可能导致数据迁移困难 - 外键约束可能导致死锁 - **DDL执行风险**: - DDL脚本执行失败可能导致表创建失败 - DDL脚本执行顺序错误可能导致依赖关系问题 - DDL脚本缺少 `IF NOT EXISTS` 可能导致重复执行失败 - DDL脚本字符集设置错误可能导致乱码 - **代码生成风险**: - 实体类生成错误可能导致数据映射失败 - Mapper 接口生成错误可能导致 SQL 执行失败 - Mapper XML 配置错误可能导致查询失败 - 注解使用错误可能导致功能异常 - **命名规范风险**: - 表命名不符合规范可能导致混淆 - 字段命名不符合规范可能导致映射错误 - 类命名不符合规范可能导致代码可读性差 - 属性命名不符合规范可能导致序列化问题 - **兼容性风险**: - MySQL 版本不兼容可能导致语法错误 - MyBatis Plus 版本不兼容可能导致功能异常 - Spring Boot 版本不兼容可能导致启动失败 - 字符集不兼容可能导致乱码 ## 参考实现示例 基于 `datai-salesforce-auth` 和 `datai-salesforce-metadata` 模块的实际实现,提供以下参考示例: ### 1. 实体类参考示例 参考 [DataiSfLoginHistory.java](file:///d:\idea_demo\datai\datai-scenes\datai-scene-salesforce\datai-salesforce-auth\src\main\java\com\datai\auth\model\domain\DataiSfLoginHistory.java) 和 [DataiMetaTask.java](file:///d:\idea_demo\datai\datai-scenes\datai-scene-salesforce\datai-salesforce-metadata\src\main\java\com\datai\metadata\model\domain\DataiMetaTask.java): ```java @Data @Builder @NoArgsConstructor @AllArgsConstructor @Schema(description = "元数据任务定义对象") public class DataiMetaTask extends BaseEntity { private static final long serialVersionUID = 1L; @Schema(title = "主键ID") private Long id; @Schema(title = "任务名称") @Excel(name = "任务名称") private String taskName; @Schema(title = "任务类型") @Excel(name = "任务类型") private String taskType; @Schema(title = "组织配置ID") @Excel(name = "组织配置ID") private Long orgConfigId; @Schema(title = "部门ID") private Long deptId; @Override public String toString() { return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE) .append("id", getId()) .append("taskName", getTaskName()) .append("taskType", getTaskType()) .append("orgConfigId", getOrgConfigId()) .append("deptId", getDeptId()) .append("createBy", getCreateBy()) .append("createTime", getCreateTime()) .append("updateBy", getUpdateBy()) .append("updateTime", getUpdateTime()) .append("remark", getRemark()) .toString(); } } ``` ### 2. Mapper 接口参考示例 参考 [DataiSfLoginHistoryMapper.java](file:///d:\idea_demo\datai\datai-scenes\datai-scene-salesforce\datai-salesforce-auth\src\main\java\com\datai\auth\mapper\DataiSfLoginHistoryMapper.java): ```java public interface DataiMetaTaskMapper { DataiMetaTask selectDataiMetaTaskById(Long id); List selectDataiMetaTaskList(DataiMetaTask dataiMetaTask); int insertDataiMetaTask(DataiMetaTask dataiMetaTask); int updateDataiMetaTask(DataiMetaTask dataiMetaTask); int deleteDataiMetaTaskById(Long id); int deleteDataiMetaTaskByIds(Long[] ids); } ``` ### 3. Mapper XML 参考示例 参考 [DataiMetaTaskMapper.xml](file:///d:\idea_demo\datai\datai-scenes\datai-scene-salesforce\datai-salesforce-metadata\src\main\resources\mapper\metadata\DataiMetaTaskMapper.xml): ```xml select dmt.id, dmt.task_name, dmt.task_type, dmt.org_config_id, dmt.dept_id, dmt.create_by, dmt.create_time, dmt.update_by, dmt.update_time, dmt.remark from datai_meta_task dmt insert into datai_meta_task task_name, task_type, org_config_id, dept_id, create_by, create_time, update_by, update_time, remark, #{taskName}, #{taskType}, #{orgConfigId}, #{deptId}, #{createBy}, #{createTime}, #{updateBy}, #{updateTime}, #{remark}, ``` ### 4. DDL 脚本参考示例 ```sql CREATE TABLE IF NOT EXISTS `datai_meta_task` ( `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键ID', `task_name` VARCHAR(100) NOT NULL COMMENT '任务名称', `task_type` VARCHAR(50) NOT NULL COMMENT '任务类型', `org_config_id` BIGINT NOT NULL COMMENT '组织配置ID', `dept_id` BIGINT DEFAULT NULL COMMENT '部门ID', `create_by` VARCHAR(64) DEFAULT '' COMMENT '创建者', `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `update_by` VARCHAR(64) DEFAULT '' COMMENT '更新者', `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', `remark` VARCHAR(500) DEFAULT NULL COMMENT '备注', PRIMARY KEY (`id`), KEY `idx_datai_meta_task_org_config_id` (`org_config_id`), KEY `idx_datai_meta_task_dept_id` (`dept_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='元数据任务定义表'; ``` ## 需求变更记录 | 日期 | 变更内容 | 变更原因 | 变更人 | 审核人 | 状态 | |------|---------|---------|--------|--------|------| | 2026-01-17 | 创建需求文档 | 初始需求 | 系统管理员 | - | 待审核 | | 2026-01-17 | 优化需求文档 | 基于参考资料 `005-源数据拉取数据库设计方案.md` 优化表设计,从 6 张表增加到 9 张表 | SSOT Architect | - | 待审核 | ## 相关人员 - **需求提出人**: 系统管理员 - 联系方式 - **需求负责人**: 系统管理员 - 联系方式 - **技术负责人**: 开发工程师 - 联系方式 - **测试负责人**: 测试工程师 - 联系方式 - **其他相关人员**: 数据库管理员 - 联系方式 ## 评审信息 - **评审日期**: - - **评审人员**: - - **评审结果**: - - **评审意见**: - - **修改建议**: -