# 阶段 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 依赖 必须参考以下"唯一真源": - [设计文档](file:///d:\idea_demo\datai\docs\design\YYYY-MM-DD-00X-设计名.md) - 阶段 2 创建的设计文档 - [project_rules.md](file:///d:\idea_demo\datai\.trae\rules\project_rules.md) - 项目规则和阶段定义 - [0004-单一真源文档驱动架构师.md](file:///d:\idea_demo\datai\docs\Prompt\0004-单一真源文档驱动架构师.md) - SSOT 架构师提示词 - `docs/sql/` 目录下的现有 SQL 脚本(作为格式参考) - 若依框架的数据库规范(如表前缀、字段命名等) --- ## 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, TIMESTAMP,如 `DATETIME` - **主键约束**:每个表必须有主键,命名格式:`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. **编写脚本内容** - **脚本说明**:使用 `--` 注释,说明脚本的用途、创建时间、创建人等 - **建表语句**: ```sql -- 创建用户表 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='用户表'; ``` - **修改语句**: ```sql -- 修改用户表,添加新字段 ALTER TABLE `sys_user` ADD COLUMN `email` VARCHAR(50) COMMENT '邮箱' AFTER `password`; ``` - **索引语句**: ```sql -- 为用户表添加索引 CREATE INDEX `IDX_sys_user_email` ON `sys_user` (`email`); ``` - **数据插入语句**: ```sql -- 插入数据字典 INSERT INTO `sys_dict_data` (`dict_type`, `dict_label`, `dict_value`, `status`) VALUES ('sys_user_status', '正常', '0', '0'), ('sys_user_status', '停用', '1', '0'); ``` - **脚本结束标识**: ```sql -- 脚本执行完成 ``` 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... ``` #### 错误 2:SQL 脚本缺少注释 **错误示例**: ```sql 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 -- 用户登录功能 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='用户表'; ``` #### 错误 3:SQL 语法错误 **错误示例**: ```sql 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; ``` **问题**: - 主键约束和索引约束之间缺少逗号 **正确示例**: ```sql 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:不遵循数据库规范 **错误示例**: ```sql CREATE TABLE SysUser ( UserId BIGINT NOT NULL AUTO_INCREMENT, UserName VARCHAR(30) NOT NULL, PRIMARY KEY (UserId) ) ENGINE=InnoDB; ``` **问题**: - 表名使用驼峰命名,不符合规范(应使用下划线分隔) - 字段名使用驼峰命名,不符合规范(应使用下划线分隔) **正确示例**: ```sql 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 脚本 AI:SQL 脚本已生成:[链接] AI:SQL 脚本是否正确? 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(错误示例) ```sql 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 -- 用户登录功能 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` ### 工具命令速查 ```powershell # 读取设计文档 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](file:///d:\idea_demo\datai\.trae\rules\project_rules.md) 的"阶段 5:提示词生成" - 准备分析需求的核心任务 - 准备生成针对当前需求的提示词 - 准备更新索引和会话记录