1. GORM 迁移概述

1.1 什么是数据库迁移

数据库迁移(Migration)是指对数据库 Schema(表结构、索引、约束等)进行版本化、可追溯的变更管理过程。在 Go 生态中,GORM 提供了轻量级的迁移能力,允许开发者通过 Go 结构体定义数据模型,并自动同步到数据库。

核心目标:让数据库 Schema 与应用程序中的模型定义始终保持一致,避免手动执行 DDL 语句带来的版本混乱和人为失误。
对比维度 手动 DDL 迁移 GORM AutoMigrate
执行方式 人工编写 SQL 脚本,手动执行 程序启动时自动检测并同步
版本控制 依赖外部工具或脚本命名 无内置版本号,仅做增量同步
回滚能力 需手动编写回滚脚本 不支持自动回滚
适用场景 生产环境严格变更控制 开发/测试环境快速迭代

1.2 GORM AutoMigrate 原理

AutoMigrate 是 GORM 提供的一个自动迁移方法,其核心逻辑是:读取 Go 结构体定义 → 对比数据库中现有表结构 → 生成并执行增量 DDL 语句。它不会删除未定义的列或表,仅做“添加”和“修改”操作。

// 典型用法
type User struct {
  gorm.Model
  Name  string `gorm:"type:varchar(100);not null"`
  Email string `gorm:"uniqueIndex"`
  Age   int    `gorm:"default:18"`
}

// 执行迁移
db.AutoMigrate(&User{})
执行流程:AutoMigrate 会依次检查:表是否存在 → 列是否存在 → 列类型是否匹配 → 索引是否存在 → 外键是否存在。对于不匹配的列,GORM 会尝试修改列类型;对于缺失的索引和约束,会新建。
GORM AutoMigrate 执行流程 Go 结构体定义 解析字段标签、类型、约束 对比数据库现有表结构 是否存在差异? 跳过,无需变更 执行增量 DDL 无差异 有差异

1.3 迁移与 Schema 同步的关系

数据库迁移和 Schema 同步是同一枚硬币的两面:

  • 迁移(Migration):强调过程——从旧 Schema 到新 Schema 的变更动作,包含版本记录、回滚策略等。
  • Schema 同步(Schema Sync):强调状态——确保数据库当前 Schema 与模型定义完全一致,不关心中间变更历史。

GORM 的 AutoMigrate 更偏向 Schema 同步 而非传统迁移。它不记录版本号,也不提供回滚能力,而是每次启动时“对齐”当前状态。这种设计在开发阶段非常高效,但在生产环境中需要配合更严谨的迁移工具使用。

生产环境注意事项:AutoMigrate 不会删除列或表,但会修改列类型。在生产数据库上,修改列类型可能导致数据截断或锁表。建议在生产环境使用版本化迁移工具(如 golang-migrate),仅在开发/测试环境使用 AutoMigrate。
特性 传统迁移工具 GORM AutoMigrate
版本号管理 ✅ 有(up/down 脚本) ❌ 无
回滚支持 ✅ 支持 ❌ 不支持
删除列/表 ✅ 支持 ❌ 不支持
增量同步 手动编写 自动检测
适用阶段 生产环境 开发/测试环境

1.4 迁移的边界与冒烟领域

在《GORM 数据库迁移与冒烟边界领域实战》课程中,我们将“迁移”的边界定义为:

  1. 正向迁移:从模型定义到数据库 Schema 的自动或手动同步。
  2. 逆向迁移:从数据库 Schema 反向生成模型定义(如 GORM 的 db.Migrator().CurrentDatabase() 等内省方法)。
  3. 冒烟测试边界:在迁移执行后,快速验证表结构、索引、约束是否与预期一致,确保迁移不会破坏现有数据完整性。
迁移边界与冒烟领域 正向迁移 模型 → 数据库 逆向迁移 数据库 → 模型 冒烟测试边界 验证表结构、索引、约束一致性 开发阶段 生产阶段

通过明确迁移的边界,我们可以在不同阶段选择合适的策略:开发阶段使用 AutoMigrate 快速迭代,生产阶段使用版本化迁移工具,并在每次迁移后执行冒烟测试,确保数据库 Schema 的完整性和一致性。