datai/docs/archive/REQ-010-1.md

21 KiB
Raw Permalink Blame History

Requirements - 数据库表结构设计和创建

需求信息

  • 需求名称: 数据库表结构设计和创建
  • 需求类型: 数据需求
  • 需求编号: REQ-010-1
  • 父需求: REQ-010
  • 创建日期: 2026-01-17
  • 需求版本: v1.0.0
  • 需求提出人: 系统管理员
  • 需求状态: 已完成

输入引用

引用相关的 docs 文档链接:

Context Maps

强制列出本次需求依赖的 Canvas 文件:

需求目标

设计和创建Salesforce元数据拉取和部署系统所需的9张核心数据库表为后续功能开发提供数据存储基础。

需求描述

概述

本需求旨在设计和创建Salesforce元数据拉取和部署系统所需的9张核心数据库表包括组织配置表、元数据包定义明细表、元数据组件索引表、元数据版本内容表、任务定义表、作业执行流水表、作业详细日志表、部署历史表、部署组件结果明细表。

技术规范参考

基于 datai-salesforce-authdatai-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
  • 使用 <resultMap> 定义结果映射
  • 使用 <sql> 定义可重用的 SQL 片段
  • 使用 <trim><if> 实现动态 SQL
  • 使用 useGeneratedKeys="true"keyProperty="id" 支持主键回填

4. 数据库设计规范

  • 字符集: 使用 utf8mb4 字符集
  • 排序规则: 使用 utf8mb4_general_ciutf8mb4_unicode_ci
  • 主键: 使用 BIGINT 类型,自增或雪花算法
  • 时间字段: 使用 DATETIMETIMESTAMP 类型
  • 布尔字段: 使用 TINYINT(1)BOOLEAN 类型
  • 部门隔离: 所有表必须包含 dept_id 字段用于部门数据隔离
  • 审计字段: 继承 BaseEntity 的审计字段(创建人、创建时间、更新人、更新时间、备注)

5. 索引设计规范

  • 主键自动创建索引
  • 外键字段创建索引
  • 常用查询条件字段创建索引
  • 组合索引根据查询频率和选择性设计
  • 索引命名规范:idx_表名_字段名(如 idx_datai_meta_task_org_config_id

详细需求

1. 数据库表结构设计

  • 需求描述: 设计9张核心数据库表的结构包括字段定义、类型选择、索引设计、外键约束等
  • 优先级: 高
  • 验收标准:
    • 所有9张表的DDL脚本设计完成
    • 表结构符合项目技术规范(参考 datai-salesforce-authdatai-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_ciutf8mb4_unicode_ci 排序规则
    • 所有表必须包含 dept_id 字段用于部门数据隔离
    • 所有表必须继承 BaseEntity 的审计字段
  • 命名约束:
    • 表名必须使用 datai_ 前缀,采用 snake_case 命名
    • 字段名必须采用 snake_case 命名
    • Java 类名必须采用 PascalCase 命名
    • Java 属性名必须采用 camelCase 命名
  • 性能约束:
    • 必须设计合理的索引以提高查询性能
    • 主键使用 BIGINT 类型
    • 时间字段使用 DATETIMETIMESTAMP 类型
    • 布尔字段使用 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 必须使用 <resultMap> 定义结果映射
    • Mapper XML 必须使用 <sql> 定义可重用的 SQL 片段
    • Mapper XML 必须使用 <trim><if> 实现动态 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使用表别名、<resultMap><sql>、动态 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-authdatai-salesforce-metadata 模块的实际实现,提供以下参考示例:

1. 实体类参考示例

参考 DataiSfLoginHistory.javaDataiMetaTask.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

public interface DataiMetaTaskMapper {
    DataiMetaTask selectDataiMetaTaskById(Long id);
    List<DataiMetaTask> selectDataiMetaTaskList(DataiMetaTask dataiMetaTask);
    int insertDataiMetaTask(DataiMetaTask dataiMetaTask);
    int updateDataiMetaTask(DataiMetaTask dataiMetaTask);
    int deleteDataiMetaTaskById(Long id);
    int deleteDataiMetaTaskByIds(Long[] ids);
}

3. Mapper XML 参考示例

参考 DataiMetaTaskMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.datai.metadata.mapper.DataiMetaTaskMapper">
    
    <resultMap type="DataiMetaTask" id="DataiMetaTaskResult">
        <result property="id" column="id" />
        <result property="taskName" column="task_name" />
        <result property="taskType" column="task_type" />
        <result property="orgConfigId" column="org_config_id" />
        <result property="deptId" column="dept_id" />
        <result property="createBy" column="create_by" />
        <result property="createTime" column="create_time" />
        <result property="updateBy" column="update_by" />
        <result property="updateTime" column="update_time" />
        <result property="remark" column="remark" />
    </resultMap>

    <sql id="selectDataiMetaTaskVo">
        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
    </sql>

    <insert id="insertDataiMetaTask" parameterType="DataiMetaTask" useGeneratedKeys="true" keyProperty="id">
        insert into datai_meta_task
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="taskName != null and taskName != ''">task_name,</if>
            <if test="taskType != null and taskType != ''">task_type,</if>
            <if test="orgConfigId != null">org_config_id,</if>
            <if test="deptId != null">dept_id,</if>
            <if test="createBy != null and createBy != ''">create_by,</if>
            <if test="createTime != null">create_time,</if>
            <if test="updateBy != null and updateBy != ''">update_by,</if>
            <if test="updateTime != null">update_time,</if>
            <if test="remark != null">remark,</if>
         </trim>
        <trim prefix="values (" suffix=")" suffixOverrides=",">
            <if test="taskName != null and taskName != ''">#{taskName},</if>
            <if test="taskType != null and taskType != ''">#{taskType},</if>
            <if test="orgConfigId != null">#{orgConfigId},</if>
            <if test="deptId != null">#{deptId},</if>
            <if test="createBy != null and createBy != ''">#{createBy},</if>
            <if test="createTime != null">#{createTime},</if>
            <if test="updateBy != null and updateBy != ''">#{updateBy},</if>
            <if test="updateTime != null">#{updateTime},</if>
            <if test="remark != null">#{remark},</if>
         </trim>
    </insert>
</mapper>

4. DDL 脚本参考示例

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 - 待审核

相关人员

  • 需求提出人: 系统管理员 - 联系方式
  • 需求负责人: 系统管理员 - 联系方式
  • 技术负责人: 开发工程师 - 联系方式
  • 测试负责人: 测试工程师 - 联系方式
  • 其他相关人员: 数据库管理员 - 联系方式

评审信息

  • 评审日期: -
  • 评审人员: -
  • 评审结果: -
  • 评审意见: -
  • 修改建议: -