datai/docs/skill/phase4-database-schema.md
Kris b7163d555b feat: 实现动态数据源延迟加载功能 (2026-01-21-001)
## 功能概述
- 实现动态数据源的延迟加载机制,支持应用启动时只加载主库,从库按需动态加载和切换
- 从库配置存储在主库中,支持运行时灵活切换从库库名
- 使用现有的 @DataSource 注解进行数据源切换,业务代码无需修改

## 新增功能
- 动态数据源管理接口 IDynamicDataSourceManager
- 动态数据源服务接口 IDynamicDataSourceService
- 动态数据源服务实现 DynamicDataSourceServiceImpl
- 数据源管理控制器 DatasourceController
- 数据源配置表 sys_datasource_config

## 新增文档
- 需求文档: docs/requirements/2026-01-21-001-动态数据源延迟加载.md
- 设计文档: docs/design/2026-01-21-001-动态数据源延迟加载设计.md
- 决策记录: docs/decisions/2026-01-21-001-ADR-动态数据源延迟加载.md
- SQL 脚本: docs/sql/2026-01-21-001-sys_datasource_config.sql
- 提示词: docs/prompts/2026-01-21-001-动态数据源延迟加载代码生成提示词.md
- 会话记录: docs/sessions/2026-01-21-001-session.md
- 变更日志: docs/changelog/2026-01-21-001-changelog.md
- 复盘文档: docs/retros/2026-01-21-001-retro.md
- API 文档: docs/api-docs/2026-01-21-001-api.md
- 根目录变更日志: CHANGELOG.md

## 修改功能
- 扩展 DataSourceManager 类,添加动态数据源管理方法
- 扩展 SysDatasourceConfigMapper 接口,添加 selectSysDatasourceConfigByDsName 方法
- 更新项目索引和 Authentication.canvas

## 修复问题
- 修复循环依赖问题:创建 IDynamicDataSourceManager 接口解决 datai-system 和 datai-framework 互相依赖
- 修复导入错误:删除 DynamicDataSourceServiceImpl 中未使用的导入
- 修复异常处理:将 setFilters() 调用移到 try-catch 块内

## API 接口
- POST /system/datasource/loadSlave - 加载从库数据源
- POST /system/datasource/switchSlave/{dbName} - 切换从库库名
- GET /system/datasource/getSlaveConfig - 获取从库配置
- POST /system/datasource/switch/{dsName} - 切换数据源
- DELETE /system/datasource/{dsName} - 移除数据源
2026-01-21 18:24:24 +08:00

18 KiB
Raw Blame History

阶段 4数据库结构生成技能书

A. 元数据 (Metadata)

name: phase4-database-schema

description: 在 Datai 项目中,基于已创建的设计文档和决策记录,分析需求是否涉及数据库变更,生成标准化的 SQL 脚本,并更新索引和会话记录。此技能确保数据库变更的可追溯性和准确性。


B. 触发与定位 (Triggers & Scope)

触发关键词

当用户输入包含以下关键词时,必须觉醒此技能:

  • "数据库结构"、"SQL 脚本"、"DDL"
  • "数据库变更"、"表设计"、"字段设计"
  • "进入阶段 4"、"下一阶段"
  • "数据库"、"表"、"字段"

触发场景

  • 用户确认阶段 3 完成,要求进入阶段 4
  • 用户要求生成 SQL 脚本
  • 用户询问如何设计数据库结构
  • 用户提到"按照项目规则"或"SSOT 流程"进行数据库设计

操作路径

此技能涉及以下文件和目录的操作:

  • 读取: docs/design/YYYY-MM-DD-00X-设计名.md (阶段 2 创建的设计文档)
  • 创建: docs/sql/YYYY-MM-DD-00X-数据库名.sql
  • 更新: docs/index.md
  • 更新: docs/design/YYYY-MM-DD-00X-设计名.md (添加 SQL 脚本引用)
  • 更新: docs/sessions/YYYY-MM-DD-00X-session.md
  • 读取: .trae/rules/project_rules.md (项目规则)
  • 读取: docs/Prompt/0004-单一真源文档驱动架构师.md (SSOT 架构师提示词)

SSOT 依赖

必须参考以下"唯一真源"


C. 核心指令集 (Instructions)

架构约束

