# 数据库迁移系统

<cite>
**本文引用的文件**
- [composer.json](file://composer.json)
- [AGENTS.MD](file://AGENTS.MD)
- [vendor/xia/migration/composer.json](file://vendor/xia/migration/composer.json)
- [vendor/xia/migration/src/Service.php](file://vendor/xia/migration/src/Service.php)
- [vendor/xia/migration/src/Creator.php](file://vendor/xia/migration/src/Creator.php)
- [vendor/xia/migration/src/Migrate.php](file://vendor/xia/migration/src/Migrate.php)
- [vendor/xia/migration/src/command/migrate/Create.php](file://vendor/xia/migration/src/command/migrate/Create.php)
- [vendor/xia/migration/src/command/migrate/Run.php](file://vendor/xia/migration/src/command/migrate/Run.php)
- [vendor/xia/migration/src/command/migrate/Rollback.php](file://vendor/xia/migration/src/command/migrate/Rollback.php)
- [vendor/xia/migration/phinx/src/Phinx/Migration/AbstractMigration.php](file://vendor/xia/migration/phinx/src/Phinx/Migration/AbstractMigration.php)
</cite>

## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖分析](#依赖分析)
7. [性能考虑](#性能考虑)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)

## 简介
本文件系统性阐述 ThinkCMF 的数据库迁移系统，围绕 xia/migration 包展开，覆盖迁移命令使用、迁移文件创建与编写、up()/down() 方法实现、迁移执行与回滚流程、数据库结构变更策略、数据迁移方法、最佳实践与常见场景解决方案。ThinkCMF 基于 ThinkPHP 8.x，采用 xia/migration 提供的迁移能力，底层依赖 Phinx，遵循 Phinx 迁移规范。

## 项目结构
- ThinkCMF 通过 Composer 引入 xia/migration，并在安装后自动注册迁移服务与命令。
- 迁移命令通过 ThinkPHP 控制台注册，支持创建迁移、执行迁移、回滚迁移等。
- 迁移文件由 Creator 生成，位于应用或插件的 data/migrations 目录中，或核心框架的 vendor/thinkcmf/cmf/src/data/migrations 目录中。
- Migrate 类负责解析迁移文件、构建适配器、执行迁移与回滚，并记录版本日志。

```mermaid
graph TB
A["ThinkCMF 应用<br/>composer.json"] --> B["xia/migration 包<br/>vendor/xia/migration"]
B --> C["迁移服务注册<br/>Service.php"]
C --> D["迁移命令<br/>Create/Run/Rollback"]
D --> E["Creator 迁移生成器<br/>Creator.php"]
D --> F["迁移执行引擎<br/>Migrate.php"]
F --> G["Phinx 抽象迁移基类<br/>AbstractMigration.php"]
```

图表来源
- [composer.json:67-72](file://composer.json#L67-L72)
- [vendor/xia/migration/composer.json:19-24](file://vendor/xia/migration/composer.json#L19-L24)
- [vendor/xia/migration/src/Service.php:25-50](file://vendor/xia/migration/src/Service.php#L25-L50)
- [vendor/xia/migration/src/Creator.php:20-65](file://vendor/xia/migration/src/Creator.php#L20-L65)
- [vendor/xia/migration/src/Migrate.php:22-114](file://vendor/xia/migration/src/Migrate.php#L22-L114)
- [vendor/xia/migration/phinx/src/Phinx/Migration/AbstractMigration.php](file://vendor/xia/migration/phinx/src/Phinx/Migration/AbstractMigration.php)

章节来源
- [composer.json:30-42](file://composer.json#L30-L42)
- [vendor/xia/migration/composer.json:13-18](file://vendor/xia/migration/composer.json#L13-L18)
- [vendor/xia/migration/src/Service.php:25-50](file://vendor/xia/migration/src/Service.php#L25-L50)

## 核心组件
- 迁移服务与命令注册：Service 在 boot 中绑定 Creator 并注册迁移命令，使 CLI 可用 migrate:create、migrate:run、migrate:rollback 等。
- 迁移生成器 Creator：根据应用或插件参数生成迁移文件，校验类名唯一性与模板可用性，写入目标目录。
- 迁移执行引擎 Migrate：解析迁移文件、构造数据库适配器、按版本顺序执行 up()/change() 或 down()，并记录版本日志。
- Phinx 抽象迁移基类 AbstractMigration：定义迁移类必须实现的接口与方法，支持 change() 自动推断方向与事务封装。

章节来源
- [vendor/xia/migration/src/Service.php:25-50](file://vendor/xia/migration/src/Service.php#L25-L50)
- [vendor/xia/migration/src/Creator.php:20-93](file://vendor/xia/migration/src/Creator.php#L20-L93)
- [vendor/xia/migration/src/Migrate.php:22-342](file://vendor/xia/migration/src/Migrate.php#L22-L342)
- [vendor/xia/migration/phinx/src/Phinx/Migration/AbstractMigration.php](file://vendor/xia/migration/phinx/src/Phinx/Migration/AbstractMigration.php)

## 架构总览
ThinkCMF 的迁移体系以 ThinkPHP 控制台为核心入口，xia/migration 提供迁移命令与执行逻辑，Creator 生成迁移文件，Migrate 解析并驱动执行，底层基于 Phinx 的适配器与抽象迁移基类。

```mermaid
sequenceDiagram
participant Dev as "开发者"
participant CLI as "ThinkPHP 控制台"
participant Cmd as "迁移命令"
participant Gen as "Creator 生成器"
participant Mig as "Migrate 执行引擎"
participant DB as "数据库"
Dev->>CLI : 执行 migrate : create
CLI->>Cmd : 解析参数并调用
Cmd->>Gen : 生成迁移文件
Gen-->>Dev : 输出创建结果
Dev->>CLI : 执行 migrate : run
CLI->>Cmd : 解析参数并调用
Cmd->>Mig : 构建适配器并执行
Mig->>DB : 执行 up()/change() 事务
DB-->>Mig : 返回执行结果
Mig-->>CLI : 记录版本日志
CLI-->>Dev : 输出执行进度与耗时
```

图表来源
- [vendor/xia/migration/src/command/migrate/Create.php:56-68](file://vendor/xia/migration/src/command/migrate/Create.php#L56-L68)
- [vendor/xia/migration/src/command/migrate/Run.php:57-138](file://vendor/xia/migration/src/command/migrate/Run.php#L57-L138)
- [vendor/xia/migration/src/Creator.php:20-65](file://vendor/xia/migration/src/Creator.php#L20-L65)
- [vendor/xia/migration/src/Migrate.php:141-189](file://vendor/xia/migration/src/Migrate.php#L141-L189)

## 详细组件分析

### 组件一：迁移命令与服务注册
- migrate:create：创建迁移文件，支持指定应用或插件参数，输出创建路径。
- migrate:run：执行迁移，支持目标版本或日期迁移；遍历核心、应用与插件迁移目录。
- migrate:rollback：回滚迁移，支持目标版本或日期回滚，可强制忽略断点。

```mermaid
classDiagram
class Service {
+boot()
}
class Create {
+configure()
+execute(input, output)
}
class Run {
+configure()
+execute(input, output)
}
class Rollback {
+configure()
+execute(input, output)
-rollback(version, force)
-rollbackToDateTime(dateTime, force)
}
Service --> Create : "注册命令"
Service --> Run : "注册命令"
Service --> Rollback : "注册命令"
```

图表来源
- [vendor/xia/migration/src/Service.php:25-50](file://vendor/xia/migration/src/Service.php#L25-L50)
- [vendor/xia/migration/src/command/migrate/Create.php:21-71](file://vendor/xia/migration/src/command/migrate/Create.php#L21-L71)
- [vendor/xia/migration/src/command/migrate/Run.php:24-142](file://vendor/xia/migration/src/command/migrate/Run.php#L24-L142)
- [vendor/xia/migration/src/command/migrate/Rollback.php:18-147](file://vendor/xia/migration/src/command/migrate/Rollback.php#L18-L147)

章节来源
- [vendor/xia/migration/src/Service.php:25-50](file://vendor/xia/migration/src/Service.php#L25-L50)
- [vendor/xia/migration/src/command/migrate/Create.php:27-68](file://vendor/xia/migration/src/command/migrate/Create.php#L27-L68)
- [vendor/xia/migration/src/command/migrate/Run.php:29-138](file://vendor/xia/migration/src/command/migrate/Run.php#L29-L138)
- [vendor/xia/migration/src/command/migrate/Rollback.php:23-146](file://vendor/xia/migration/src/command/migrate/Rollback.php#L23-L146)

### 组件二：迁移文件创建与模板注入
- Creator.create：确保迁移目录存在且可写，校验类名合法性与唯一性，映射文件名，读取模板并注入类名，写入文件。
- 目录策略：应用迁移位于 app/{app}/data/migrations；插件迁移位于 plugins/{plugin}/data/migrations；核心迁移位于 vendor/thinkcmf/cmf/src/data/migrations。
- 模板路径：/src/command/stubs/migrate.stub。

```mermaid
flowchart TD
Start(["开始"]) --> Ensure["确保迁移目录存在且可写"]
Ensure --> ValidateName["校验迁移类名是否合法"]
ValidateName --> Unique["校验类名是否唯一"]
Unique --> MapFile["映射类名为文件名"]
MapFile --> LoadStub["加载模板内容"]
LoadStub --> Inject["注入类名到模板"]
Inject --> Write["写入迁移文件"]
Write --> End(["结束"])
```

图表来源
- [vendor/xia/migration/src/Creator.php:20-65](file://vendor/xia/migration/src/Creator.php#L20-L65)
- [vendor/xia/migration/src/Creator.php:67-86](file://vendor/xia/migration/src/Creator.php#L67-L86)
- [vendor/xia/migration/src/Creator.php:88-91](file://vendor/xia/migration/src/Creator.php#L88-L91)

章节来源
- [vendor/xia/migration/src/Creator.php:20-93](file://vendor/xia/migration/src/Creator.php#L20-L93)

### 组件三：迁移执行与回滚流程
- Migrate.migrate：解析迁移文件，确定方向（上/下），先执行 down 再执行 up，逐个执行未记录的迁移。
- Migrate.executeMigration：设置适配器，开启事务，执行 change()/up()/down()，记录版本日志。
- Migrate.rollback：根据目标版本或日期回滚，支持断点强制忽略。

```mermaid
sequenceDiagram
participant Run as "Run 命令"
participant Mig as "Migrate"
participant Adp as "适配器"
participant Log as "版本日志"
Run->>Mig : migrate(version/date)
Mig->>Mig : 解析迁移文件与已执行版本
Mig->>Adp : 获取适配器并开启事务
alt change() 可用
Mig->>Adp : 执行 change() 或其反向
else
Mig->>Adp : 执行 up()/down()
end
Mig->>Log : 记录 migrated 时间
Adp-->>Mig : 提交事务
Mig-->>Run : 输出执行结果
```

图表来源
- [vendor/xia/migration/src/Migrate.php:291-340](file://vendor/xia/migration/src/Migrate.php#L291-L340)
- [vendor/xia/migration/src/Migrate.php:141-189](file://vendor/xia/migration/src/Migrate.php#L141-L189)
- [vendor/xia/migration/src/command/migrate/Run.php:57-85](file://vendor/xia/migration/src/command/migrate/Run.php#L57-L85)

章节来源
- [vendor/xia/migration/src/Migrate.php:141-340](file://vendor/xia/migration/src/Migrate.php#L141-L340)
- [vendor/xia/migration/src/command/migrate/Run.php:57-138](file://vendor/xia/migration/src/command/migrate/Run.php#L57-L138)
- [vendor/xia/migration/src/command/migrate/Rollback.php:49-146](file://vendor/xia/migration/src/command/migrate/Rollback.php#L49-L146)

### 组件四：迁移类编写与方法实现
- 迁移类需继承 AbstractMigration，实现 change() 或 up()/down()。
- change()：推荐使用，Phinx 自动推断方向；若实现 down()，则 change() 方向回滚将使用 down()。
- 事务：Migrate 在执行迁移时自动开启/提交事务，保证原子性。
- 版本表：默认使用 default_migration_table，应用/插件/核心分别对应不同表名。

```mermaid
classDiagram
class AbstractMigration {
+change()
+up()
+down()
}
class Migrate {
+executeMigration(migration, direction)
+migrate(version)
+rollback(version, force)
}
AbstractMigration <|-- MyMigration : "开发者实现"
Migrate --> AbstractMigration : "实例化并执行"
```

图表来源
- [vendor/xia/migration/phinx/src/Phinx/Migration/AbstractMigration.php](file://vendor/xia/migration/phinx/src/Phinx/Migration/AbstractMigration.php)
- [vendor/xia/migration/src/Migrate.php:141-189](file://vendor/xia/migration/src/Migrate.php#L141-L189)

章节来源
- [vendor/xia/migration/phinx/src/Phinx/Migration/AbstractMigration.php](file://vendor/xia/migration/phinx/src/Phinx/Migration/AbstractMigration.php)
- [vendor/xia/migration/src/Migrate.php:141-189](file://vendor/xia/migration/src/Migrate.php#L141-L189)

## 依赖分析
- ThinkCMF 通过 composer.json 引入 xia/migration，并在 autoload 中声明 PSR-4 映射，使 think\migration 与 Phinx 命名空间可用。
- xia/migration 在 extra.think.services 中声明迁移服务，Service 在 boot 中注册命令。
- 运行脚本 post-autoload-dump 中调用 migrate:run，便于安装后自动执行迁移。

```mermaid
graph TB
CMF["ThinkCMF<br/>composer.json"] --> XIA["xia/migration<br/>composer.json"]
XIA --> PSR4["PSR-4 映射<br/>think\\migration/, Phinx\\"]
CMF --> Script["post-autoload-dump<br/>migrate:run"]
XIA --> Service["Service 注册命令"]
```

图表来源
- [composer.json:30-42](file://composer.json#L30-L42)
- [composer.json:67-72](file://composer.json#L67-L72)
- [vendor/xia/migration/composer.json:13-18](file://vendor/xia/migration/composer.json#L13-L18)
- [vendor/xia/migration/composer.json:19-24](file://vendor/xia/migration/composer.json#L19-L24)
- [vendor/xia/migration/src/Service.php:25-50](file://vendor/xia/migration/src/Service.php#L25-L50)

章节来源
- [composer.json:30-42](file://composer.json#L30-L42)
- [vendor/xia/migration/composer.json:13-24](file://vendor/xia/migration/composer.json#L13-L24)
- [vendor/xia/migration/src/Service.php:25-50](file://vendor/xia/migration/src/Service.php#L25-L50)

## 性能考虑
- 事务执行：每次迁移在适配器支持事务时自动开启/提交，减少失败风险，但大量 DDL/DML 可能增加锁竞争，建议拆分迁移或批量执行时合理规划。
- 版本扫描：Migrate 通过 glob 与版本解析定位迁移文件，版本较多时注意磁盘 I/O 与文件数量。
- 适配器选择：根据数据库类型与连接参数动态选择适配器，确保字符集与前缀正确传递。
- 批量迁移：migrate:run 会遍历核心、应用与插件迁移目录，建议在生产环境分批执行并监控耗时。

## 故障排查指南
- 数据库配置错误：migrate:run 捕获异常并提示检查 ThinkCMF 是否已安装及 data/config/database.php 配置。
- 目录不可写：Creator.ensureDirectory 会在目录不存在或不可写时报错，需检查权限。
- 类名非法或重复：Creator 校验类名合法性与唯一性，需修正类名或清理冲突文件。
- 断点限制：rollback 命令在断点处会阻止进一步回滚，可通过 -f 强制忽略断点。
- 版本无效：migrate 时若目标版本不存在，会输出警告并跳过。

章节来源
- [vendor/xia/migration/src/command/migrate/Run.php:72-85](file://vendor/xia/migration/src/command/migrate/Run.php#L72-L85)
- [vendor/xia/migration/src/Creator.php:24-46](file://vendor/xia/migration/src/Creator.php#L24-L46)
- [vendor/xia/migration/src/command/migrate/Rollback.php:112-118](file://vendor/xia/migration/src/command/migrate/Rollback.php#L112-L118)
- [vendor/xia/migration/src/Migrate.php:308-311](file://vendor/xia/migration/src/Migrate.php#L308-L311)

## 结论
ThinkCMF 的数据库迁移系统以 xia/migration 为核心，结合 ThinkPHP 控制台与 Phinx，提供了完整的迁移生命周期管理。通过规范化的迁移文件生成、严谨的执行与回滚流程、完善的错误处理与断点机制，能够满足 ThinkCMF 在开发、测试与生产环境中的数据库演进需求。建议配合版本控制、备份策略与幂等设计，确保迁移安全可靠。

## 附录

### 迁移命令速查
- 创建迁移：migrate:create <类名> [-a 应用] [-p 插件]
- 执行迁移：migrate:run [-t 目标版本] [-d 日期] [-a 应用] [-p 插件]
- 回滚迁移：migrate:rollback [-t 目标版本] [-d 日期] [-f 强制]

章节来源
- [vendor/xia/migration/src/command/migrate/Create.php:30-44](file://vendor/xia/migration/src/command/migrate/Create.php#L30-L44)
- [vendor/xia/migration/src/command/migrate/Run.php:31-46](file://vendor/xia/migration/src/command/migrate/Run.php#L31-L46)
- [vendor/xia/migration/src/command/migrate/Rollback.php:25-40](file://vendor/xia/migration/src/command/migrate/Rollback.php#L25-L40)

### 迁移文件位置
- 核心迁移：vendor/thinkcmf/cmf/src/data/migrations
- 应用迁移：app/{app}/data/migrations
- 插件迁移：plugins/{plugin}/data/migrations

章节来源
- [vendor/xia/migration/src/Creator.php:67-86](file://vendor/xia/migration/src/Creator.php#L67-L86)
- [vendor/xia/migration/src/Migrate.php:127-139](file://vendor/xia/migration/src/Migrate.php#L127-L139)

### 数据库结构变更策略
- 表创建：在 change() 中使用 createTable 定义字段、索引与约束。
- 修改表：使用 alterTable 对列、索引进行变更，注意兼容性与数据完整性。
- 删除表：dropTable 前做好备份与数据导出。
- 索引管理：统一在迁移中维护索引，避免遗漏或重复。

### 数据迁移方法
- 数据导入/导出：可在迁移中使用 insert/select/update/delete，或结合外部工具进行批量数据处理。
- 数据转换：在 up() 中进行字段类型转换、编码替换、路径修正等，down() 中回退。
- 批量更新：分批次处理大数据量，避免长时间锁表。

### 最佳实践
- 版本控制：迁移文件名以时间戳开头，确保顺序稳定；每次变更提交独立分支并评审。
- 备份策略：执行迁移前对生产库做快照或逻辑备份；回滚前确认备份可用。
- 错误处理：在迁移中捕获异常并记录详细日志；必要时提供 down() 回滚路径。
- 幂等性：尽量使 up() 可重复执行而不产生副作用；对唯一约束与索引进行幂等处理。
- 分层迁移：将大变更拆分为多个小迁移，降低风险与回滚成本。

### 常见场景
- 新增模块表：创建迁移文件，定义表结构与索引，执行 migrate:run。
- 修改现有表：使用 alterTable 增删字段或索引，确保数据迁移与兼容性。
- 回滚至上一版本：migrate:rollback 或 migrate:rollback -t <版本号>。
- 按日期回滚：migrate:rollback -d <YYYYMMDD>。
- 应用/插件迁移：migrate:run -a <应用> 或 migrate:run -p <插件>。

章节来源
- [AGENTS.MD:576-598](file://AGENTS.MD#L576-L598)
- [vendor/xia/migration/src/command/migrate/Run.php:68-131](file://vendor/xia/migration/src/command/migrate/Run.php#L68-L131)
- [vendor/xia/migration/src/command/migrate/Rollback.php:50-61](file://vendor/xia/migration/src/command/migrate/Rollback.php#L50-L61)