1. GORM 迁移概述

1.1 什么是数据库迁移

数据库迁移(Database Migration)是指对数据库 Schema(表结构、索引、约束等)进行版本化、可追溯的变更管理。在应用开发过程中,模型定义会随业务需求不断调整,而数据库迁移正是将模型变更同步到数据库的规范化手段。

核心目标:让数据库 Schema 始终与代码中的模型定义保持一致,同时支持团队协作、回滚和审计。

迁移通常包含以下操作类型:

操作类型 说明 示例
创建表 根据模型定义新建数据库表 CREATE TABLE users (...)
新增字段 为已有表添加列 ALTER TABLE users ADD COLUMN age INT
修改字段 变更列类型、默认值或约束 ALTER TABLE users MODIFY COLUMN name VARCHAR(100)
删除字段 移除不再使用的列 ALTER TABLE users DROP COLUMN temp_field
添加索引 为查询性能创建索引 CREATE INDEX idx_email ON users(email)
删除索引 移除冗余索引 DROP INDEX idx_email ON users
提示:在生产环境中,手动执行 DDL 语句风险较高,推荐使用迁移工具(如 GORM AutoMigrate、golang-migrate、Flyway)来保证变更的可控性和可重复性。
数据库迁移流程 模型定义变更 迁移脚本生成 执行迁移 Schema 同步 说明: 迁移流程从模型变更开始,经过脚本生成、执行,最终使数据库 Schema 与模型同步。 手动 DDL 风险高 版本化可追溯 团队协作基础

1.2 GORM AutoMigrate 简介

GORM 提供了 AutoMigrate 方法,用于自动将 Go 结构体模型与数据库表结构进行同步。它会在启动时检查数据库中是否存在对应的表,并根据模型定义自动创建表、添加字段和索引。

// 基本用法
db.AutoMigrate(&User{}, &Product{}, &Order{})

// 模型定义示例
type User struct {
    ID        uint      `gorm:"primaryKey"`
    Name      string    `gorm:"size:100;not null"`
    Email     string    `gorm:"uniqueIndex;size:255"`
    Age       int       `gorm:"default:0"`
    CreatedAt time.Time
    UpdatedAt time.Time
}
注意:AutoMigrate 只会新增表和字段,不会删除已存在的字段或表。如需删除操作,需手动执行迁移脚本或使用第三方迁移工具。

AutoMigrate 的核心特性:

  • 自动建表:根据模型定义自动生成 CREATE TABLE 语句
  • 字段追加:检测到模型新增字段时,自动执行 ALTER TABLE 添加列
  • 索引管理:根据标签(如 uniqueIndex、index)自动创建索引
  • 外键约束:支持通过标签或嵌套结构自动建立外键关系
  • 表名映射:默认使用结构体名的蛇形复数形式作为表名,支持自定义
特性 支持情况 说明
创建表 ✅ 完全支持 表不存在时自动创建
新增字段 ✅ 完全支持 仅追加,不影响已有数据
修改字段 ⚠️ 部分支持 需配合 gorm:"type:..." 标签
删除字段 ❌ 不支持 需手动执行 DDL
删除表 ❌ 不支持 需手动执行 DDL
索引变更 ✅ 支持新增 不删除已有索引
GORM AutoMigrate 工作流程 Go 模型定义 AutoMigrate 调用 Schema 对比 执行变更 AutoMigrate 对比逻辑: 1. 检查数据库中是否存在对应表 2. 如果表不存在 → 执行 CREATE TABLE 3. 如果表已存在 → 对比字段列表,执行 ALTER TABLE ADD COLUMN 4. 检查索引定义,执行 CREATE INDEX(仅新增)

1.3 迁移与契约校验的关系

在微服务架构和数据密集型应用中,数据库 Schema 本身就是一种契约——它定义了数据的形状、类型和约束。迁移与契约校验的关系体现在以下三个层面:

  1. 结构契约:模型定义(Go struct)与数据库表结构之间的双向一致性校验
  2. 类型契约:Go 数据类型与数据库列类型之间的映射正确性校验
  3. 约束契约:非空、唯一、默认值、外键等约束条件的完整性校验
核心观点:迁移是契约的执行过程,校验是契约的验证过程。两者结合才能确保数据层的可靠性和可维护性。

迁移与契约校验的对比:

维度 数据库迁移 契约校验
关注点 Schema 变更的执行 Schema 一致性的验证
执行时机 应用启动 / 部署时 开发阶段 / CI 流程 / 运行时
输出 DDL 语句执行结果 校验通过 / 失败报告
风险 数据丢失、表结构冲突 模型与数据库不一致导致运行时错误
GORM 支持 AutoMigrate / Migrator 接口 需自定义校验逻辑或使用第三方库
实践建议:在 CI/CD 流程中加入契约校验步骤,确保模型定义与数据库 Schema 一致后再执行迁移,可以有效避免生产环境的结构冲突问题。