# 数据库操作语法

<cite>
**本文引用的文件**
- [Migrator.php](file://vendor/xia/migration/src/Migrator.php)
- [Table.php](file://vendor/xia/migration/src/db/Table.php)
- [Column.php](file://vendor/xia/migration/src/db/Column.php)
- [20230320162718_migration_cmf_role_type.php](file://vendor/thinkcmf/cmf/src/data/migrations/20230320162718_migration_cmf_role_type.php)
- [20230322153218_migration_cmf_admin_api.php](file://vendor/thinkcmf/cmf/src/data/migrations/20230322153218_migration_cmf_admin_api.php)
- [AbstractMigration.php](file://vendor/xia/migration/phinx/src/Phinx/Migration/AbstractMigration.php)
- [Manager.php](file://vendor/xia/migration/phinx/src/Phinx/Migration/Manager.php)
- [Migrate.php](file://vendor/xia/migration/src/command/Migrate.php)
</cite>

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

## 简介
本文件系统性梳理 ThinkCMF 在数据库迁移中可使用的操作语法，覆盖表操作、字段（列）定义、索引创建与约束设置，并结合项目中已有的迁移示例进行说明。ThinkCMF 基于 xia/migration（Phinx）实现迁移能力，迁移文件通过统一入口执行，支持可逆迁移与多种数据库适配。

## 项目结构
- 迁移框架来源：think\migration 命名空间映射到 vendor/xia/migration，其内部继承并扩展了 Phinx 的迁移能力。
- 核心入口：应用在安装或部署时自动运行迁移命令，确保数据库结构与迁移脚本保持一致。
- 示例迁移：项目内置多条迁移示例，演示如何添加表、列、索引以及设置表注释等。

```mermaid
graph TB
A["应用启动<br/>执行迁移命令"] --> B["迁移管理器<br/>think\\migration\\src\\command\\Migrate.php"]
B --> C["迁移执行器<br/>vendor/xia/migration/phinx/src/Phinx/Migration/Manager.php"]
C --> D["抽象迁移基类<br/>vendor/xia/migration/phinx/src/Phinx/Migration/AbstractMigration.php"]
D --> E["业务迁移类<br/>vendor/thinkcmf/cmf/src/data/migrations/*.php"]
E --> F["表操作封装<br/>think\\migration\\db\\Table"]
F --> G["列定义封装<br/>think\\migration\\db\\Column"]
```

图表来源
- [Migrate.php](file://vendor/xia/migration/src/command/Migrate.php#L136)
- [Manager.php](file://vendor/xia/migration/phinx/src/Phinx/Migration/Manager.php#L771)
- [AbstractMigration.php](file://vendor/xia/migration/phinx/src/Phinx/Migration/AbstractMigration.php#L26)
- [20230322153218_migration_cmf_admin_api.php:29-72](file://vendor/thinkcmf/cmf/src/data/migrations/20230322153218_migration_cmf_admin_api.php#L29-L72)

章节来源
- [Migrate.php](file://vendor/xia/migration/src/command/Migrate.php#L136)
- [Manager.php](file://vendor/xia/migration/phinx/src/Phinx/Migration/Manager.php#L771)
- [AbstractMigration.php](file://vendor/xia/migration/phinx/src/Phinx/Migration/AbstractMigration.php#L26)

## 核心组件
- think\migration\Migrator：迁移入口类，提供 table() 方法获取表操作对象。
- think\migration\db\Table：表级操作封装，支持设置引擎、注释、主键、软删除、morphs 辅助列、时间戳列等；重写 addColumn 可自动为唯一列创建唯一索引。
- think\migration\db\Column：列级定义封装，提供常用数据类型工厂方法（字符串、整型、日期时间、JSON 等），并支持可空、无符号、唯一等属性设置。

章节来源
- [Migrator.php:23-26](file://vendor/xia/migration/src/Migrator.php#L23-L26)
- [Table.php:16-136](file://vendor/xia/migration/src/db/Table.php#L16-L136)
- [Column.php:17-171](file://vendor/xia/migration/src/db/Column.php#L17-L171)

## 架构总览
下图展示迁移执行链路与核心类之间的关系：

```mermaid
classDiagram
class AbstractMigration {
<<phinx>>
}
class Migrator {
+table(tableName, options) Table
}
class Table {
+setEngine(engine)
+setComment(comment)
+setPrimaryKey(key)
+setId(id)
+addSoftDelete()
+addMorphs(name, indexName)
+addNullableMorphs(name, indexName)
+addTimestamps(createdAt, updatedAt, withTimezone)
+addColumn(columnName, type, options)
+changeColumn(columnName, newType, options)
}
class Column {
+setNullable()
+setUnsigned()
+setUnique()
+getUnique()
+isUnique()
+string(name, length)
+integer(name, length)
+tinyInteger(name)
+mediumInteger(name)
+bigInteger(name)
+decimal(name, precision, scale)
+float(name)
+boolean(name)
+date(name)
+dateTime(name)
+time(name)
+timestamp(name)
+json(name)
+jsonb(name)
+uuid(name)
+text(name)
+longText(name)
+mediumText(name)
+binary(name)
+enum(name, values)
}
Migrator --|> AbstractMigration
Migrator --> Table : "创建"
Table --> Column : "使用"
```

图表来源
- [AbstractMigration.php](file://vendor/xia/migration/phinx/src/Phinx/Migration/AbstractMigration.php#L26)
- [Migrator.php:16-27](file://vendor/xia/migration/src/Migrator.php#L16-L27)
- [Table.php:16-136](file://vendor/xia/migration/src/db/Table.php#L16-L136)
- [Column.php:17-171](file://vendor/xia/migration/src/db/Column.php#L17-L171)

## 详细组件分析

### 表操作
- 获取表对象：在迁移的 change() 中通过 $this->table('表名', ['comment' => '注释', ...]) 获取表操作对象。
- 常用设置：
  - 引擎：setEngine('InnoDB' 等)
  - 排序规则：setCollation('utf8mb4_general_ci' 等)
  - 注释：setComment('表说明')
  - 主键：setPrimaryKey('id' 或复合主键数组)
  - 自增标识：setId(true/false)
- 时间戳辅助：addTimestamps('create_time','update_time', false) 自动添加创建与更新时间列。
- 软删除：addSoftDelete() 添加 delete_time 时间戳列。
- 多态关联辅助：addMorphs('taggable') 创建 morphs 列并建立复合索引；addNullableMorphs(...) 允许为空。
- 列操作：addColumn()/changeColumn() 完成列的新增与变更。

章节来源
- [Migrator.php:23-26](file://vendor/xia/migration/src/Migrator.php#L23-L26)
- [Table.php:24-78](file://vendor/xia/migration/src/db/Table.php#L24-L78)
- [Table.php:101-104](file://vendor/xia/migration/src/db/Table.php#L101-L104)
- [Table.php:74-78](file://vendor/xia/migration/src/db/Table.php#L74-L78)
- [Table.php:80-94](file://vendor/xia/migration/src/db/Table.php#L80-L94)

### 字段（列）定义
- 数据类型工厂方法：
  - 字符串：string(name, length)
  - 整数系列：integer/tinyInteger/mediumInteger/bigInteger(unsignedInteger)
  - 浮点与精度：float/decimal(name, precision, scale)
  - 布尔：boolean
  - 日期时间：date/dateTime/time/timestamp
  - 文本：text/mediumText/longText
  - JSON：json/jsonb
  - UUID：uuid
  - 二进制：binary
  - 枚举：enum(name, [values])
- 属性设置：
  - 可空：setNullable()
  - 无符号：setUnsigned()
  - 唯一：setUnique()（配合 addColumn 会自动创建唯一索引）
- 选项参数（传入 addColumn 的第三个参数）：
  - default：默认值
  - null：是否允许为空
  - limit：长度限制（如字符串长度、整型宽度）
  - comment：列注释
  - after：指定列在某列之后插入

章节来源
- [Column.php:47-54](file://vendor/xia/migration/src/db/Column.php#L47-L54)
- [Column.php:56-169](file://vendor/xia/migration/src/db/Column.php#L56-L169)
- [Column.php:21-29](file://vendor/xia/migration/src/db/Column.php#L21-L29)
- [Table.php:112-121](file://vendor/xia/migration/src/db/Table.php#L112-L121)
- [20230320162718_migration_cmf_role_type.php:31-38](file://vendor/thinkcmf/cmf/src/data/migrations/20230320162718_migration_cmf_role_type.php#L31-L38)

### 索引操作
- 普通索引：addIndex('列名') 或 addIndex(['col1','col2'], ['name' => '索引名'])
- 唯一索引：addColumn() 时使用 setUnique()，底层会自动创建唯一索引
- 主键：setPrimaryKey('id') 或复合主键数组
- 复合索引：addIndex(['a','b'], ['name' => 'idx_ab'])

章节来源
- [Table.php:112-121](file://vendor/xia/migration/src/db/Table.php#L112-L121)
- [20230322153218_migration_cmf_admin_api.php:68-70](file://vendor/thinkcmf/cmf/src/data/migrations/20230322153218_migration_cmf_admin_api.php#L68-L70)

### 约束设置
- 唯一约束：通过 Column::setUnique() 实现，底层自动创建唯一索引。
- 外键约束：Phinx 原生支持 addForeignKey()，可在迁移中显式定义外键关系。
- 检查约束：Phinx 支持 addCheck()，可用于表达更复杂的约束条件。

章节来源
- [Table.php:112-121](file://vendor/xia/migration/src/db/Table.php#L112-L121)
- [AbstractMigration.php](file://vendor/xia/migration/phinx/src/Phinx/Migration/AbstractMigration.php#L26)

### 实际使用示例
- 为现有表添加新列并设置默认值、非空、注释与位置：
  - 参考路径：[20230320162718_migration_cmf_role_type.php:28-39](file://vendor/thinkcmf/cmf/src/data/migrations/20230320162718_migration_cmf_role_type.php#L28-L39)
- 创建新表并批量添加列、索引与表注释：
  - 参考路径：[20230322153218_migration_cmf_admin_api.php:29-72](file://vendor/thinkcmf/cmf/src/data/migrations/20230322153218_migration_cmf_admin_api.php#L29-L72)

## 依赖关系分析
- think\migration\Migrator 继承自 Phinx 的 AbstractMigration，并通过 table() 返回 think\migration\db\Table 实例。
- think\migration\db\Table 继承自 Phinx 的 Table，扩展了更多便捷方法（如 addTimestamps、addSoftDelete、addMorphs 等）。
- think\migration\db\Column 继承自 Phinx 的 Column，提供丰富的类型工厂方法与属性设置。

```mermaid
graph LR
A["think\\migration\\Migrator"] --> B["think\\migration\\db\\Table"]
B --> C["think\\migration\\db\\Column"]
A --> D["phinx\\Migration\\AbstractMigration"]
B --> D
```

图表来源
- [Migrator.php:16-27](file://vendor/xia/migration/src/Migrator.php#L16-L27)
- [Table.php:16-17](file://vendor/xia/migration/src/db/Table.php#L16-L17)
- [Column.php:17-18](file://vendor/xia/migration/src/db/Column.php#L17-L18)
- [AbstractMigration.php](file://vendor/xia/migration/phinx/src/Phinx/Migration/AbstractMigration.php#L26)

章节来源
- [Migrator.php:16-27](file://vendor/xia/migration/src/Migrator.php#L16-L27)
- [Table.php:16-17](file://vendor/xia/migration/src/db/Table.php#L16-L17)
- [Column.php:17-18](file://vendor/xia/migration/src/db/Column.php#L17-L18)

## 性能考量
- 批量列变更：尽量合并多次 addColumn/changeColumn 操作，减少往返次数。
- 索引数量控制：避免在同一张表上创建过多索引，平衡查询与写入性能。
- 大字段处理：长文本、JSON 等大字段应谨慎使用，必要时拆表或延迟加载。
- 唯一索引：仅在确有业务需求时启用唯一约束，避免影响写入性能。

## 故障排查指南
- 迁移类必须继承抽象基类：若迁移类未正确继承基类，执行时会抛出异常提示类必须继承特定基类。
  - 参考路径：[Manager.php](file://vendor/xia/migration/phinx/src/Phinx/Migration/Manager.php#L771)
  - 参考路径：[Migrate.php](file://vendor/xia/migration/src/command/Migrate.php#L136)
- 迁移执行失败：检查迁移文件命名、类名与基类继承是否符合规范；确认数据库连接配置正确。
- 回滚问题：确保迁移逻辑可逆（使用 change() 模式），避免在 up() 中执行不可逆操作。

章节来源
- [Manager.php](file://vendor/xia/migration/phinx/src/Phinx/Migration/Manager.php#L771)
- [Migrate.php](file://vendor/xia/migration/src/command/Migrate.php#L136)

## 结论
ThinkCMF 的迁移体系基于 xia/migration（Phinx），提供了简洁易用的表、列、索引与约束操作接口。通过统一的 Migrator、Table 与 Column 封装，开发者可以快速完成数据库结构演进，并借助示例迁移文件掌握常见场景的写法。建议在团队内统一迁移编写规范，确保可读性与可维护性。

## 附录：完整语法参考

- 表级操作
  - 获取表对象：table('表名', ['comment' => '注释', 'id' => true/false, 'primary_key' => 'id' 或数组])
  - 设置引擎：setEngine('InnoDB' 等)
  - 设置排序规则：setCollation('utf8mb4_general_ci' 等)
  - 设置注释：setComment('表说明')
  - 设置主键：setPrimaryKey('id' 或 ['a','b'])
  - 时间戳列：addTimestamps('create_time','update_time', false)
  - 软删除列：addSoftDelete()
  - 多态列：addMorphs('taggable', '索引名'), addNullableMorphs(...)
  - 新增列：addColumn($columnOrName, $type, ['default' => ..., 'null' => true/false, 'limit' => N, 'comment' => '', 'after' => '...'])
  - 修改列：changeColumn($columnOrName, $newType, ['...'])

- 列级定义（常用类型工厂）
  - string(name, length)
  - integer(name, length)
  - tinyInteger(name)
  - mediumInteger(name)
  - bigInteger(name)
  - decimal(name, precision, scale)
  - float(name)
  - boolean(name)
  - date(name), dateTime(name), time(name), timestamp(name)
  - text(name), mediumText(name), longText(name)
  - json(name), jsonb(name)
  - uuid(name)
  - binary(name)
  - enum(name, [values])

- 列属性设置
  - setNullable()
  - setUnsigned()
  - setUnique()

- 索引与约束
  - 普通索引：addIndex('col'), addIndex(['a','b'], ['name' => '索引名'])
  - 唯一索引：addColumn(...)->setUnique()（自动创建唯一索引）
  - 主键：setPrimaryKey('id' 或 ['a','b'])
  - 外键：addForeignKey(...)
  - 检查约束：addCheck(...)

- 示例参考
  - 为现有表添加列：[20230320162718_migration_cmf_role_type.php:28-39](file://vendor/thinkcmf/cmf/src/data/migrations/20230320162718_migration_cmf_role_type.php#L28-L39)
  - 创建新表并添加多列与索引：[20230322153218_migration_cmf_admin_api.php:29-72](file://vendor/thinkcmf/cmf/src/data/migrations/20230322153218_migration_cmf_admin_api.php#L29-L72)