数据库迁移
问题
Go 项目中如何管理数据库 Schema 变更?有哪些迁移工具?
答案
golang-migrate
最流行的 Go 数据库迁移工具:
# 安装
go install -tags 'mysql' github.com/golang-migrate/migrate/v4/cmd/migrate@latest
# 创建迁移
migrate create -ext sql -dir migrations -seq create_users_table
-- migrations/000001_create_users_table.up.sql
CREATE TABLE users (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(100) NOT NULL,
email VARCHAR(255) UNIQUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- migrations/000001_create_users_table.down.sql
DROP TABLE IF EXISTS users;
# 执行迁移
migrate -path migrations -database "mysql://user:pass@tcp(localhost:3306)/db" up
# 回滚
migrate -path migrations -database "..." down 1
# 查看版本
migrate -path migrations -database "..." version
在代码中嵌入迁移:
import "github.com/golang-migrate/migrate/v4"
m, err := migrate.New("file://migrations", "mysql://...")
m.Up() // 执行所有待处理迁移
Atlas(新一代)
声明式 Schema 管理:
// schema.hcl
table "users" {
schema = schema.main
column "id" { type = bigint }
column "name" { type = varchar(100) }
primary_key { columns = [column.id] }
}
atlas schema apply --url "mysql://..." --to "file://schema.hcl"
迁移最佳实践
| 实践 | 说明 |
|---|---|
| 每个迁移可逆 | up + down 成对 |
| 迁移文件不可修改 | 一旦提交不能改已有迁移 |
| CI 中自动执行 | 部署时自动 migrate up |
| 大表变更分步骤 | 先加列 → 填数据 → 改代码 → 删旧列 |
常见面试问题
Q1: GORM AutoMigrate 能用于生产吗?
答案:不推荐。AutoMigrate 只能添加字段/索引,不能删除/重命名,也无法记录版本。生产环境应使用专门的迁移工具。