1. 脚本命名规范(强制)

  • 必须使用格式:YYYY-MM-DD-00X-数据库名.sql
  • YYYY-MM-DD:当前日期(如 2026-01-21
  • 00X:需求编号(与阶段 1-3 保持一致)
  • 数据库名:简洁描述,使用中文或英文,如"user-login"、"订单表"
  • 严禁使用无意义的文件名

2. 脚本内容约束(强制)

SQL 脚本必须包含以下内容:

  • 脚本说明(-- 注释)
  • 建表语句CREATE TABLE
  • 修改语句ALTER TABLE如果需要
  • 索引语句CREATE INDEX如果需要
  • 数据插入语句INSERT INTO如果需要如数据字典
  • 脚本结束标识

3. 数据库规范约束(强制)

  • 表命名:使用小写字母,单词之间用下划线分隔,如 sys_user
  • 字段命名:使用小写字母,单词之间用下划线分隔,如 user_name
  • 字段类型
    • 字符串VARCHAR(长度),如 VARCHAR(30)
    • 数字INT, BIGINT, DECIMAL(精度, 小数位数),如 BIGINT, DECIMAL(10, 2)
    • 日期DATETIME, DATE, TIMESTAMPDATETIME
  • 主键约束:每个表必须有主键,命名格式:PRIMARY KEY (id)
  • 外键约束:命名格式:FK_表名_关联表名,如 FK_sys_user_sys_dept
  • 索引约束:命名格式:IDX_表名_字段名,如 IDX_sys_user_user_name
  • 注释:每个表和字段必须有注释,使用 COMMENT 关键字

4. 条件约束(强制)

  • 必须分析需求是否涉及数据库变更
  • 如果不涉及,跳过此阶段,直接进入阶段 5
  • 如果涉及,识别需要变更的表和字段

5. 索引更新约束(强制)

  • 必须在生成 SQL 脚本后立即更新 docs/index.md
  • 必须更新设计文档,添加 SQL 脚本引用
  • 采用增量更新策略,严禁删除现有内容
  • 索引链接格式:[文档名](./相对路径/文件名.md)
  • 必须在 docs/index.md 中添加到"SQL 脚本"部分

6. 会话记录约束(强制)

  • 必须更新 docs/sessions/YYYY-MM-DD-00X-session.md
  • 必须更新当前阶段为"阶段 4数据库结构生成"
  • 必须记录是否涉及数据库变更
  • 必须记录 SQL 脚本链接

业务逻辑 SOP标准操作流程

步骤 1需求分析Let's think step by step

在生成 SQL 脚本前,必须执行以下分析:

  1. 分析需求是否涉及数据库变更

    • 读取阶段 2 创建的设计文档
    • 检查设计文档中的"数据模型"部分
    • 检查是否需要创建新表
    • 检查是否需要修改现有表
    • 检查是否需要添加索引
    • 检查是否需要插入初始数据(如数据字典)
  2. 如果不涉及,跳过此阶段

    • 记录到会话记录中
    • 直接进入阶段 5
  3. 如果涉及,识别需要变更的表和字段

    • 识别需要创建的新表
    • 识别需要修改的现有表
    • 识别需要添加的字段
    • 识别需要修改的字段
    • 识别需要删除的字段
    • 识别需要添加的索引
    • 识别需要插入的初始数据

步骤 2生成 SQL 脚本

  1. 确定脚本路径

    • 路径:docs/sql/YYYY-MM-DD-00X-数据库名.sql
    • 使用 Write 工具创建文件
    • 确保目录存在(使用 LS 工具检查)
  2. 编写脚本内容

    • 脚本说明:使用 -- 注释,说明脚本的用途、创建时间、创建人等
    • 建表语句
      -- 创建用户表
      CREATE TABLE `sys_user` (
        `user_id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '用户ID',
        `user_name` VARCHAR(30) NOT NULL COMMENT '用户名',
        `password` VARCHAR(100) NOT NULL COMMENT '密码',
        `dept_id` BIGINT NOT NULL COMMENT '部门ID',
        `status` CHAR(1) NOT NULL DEFAULT '0' COMMENT '状态0正常 1停用',
        `create_time` DATETIME NOT NULL COMMENT '创建时间',
        `update_time` DATETIME NOT NULL COMMENT '更新时间',
        PRIMARY KEY (`user_id`),
        INDEX `IDX_sys_user_user_name` (`user_name`),
        FOREIGN KEY (`dept_id`) REFERENCES `sys_dept` (`dept_id`) ON DELETE CASCADE
      ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';
      
    • 修改语句
      -- 修改用户表,添加新字段
      ALTER TABLE `sys_user` ADD COLUMN `email` VARCHAR(50) COMMENT '邮箱' AFTER `password`;
      
    • 索引语句
      -- 为用户表添加索引
      CREATE INDEX `IDX_sys_user_email` ON `sys_user` (`email`);
      
    • 数据插入语句
      -- 插入数据字典
      INSERT INTO `sys_dict_data` (`dict_type`, `dict_label`, `dict_value`, `status`) VALUES
      ('sys_user_status', '正常', '0', '0'),
      ('sys_user_status', '停用', '1', '0');
      
    • 脚本结束标识
      -- 脚本执行完成
      
  3. 脚本质量检查

    • 使用 Read 工具读取刚创建的脚本
    • 检查是否符合脚本内容约束
    • 检查是否符合数据库规范约束
    • 检查 SQL 语法是否正确
    • 检查表和字段注释是否完整

步骤 3更新索引和设计文档

  1. 读取现有索引

    • 使用 Read 工具读取 docs/index.md
    • 找到"SQL 脚本"部分
    • 如果不存在,则创建该部分
  2. 添加新 SQL 脚本链接

    • 在"SQL 脚本"部分追加新脚本
    • 格式:- [SQL 脚本名](./sql/YYYY-MM-DD-00X-数据库名.sql) - [描述]
    • 示例:- [用户登录功能-SQL 脚本](./sql/2026-01-21-001-user-login.sql) - 创建用户表和相关索引
  3. 更新设计文档

    • 使用 Read 工具读取设计文档
    • 在"相关文档"部分添加 SQL 脚本引用
    • 格式:- [SQL 脚本](../sql/YYYY-MM-DD-00X-数据库名.sql)
    • 使用 Write 工具更新设计文档
  4. 保存索引

    • 使用 Write 工具更新 docs/index.md
    • 严禁删除现有内容,只追加新内容

步骤 4更新会话记录

  1. 读取现有会话记录

    • 使用 Read 工具读取 docs/sessions/YYYY-MM-DD-00X-session.md
  2. 更新阶段 4 信息

    • 更新"当前阶段"为"阶段 4数据库结构生成"
    • 更新"阶段 4数据库结构生成"的状态为"已完成"
    • 记录是否涉及数据库变更
    • 添加生成的 SQL 脚本链接
    • 记录关键数据库变更内容
  3. 保存会话记录

    • 使用 Write 工具更新会话记录

步骤 5确认与询问

  1. 向用户确认

    • 显示 SQL 脚本的链接
    • 询问:"SQL 脚本是否正确?"
    • 询问:"是否进入下一阶段(提示词生成)?"
  2. 等待用户反馈

    • 如果用户不满意,询问具体需要修改的地方
    • 如果用户要求回退,执行回退机制(见错误陷阱部分)
    • 如果用户确认,标记阶段 4 为已完成,准备进入阶段 5

工具调用

必须使用的工具

  1. Read 工具:读取现有文件

    • 使用场景:读取设计文档、读取索引、读取会话记录
    • 命令:Read(file_path="d:\\idea_demo\\datai\\docs\\design\\2026-01-21-001-用户登录功能-设计.md")
  2. Write 工具:创建或更新文件

    • 使用场景:生成 SQL 脚本、更新索引、更新设计文档、更新会话记录
    • 命令:Write(file_path="d:\\idea_demo\\datai\\docs\\sql\\2026-01-21-001-user-login.sql", content="...")
  3. LS 工具:检查目录是否存在

    • 使用场景:创建脚本前检查 docs/sql/ 目录
    • 命令:LS(path="d:\\idea_demo\\datai\\docs")

可选使用的工具

  1. SearchCodebase 工具:搜索现有 SQL 脚本

    • 使用场景:查找现有 SQL 脚本作为参考
    • 命令:SearchCodebase(information_request="查找 docs/sql 目录下的所有 SQL 脚本")
  2. Glob 工具:查找文件

    • 使用场景:查找所有 SQL 脚本
    • 命令:Glob(pattern="docs/sql/*.sql")
  3. TodoWrite 工具:管理任务

    • 使用场景:跟踪阶段执行进度
    • 命令:TodoWrite(todos=[...])

D. 错误陷阱与验证 (Anti-Patterns & Checklist)

常见错误Anti-Patterns

错误 1不分析需求直接生成 SQL 脚本

错误示例

用户:进入阶段 4
AI直接生成 SQL 脚本,不分析需求是否涉及数据库变更

正确示例

用户:进入阶段 4
AI让我先分析需求是否涉及数据库变更...
AI读取设计文档检查数据模型部分...
AI如果涉及数据库变更生成 SQL 脚本...
AI如果不涉及跳过此阶段直接进入阶段 5...

错误 2SQL 脚本缺少注释

错误示例

CREATE TABLE sys_user (
  user_id BIGINT NOT NULL AUTO_INCREMENT,
  user_name VARCHAR(30) NOT NULL,
  password VARCHAR(100) NOT NULL,
  PRIMARY KEY (user_id)
) ENGINE=InnoDB;

问题

  • 缺少脚本说明
  • 缺少表注释
  • 缺少字段注释

正确示例

-- 用户登录功能 SQL 脚本
-- 创建时间2026-01-21
-- 创建人AI Assistant

-- 创建用户表
CREATE TABLE `sys_user` (
  `user_id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '用户ID',
  `user_name` VARCHAR(30) NOT NULL COMMENT '用户名',
  `password` VARCHAR(100) NOT NULL COMMENT '密码',
  PRIMARY KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';

错误 3SQL 语法错误

错误示例

CREATE TABLE sys_user (
  user_id BIGINT NOT NULL AUTO_INCREMENT,
  user_name VARCHAR(30) NOT NULL,
  password VARCHAR(100) NOT NULL,
  PRIMARY KEY (user_id)
  INDEX IDX_sys_user_user_name (user_name)
) ENGINE=InnoDB;

问题

  • 主键约束和索引约束之间缺少逗号

正确示例

CREATE TABLE sys_user (
  user_id BIGINT NOT NULL AUTO_INCREMENT,
  user_name VARCHAR(30) NOT NULL,
  password VARCHAR(100) NOT NULL,
  PRIMARY KEY (user_id),
  INDEX IDX_sys_user_user_name (user_name)
) ENGINE=InnoDB;

错误 4不遵循数据库规范

错误示例

CREATE TABLE SysUser (
  UserId BIGINT NOT NULL AUTO_INCREMENT,
  UserName VARCHAR(30) NOT NULL,
  PRIMARY KEY (UserId)
) ENGINE=InnoDB;

问题

  • 表名使用驼峰命名,不符合规范(应使用下划线分隔)
  • 字段名使用驼峰命名,不符合规范(应使用下划线分隔)

正确示例

CREATE TABLE `sys_user` (
  `user_id` BIGINT NOT NULL AUTO_INCREMENT,
  `user_name` VARCHAR(30) NOT NULL,
  PRIMARY KEY (`user_id`)
) ENGINE=InnoDB;

错误 5不更新设计文档的 SQL 脚本引用

错误示例

AI生成 SQL 脚本
AI更新 docs/index.md
AI完成忘记更新设计文档

正确示例

AI生成 SQL 脚本
AI更新 docs/index.md
AI更新设计文档添加 SQL 脚本引用
AI完成

错误 6不询问用户确认就进入下一阶段

错误示例

AI生成 SQL 脚本
AI进入阶段 5提示词生成未询问用户

正确示例

AI生成 SQL 脚本
AISQL 脚本已生成:[链接]
AISQL 脚本是否正确?
AI是否进入下一阶段提示词生成

验收清单Checklist

在完成阶段 4 前,必须检查以下项目:

脚本完整性检查

  • SQL 脚本已创建在 docs/sql/ 目录下(如果涉及数据库变更)
  • 脚本命名符合 YYYY-MM-DD-00X-数据库名.sql 格式
  • 脚本包含脚本说明(注释)
  • 脚本包含建表语句(如果需要)
  • 脚本包含修改语句(如果需要)
  • 脚本包含索引语句(如果需要)
  • 脚本包含数据插入语句(如果需要)
  • 脚本包含脚本结束标识

脚本质量检查

  • SQL 语法正确
  • 表命名符合规范(小写字母,下划线分隔)
  • 字段命名符合规范(小写字母,下划线分隔)
  • 字段类型选择合理
  • 每个表都有主键
  • 每个表和字段都有注释
  • 索引命名符合规范
  • 外键命名符合规范

条件检查

  • 已分析需求是否涉及数据库变更
  • 如果不涉及,已跳过此阶段,直接进入阶段 5
  • 如果涉及,已识别需要变更的表和字段

索引更新检查

  • docs/index.md 已更新(如果涉及数据库变更)
  • 新 SQL 脚本链接已添加到"SQL 脚本"部分
  • 索引链接格式正确:[文档名](./相对路径/文件名.md)
  • 索引更新采用增量策略,未删除现有内容

设计文档更新检查

  • 设计文档已更新(如果涉及数据库变更)
  • 设计文档的"相关文档"部分已添加 SQL 脚本引用
  • SQL 脚本链接格式正确:[SQL 脚本](../sql/YYYY-MM-DD-00X-数据库名.sql)

会话记录更新检查

  • 会话记录已更新
  • 会话记录的"当前阶段"已更新为"阶段 4数据库结构生成"
  • 会话记录的"阶段 4数据库结构生成"状态已更新为"已完成"
  • 会话记录包含是否涉及数据库变更的记录
  • 会话记录包含 SQL 脚本链接(如果涉及数据库变更)
  • 会话记录包含关键数据库变更内容(如果涉及数据库变更)

用户确认检查

  • 已向用户显示 SQL 脚本链接(如果涉及数据库变更)
  • 已询问用户"SQL 脚本是否正确?"(如果涉及数据库变更)
  • 已询问用户"是否进入下一阶段?"
  • 已等待用户反馈

回退机制检查(如果需要)

  • 如果用户不满意,已询问具体需要修改的地方
  • 如果用户要求回退,已删除相关文档
  • 如果用户要求回退,已撤销索引更新
  • 如果用户要求回退,已撤销设计文档更新
  • 如果用户要求回退,已更新会话记录

Correct vs Incorrect 代码对比

Incorrect错误示例

CREATE TABLE SysUser (
  UserId BIGINT NOT NULL AUTO_INCREMENT,
  UserName VARCHAR(30) NOT NULL,
  Password VARCHAR(100) NOT NULL,
  PRIMARY KEY (UserId)
) ENGINE=InnoDB;

Correct正确示例

-- 用户登录功能 SQL 脚本
-- 创建时间2026-01-21
-- 创建人AI Assistant

-- 创建用户表
CREATE TABLE `sys_user` (
  `user_id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '用户ID',
  `user_name` VARCHAR(30) NOT NULL COMMENT '用户名',
  `password` VARCHAR(100) NOT NULL COMMENT '密码',
  `dept_id` BIGINT NOT NULL COMMENT '部门ID',
  `status` CHAR(1) NOT NULL DEFAULT '0' COMMENT '状态0正常 1停用',
  `create_time` DATETIME NOT NULL COMMENT '创建时间',
  `update_time` DATETIME NOT NULL COMMENT '更新时间',
  PRIMARY KEY (`user_id`),
  INDEX `IDX_sys_user_user_name` (`user_name`),
  FOREIGN KEY (`dept_id`) REFERENCES `sys_dept` (`dept_id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';

-- 插入用户状态数据字典
INSERT INTO `sys_dict_data` (`dict_type`, `dict_label`, `dict_value`, `status`) VALUES
('sys_user_status', '正常', '0', '0'),
('sys_user_status', '停用', '1', '0');

-- 脚本执行完成

附录:快速参考

文件路径速查

  • 设计文档:docs/design/YYYY-MM-DD-00X-设计名.md
  • SQL 脚本:docs/sql/YYYY-MM-DD-00X-数据库名.sql
  • 主索引:docs/index.md
  • 会话记录:docs/sessions/YYYY-MM-DD-00X-session.md
  • 项目规则:.trae/rules/project_rules.md
  • SSOT 架构师提示词:docs/Prompt/0004-单一真源文档驱动架构师.md

工具命令速查

# 读取设计文档
Read(file_path="d:\\idea_demo\\datai\\docs\\design\\2026-01-21-001-用户登录功能-设计.md")

# 生成 SQL 脚本
Write(file_path="d:\\idea_demo\\datai\\docs\\sql\\2026-01-21-001-user-login.sql", content="...")

# 读取索引
Read(file_path="d:\\idea_demo\\datai\\docs\\index.md")

# 更新索引
Write(file_path="d:\\idea_demo\\datai\\docs\\index.md", content="...")

# 搜索现有 SQL 脚本
SearchCodebase(information_request="查找 docs/sql 目录下的所有 SQL 脚本")

# 查找所有 SQL 脚本
Glob(pattern="docs/sql/*.sql")

阶段 4 输出清单

  • SQL 脚本:docs/sql/YYYY-MM-DD-00X-数据库名.sql(如果涉及数据库变更)
  • 更新的索引:docs/index.md(如果涉及数据库变更)
  • 更新的设计文档:docs/design/YYYY-MM-DD-00X-设计名.md(如果涉及数据库变更)
  • 更新的会话记录:docs/sessions/YYYY-MM-DD-00X-session.md

下一阶段提示

如果用户确认进入下一阶段,请参考:

  • project_rules.md 的"阶段 5提示词生成"
  • 准备分析需求的核心任务
  • 准备生成针对当前需求的提示词
  • 准备更新索引和会话记录