# 迁移文件基本结构

<cite>
**本文引用的文件**
- [vendor/xia/migration/phinx/src/Phinx/Migration/AbstractMigration.php](file://vendor/xia/migration/phinx/src/Phinx/Migration/AbstractMigration.php)
- [vendor/xia/migration/src/Migrator.php](file://vendor/xia/migration/src/Migrator.php)
- [vendor/xia/migration/phinx/src/Phinx/Migration/MigrationInterface.php](file://vendor/xia/migration/phinx/src/Phinx/Migration/MigrationInterface.php)
- [vendor/xia/migration/phinx/src/Phinx/Config/Config.php](file://vendor/xia/migration/phinx/src/Phinx/Config/Config.php)
- [vendor/xia/migration/phinx/src/Phinx/Console/Command/Create.php](file://vendor/xia/migration/phinx/src/Phinx/Console/Command/Create.php)
- [vendor/xia/migration/src/Creator.php](file://vendor/xia/migration/src/Creator.php)
- [vendor/xia/migration/src/command/stubs/migrate.stub](file://vendor/xia/migration/src/command/stubs/migrate.stub)
- [vendor/xia/migration/phinx/src/Phinx/Util/Util.php](file://vendor/xia/migration/phinx/src/Phinx/Util/Util.php)
- [vendor/thinkcmf/cmf/src/data/migrations/20230320162718_migration_cmf_role_type.php](file://vendor/thinkcmf/cmf/src/data/migrations/20230320162718_migration_cmf_role_type.php)
- [AGENTS.MD](file://AGENTS.MD)
- [composer.lock](file://composer.lock)
</cite>

## 目录
1. [引言](#引言)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖分析](#依赖分析)
7. [性能考虑](#性能考虑)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录：迁移文件模板与示例](#附录迁移文件模板与示例)

## 引言
本文件面向 ThinkCMF 的数据库迁移开发，系统性说明迁移文件的命名规范、文件组织方式、迁移类的继承关系与基础结构，并给出版本号与时间戳规范及执行顺序保障机制。同时提供标准迁移文件模板与完整示例路径，帮助开发者快速上手编写可维护、可回滚的迁移文件。

## 项目结构
ThinkCMF 使用 xia/migration 库（基于 Phinx）进行数据库迁移管理。迁移文件由 ThinkPHP 控制台命令生成并执行，遵循 Phinx 的迁移命名与版本控制策略。

- 迁移文件位置
  - ThinkCMF 核心迁移位于 vendor/thinkcmf/cmf/src/data/migrations
  - 应用迁移位于应用目录下的 data/migrations
  - 插件迁移位于插件目录下的 data/migrations
- 迁移命令
  - 创建迁移：php think migrate:create
  - 执行迁移：php think migrate:run
  - 回滚迁移：php think migrate:rollback

```mermaid
graph TB
subgraph "ThinkCMF 应用"
CLI["ThinkPHP 控制台<br/>命令入口"]
CFG["Phinx 配置<br/>Config"]
MAN["迁移管理器<br/>Manager"]
ADP["适配器接口<br/>AdapterInterface"]
end
subgraph "迁移文件"
CORE["核心迁移<br/>vendor/thinkcmf/cmf/src/data/migrations/*"]
APP["应用迁移<br/>app/*/data/migrations/*"]
PLG["插件迁移<br/>plugins/*/data/migrations/*"]
end
CLI --> CFG
CFG --> MAN
MAN --> ADP
ADP --> CORE
ADP --> APP
ADP --> PLG
```

**图表来源**
- [vendor/xia/migration/phinx/src/Phinx/Config/Config.php:266-277](file://vendor/xia/migration/phinx/src/Phinx/Config/Config.php#L266-L277)
- [vendor/xia/migration/phinx/src/Phinx/Console/Command/Create.php:139-144](file://vendor/xia/migration/phinx/src/Phinx/Console/Command/Create.php#L139-L144)
- [vendor/xia/migration/src/Creator.php:67-86](file://vendor/xia/migration/src/Creator.php#L67-L86)

**章节来源**
- [AGENTS.MD:576-599](file://AGENTS.MD#L576-L599)
- [composer.lock:1121-1151](file://composer.lock#L1121-L1151)

## 核心组件
- 抽象迁移基类 AbstractMigration
  - 提供数据库适配器、输入输出、版本号、方向控制、SQL 执行、表对象创建等能力
- 迁移适配器接口 MigrationInterface
  - 定义迁移生命周期方法与能力契约
- ThinkCMF 迁移基类 Migrator
  - 继承 AbstractMigration 并重写 table 方法，返回 ThinkPHP 风格的 Table 对象
- 迁移创建器 Creator
  - 负责根据应用或插件上下文生成迁移文件，自动选择目录与命名空间
- 迁移模板 migrate.stub
  - 提供迁移骨架，包含 use 语句、类定义与 change 方法占位
- 命名工具 Util
  - 提供时间戳生成、文件名与类名映射、唯一性校验等

**章节来源**
- [vendor/xia/migration/phinx/src/Phinx/Migration/AbstractMigration.php:27-331](file://vendor/xia/migration/phinx/src/Phinx/Migration/AbstractMigration.php#L27-L331)
- [vendor/xia/migration/phinx/src/Phinx/Migration/MigrationInterface.php:19-244](file://vendor/xia/migration/phinx/src/Phinx/Migration/MigrationInterface.php#L19-L244)
- [vendor/xia/migration/src/Migrator.php:16-27](file://vendor/xia/migration/src/Migrator.php#L16-L27)
- [vendor/xia/migration/src/Creator.php:20-65](file://vendor/xia/migration/src/Creator.php#L20-L65)
- [vendor/xia/migration/src/command/stubs/migrate.stub:1-32](file://vendor/xia/migration/src/command/stubs/migrate.stub#L1-L32)
- [vendor/xia/migration/phinx/src/Phinx/Util/Util.php:48-134](file://vendor/xia/migration/phinx/src/Phinx/Util/Util.php#L48-L134)

## 架构总览
迁移从命令行触发，通过配置定位迁移目录，利用 Creator 生成迁移文件，最终由 Manager 加载并按版本顺序执行。

```mermaid
sequenceDiagram
participant Dev as "开发者"
participant CLI as "ThinkPHP 控制台"
participant CFG as "Phinx 配置(Config)"
participant CREAT as "迁移创建器(Creator)"
participant FS as "文件系统"
participant MAN as "迁移管理器(Manager)"
participant ADP as "数据库适配器"
Dev->>CLI : 执行 migrate : create
CLI->>CFG : 读取迁移路径与模板
CLI->>CREAT : 传入类名与上下文(app/plugin/cmfx)
CREAT->>FS : 写入迁移文件到对应目录
Dev->>CLI : 执行 migrate : run
CLI->>MAN : 加载迁移文件并解析版本
MAN->>ADP : 逐个执行 up/down
ADP-->>MAN : 返回执行结果
MAN-->>CLI : 输出执行日志
CLI-->>Dev : 显示执行状态
```

**图表来源**
- [vendor/xia/migration/phinx/src/Phinx/Console/Command/Create.php:139-313](file://vendor/xia/migration/phinx/src/Phinx/Console/Command/Create.php#L139-L313)
- [vendor/xia/migration/src/Creator.php:20-65](file://vendor/xia/migration/src/Creator.php#L20-L65)
- [vendor/xia/migration/phinx/src/Phinx/Config/Config.php:266-277](file://vendor/xia/migration/phinx/src/Phinx/Config/Config.php#L266-L277)

## 详细组件分析

### 命名规范与文件组织
- 文件命名
  - 采用“时间戳_描述.php”的模式，时间戳精确到秒，保证自然排序即版本顺序
  - 类名采用驼峰命名（CamelCase），去除下划线后首字母大写
- 版本号与时间戳
  - 时间戳由 Util.getCurrentTimestamp 生成，格式为 14 位数字
  - 文件名前缀即版本号；若无描述部分则为 V+14 位时间戳
- 目录组织
  - ThinkCMF 核心迁移：vendor/thinkcmf/cmf/src/data/migrations
  - 应用迁移：app/{app}/data/migrations
  - 插件迁移：plugins/{plugin}/data/migrations
- 命令行生成
  - migrate:create 会根据当前时间戳生成文件名，并将类名映射到文件名

```mermaid
flowchart TD
Start(["开始"]) --> GenTS["生成时间戳(UTC)<br/>YYYYMMDDHHmmSS"]
GenTS --> MapName["类名转文件名<br/>驼峰->蛇形+前缀"]
MapName --> Validate["校验唯一性<br/>同名类检查"]
Validate --> |通过| Write["写入迁移文件"]
Validate --> |不通过| Error["抛出异常/提示"]
Write --> End(["结束"])
Error --> End
```

**图表来源**
- [vendor/xia/migration/phinx/src/Phinx/Util/Util.php:48-134](file://vendor/xia/migration/phinx/src/Phinx/Util/Util.php#L48-L134)
- [vendor/xia/migration/phinx/src/Phinx/Console/Command/Create.php:164-177](file://vendor/xia/migration/phinx/src/Phinx/Console/Command/Create.php#L164-L177)
- [vendor/xia/migration/src/Creator.php:40-46](file://vendor/xia/migration/src/Creator.php#L40-L46)

**章节来源**
- [vendor/xia/migration/phinx/src/Phinx/Util/Util.php:88-134](file://vendor/xia/migration/phinx/src/Phinx/Util/Util.php#L88-L134)
- [vendor/xia/migration/phinx/src/Phinx/Console/Command/Create.php:164-177](file://vendor/xia/migration/phinx/src/Phinx/Console/Command/Create.php#L164-L177)
- [vendor/xia/migration/src/Creator.php:67-86](file://vendor/xia/migration/src/Creator.php#L67-L86)

### 迁移类继承关系与基础结构
- 继承链
  - Migrator 继承 AbstractMigration
  - AbstractMigration 实现 MigrationInterface
- 基础结构
  - use 语句引入 think\migration\Migrator
  - 类继承 Migrator
  - change() 方法内使用 $this->table() 定义表结构变更
- 可选方法
  - up()/down() 与 change() 二选一；若同时存在，优先使用 change()

```mermaid
classDiagram
class MigrationInterface {
+setAdapter(adapter)
+getAdapter()
+setInput(input)
+getInput()
+setOutput(output)
+getOutput()
+getName()
+getEnvironment()
+setVersion(version)
+getVersion()
+setMigratingUp(flag)
+isMigratingUp()
+execute(sql)
+query(sql)
+getQueryBuilder()
+fetchRow(sql)
+fetchAll(sql)
+insert(table,data)
+createDatabase(name,options)
+dropDatabase(name)
+hasTable(tableName)
+table(tableName,options)
+preFlightCheck(direction)
+postFlightCheck(direction)
}
class AbstractMigration {
-environment
-version
-adapter
-input
-output
-isMigratingUp
-tables
+__construct(env,version,input,output)
+setAdapter(...)
+getAdapter()
+setInput(...)
+getInput()
+setOutput(...)
+getOutput()
+getName()
+getEnvironment()
+setVersion(...)
+getVersion()
+setMigratingUp(...)
+isMigratingUp()
+execute(sql)
+query(sql)
+getQueryBuilder()
+fetchRow(sql)
+fetchAll(sql)
+insert(table,data)
+createDatabase(name,options)
+dropDatabase(name)
+hasTable(tableName)
+table(tableName,options)
+preFlightCheck(direction)
+postFlightCheck(direction)
}
class Migrator {
+table(tableName,options)
}
MigrationInterface <|.. AbstractMigration
AbstractMigration <|-- Migrator
```

**图表来源**
- [vendor/xia/migration/phinx/src/Phinx/Migration/MigrationInterface.php:19-244](file://vendor/xia/migration/phinx/src/Phinx/Migration/MigrationInterface.php#L19-L244)
- [vendor/xia/migration/phinx/src/Phinx/Migration/AbstractMigration.php:27-331](file://vendor/xia/migration/phinx/src/Phinx/Migration/AbstractMigration.php#L27-L331)
- [vendor/xia/migration/src/Migrator.php:16-27](file://vendor/xia/migration/src/Migrator.php#L16-L27)

**章节来源**
- [vendor/xia/migration/src/Migrator.php:16-27](file://vendor/xia/migration/src/Migrator.php#L16-L27)
- [vendor/xia/migration/phinx/src/Phinx/Migration/AbstractMigration.php:27-331](file://vendor/xia/migration/phinx/src/Phinx/Migration/AbstractMigration.php#L27-L331)
- [vendor/xia/migration/phinx/src/Phinx/Migration/MigrationInterface.php:19-244](file://vendor/xia/migration/phinx/src/Phinx/Migration/MigrationInterface.php#L19-L244)

### 迁移文件基本组成
- 命名空间与 use 语句
  - 使用 think\migration\Migrator
- 类定义
  - 继承 Migrator
  - 类名符合驼峰命名
- change() 方法
  - 使用 $this->table('表名')->addColumn()/renameTable()/addIndex() 等
  - 注意：使用 create()/update() 而非 save()
- 注释与文档链接
  - 模板中包含迁移编写参考链接与常用命令说明

**章节来源**
- [vendor/xia/migration/src/command/stubs/migrate.stub:1-32](file://vendor/xia/migration/src/command/stubs/migrate.stub#L1-L32)
- [vendor/thinkcmf/cmf/src/data/migrations/20230320162718_migration_cmf_role_type.php:1-41](file://vendor/thinkcmf/cmf/src/data/migrations/20230320162718_migration_cmf_role_type.php#L1-L41)

### 版本号格式与时间戳规范
- 版本号即文件名前缀的时间戳，14 位数字
- 文件名模式
  - 带描述：YYYYMMDDHHmmSS_描述.php
  - 无描述：YYYYMMDDHHmmSS.php（内部映射为 V+时间戳）
- 类名模式
  - 驼峰命名，去除下划线后首字母大写
- 唯一性与合法性
  - 类名需满足驼峰格式且全局唯一
  - 文件名需匹配合法模式

**章节来源**
- [vendor/xia/migration/phinx/src/Phinx/Util/Util.php:21-42](file://vendor/xia/migration/phinx/src/Phinx/Util/Util.php#L21-L42)
- [vendor/xia/migration/phinx/src/Phinx/Util/Util.php:88-134](file://vendor/xia/migration/phinx/src/Phinx/Util/Util.php#L88-L134)
- [vendor/xia/migration/phinx/src/Phinx/Console/Command/Create.php:168-177](file://vendor/xia/migration/phinx/src/Phinx/Console/Command/Create.php#L168-L177)

### 执行顺序与版本控制
- 顺序依据
  - 以文件名前缀（时间戳）升序执行，时间越新越靠后
- 配置项
  - version_order 支持 creation（默认，按创建时间）与 execution（按执行时间）
- 基类配置
  - migration_base_class 默认为 Phinx\Migration\AbstractMigration，可通过配置覆盖

**章节来源**
- [vendor/xia/migration/phinx/src/Phinx/Config/Config.php:379-386](file://vendor/xia/migration/phinx/src/Phinx/Config/Config.php#L379-L386)
- [vendor/xia/migration/phinx/src/Phinx/Config/Config.php:285-290](file://vendor/xia/migration/phinx/src/Phinx/Config/Config.php#L285-L290)

## 依赖分析
- 外部依赖
  - xia/migration ^6.0：提供迁移命令、模板、管理器与适配器
  - topthink/framework：ThinkPHP 框架，提供控制台与容器
- 内部依赖
  - think\migration\Migrator 依赖 Phinx 的 AbstractMigration 与 Table
  - Creator 根据上下文决定迁移文件存放位置

```mermaid
graph LR
XIA["xia/migration ^6.0"] --> THK["topthink/framework"]
XIA --> PHX["phinx 核心"]
THK --> CLI["think 控制台"]
CLI --> XIA
XIA --> CMF["thinkcmf/cmf 核心迁移"]
```

**图表来源**
- [composer.lock:1121-1151](file://composer.lock#L1121-L1151)
- [AGENTS.MD:66-71](file://AGENTS.MD#L66-L71)

**章节来源**
- [composer.lock:1121-1151](file://composer.lock#L1121-L1151)
- [AGENTS.MD:66-71](file://AGENTS.MD#L66-L71)

## 性能考虑
- 迁移执行期间避免大量一次性写入，建议拆分为多个小迁移
- 在 change() 中尽量使用批量操作与索引优化
- 避免在迁移中执行耗时任务（如外部 API 调用）

## 故障排查指南
- “必须继承 AbstractMigration”
  - 症状：加载迁移时报错，提示类必须继承 AbstractMigration
  - 原因：迁移类未正确继承 Migrator（间接继承 AbstractMigration）
  - 处理：确认 use 语句与类继承链
- “类名无效或已存在”
  - 症状：创建迁移时报类名非法或重复
  - 原因：类名不符合驼峰格式或同名类已存在
  - 处理：修正类名或更换描述部分
- “文件已存在”
  - 症状：创建迁移时报文件已存在
  - 原因：时间戳冲突或手动修改过文件名
  - 处理：清理冲突文件或调整类名
- “迁移未按预期顺序执行”
  - 症状：迁移顺序与期望不符
  - 原因：文件名前缀时间戳错误或 version_order 配置不当
  - 处理：修正时间戳或调整配置

**章节来源**
- [vendor/xia/migration/phinx/src/Phinx/Console/Command/Create.php:168-185](file://vendor/xia/migration/phinx/src/Phinx/Console/Command/Create.php#L168-L185)
- [vendor/xia/migration/src/Creator.php:36-46](file://vendor/xia/migration/src/Creator.php#L36-L46)
- [vendor/xia/migration/phinx/src/Phinx/Config/Config.php:379-386](file://vendor/xia/migration/phinx/src/Phinx/Config/Config.php#L379-L386)

## 结论
ThinkCMF 的迁移体系基于 xia/migration（Phinx）实现，通过严格的命名规范与时间戳机制确保迁移顺序可控、可回滚。开发者只需遵循模板与命名约定，即可快速编写高质量的迁移文件，并通过统一的命令行工具完成创建、执行与回滚。

## 附录：迁移文件模板与示例
- 标准模板
  - 模板文件路径：vendor/xia/migration/src/command/stubs/migrate.stub
  - 内容要点：use think\migration\Migrator；类继承 Migrator；change() 占位
- 实际示例
  - ThinkCMF 核心迁移示例：vendor/thinkcmf/cmf/src/data/migrations/20230320162718_migration_cmf_role_type.php
- 命令参考
  - 创建迁移：php think migrate:create
  - 执行迁移：php think migrate:run
  - 回滚迁移：php think migrate:rollback

**章节来源**
- [vendor/xia/migration/src/command/stubs/migrate.stub:1-32](file://vendor/xia/migration/src/command/stubs/migrate.stub#L1-L32)
- [vendor/thinkcmf/cmf/src/data/migrations/20230320162718_migration_cmf_role_type.php:1-41](file://vendor/thinkcmf/cmf/src/data/migrations/20230320162718_migration_cmf_role_type.php#L1-L41)
- [AGENTS.MD:578-593](file://AGENTS.MD#L578-L593)