Files
martial-master/docs/DATABASE_MIGRATION.md
宅房 d583bdc5c8 feat: 集成Flyway数据库迁移工具
- 添加Flyway依赖到pom.xml
- 配置application.yml启用Flyway
- 创建迁移脚本目录db/migration
- 添加V1基线脚本和V2项目字段迁移脚本
- 添加DATABASE_MIGRATION.md使用文档
2025-12-29 14:07:27 +08:00

5.7 KiB
Raw Permalink Blame History

数据库迁移指南

本项目使用 Flyway 进行数据库版本管理和自动迁移。

概述

Flyway 是一个数据库迁移工具,它能够:

  • 自动追踪数据库版本
  • 按顺序执行迁移脚本
  • 确保团队成员的数据库结构一致
  • 支持回滚和修复

工作原理

  1. 应用启动时Flyway 自动扫描 src/main/resources/db/migration 目录
  2. 检查 flyway_schema_history 表,确定已执行的版本
  3. 按版本号顺序执行未运行的迁移脚本
  4. 记录执行结果到历史表

迁移脚本命名规范

V{版本号}__{描述}.sql

命名规则

规则 说明 示例
前缀 必须以 V 开头(大写) V1, V2, V10
版本号 数字,支持小数点 1, 2, 2.1, 10
分隔符 两个下划线 __
描述 用下划线连接单词 add_user_table
后缀 必须是 .sql .sql

正确示例

V1__baseline.sql                    # 基线版本
V2__add_project_fields.sql          # 添加项目字段
V3__create_order_table.sql          # 创建订单表
V4__add_index_to_user.sql           # 添加用户索引
V4.1__fix_user_column_type.sql      # 修复用户列类型(小版本)
V10__major_refactor.sql             # 大版本重构

错误示例

v1__init.sql          # 错误v 应该大写
V1_init.sql           # 错误:只有一个下划线
V1-init.sql           # 错误:使用了连字符
V1__init.SQL          # 错误:后缀应该小写
init.sql              # 错误:缺少版本前缀

如何添加新的迁移

步骤 1确定版本号

查看当前最新版本:

ls src/main/resources/db/migration/

新版本号 = 最新版本号 + 1

步骤 2创建迁移脚本

src/main/resources/db/migration/ 目录创建新文件:

-- =====================================================
-- 迁移脚本: [描述]
-- 版本: V{版本号}
-- 描述: [详细说明]
-- 日期: YYYY-MM-DD
-- =====================================================

-- 你的 SQL 语句
ALTER TABLE xxx ADD COLUMN yyy VARCHAR(100);

步骤 3测试迁移

本地启动应用,观察日志:

Flyway Community Edition 9.x.x
Successfully validated 3 migrations
Current version of schema: 2
Migrating schema to version 3 - create_order_table
Successfully applied 1 migration

步骤 4提交代码

git add src/main/resources/db/migration/V3__xxx.sql
git commit -m "db: 添加xxx迁移脚本"
git push

最佳实践

1. 幂等性脚本

编写可重复执行的脚本,避免重复执行报错:

-- 添加列(如果不存在)
SET @exist := (SELECT COUNT(*) FROM information_schema.columns 
               WHERE table_schema = DATABASE() 
               AND table_name = 'your_table' 
               AND column_name = 'new_column');
SET @sql := IF(@exist = 0, 
    'ALTER TABLE your_table ADD COLUMN new_column VARCHAR(100)',
    'SELECT 1');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

2. 不要修改已执行的脚本

一旦迁移脚本被执行(已提交到版本库),永远不要修改它

如果需要修复,创建新的迁移脚本:

V3__create_table.sql      # 已执行,有错误
V4__fix_v3_error.sql      # 新建脚本修复错误

3. 小步迁移

每个迁移脚本只做一件事:

  • V2__add_user_email.sql
  • V3__add_user_phone.sql
  • 不要: V2__add_user_email_and_phone_and_address.sql

4. 添加注释

-- =====================================================
-- 迁移脚本: 添加用户邮箱字段
-- 版本: V5
-- 描述: 为用户表添加邮箱字段,用于接收通知
-- 作者: 张三
-- 日期: 2024-12-29
-- 关联需求: JIRA-123
-- =====================================================

5. 备份数据

生产环境执行迁移前,务必备份数据库:

mysqldump -u root -p martial_db > backup_$(date +%Y%m%d).sql

常见问题

Q1: 迁移失败怎么办?

  1. 查看错误日志,定位问题
  2. 修复数据库中的问题(手动)
  3. 修复迁移脚本
  4. 执行 Flyway repair如需要

Q2: 如何跳过某个版本?

不建议跳过版本。如果必须跳过,可以创建空脚本:

-- V3__placeholder.sql
-- 此版本跳过
SELECT 1;

Q3: 多人开发版本冲突怎么办?

使用日期时间作为版本号前缀:

V20241229001__add_field.sql
V20241229002__fix_bug.sql

Q4: 如何查看迁移历史?

SELECT * FROM flyway_schema_history ORDER BY installed_rank;

目录结构

src/main/resources/
└── db/
    └── migration/
        ├── V1__baseline.sql              # 基线版本
        ├── V2__add_project_fields.sql    # 添加项目字段
        └── V3__xxx.sql                   # 后续迁移...

配置说明

application.yml 中的 Flyway 配置:

spring:
  flyway:
    enabled: true                          # 启用 Flyway
    locations: classpath:db/migration      # 迁移脚本位置
    table: flyway_schema_history           # 版本历史表名
    baseline-version: 0                    # 基线版本号
    baseline-on-migrate: true              # 自动执行基线
    validate-on-migrate: true              # 校验迁移脚本
    encoding: UTF-8                        # 脚本编码
    out-of-order: false                    # 禁止乱序执行
    clean-disabled: true                   # 禁用清理(生产安全)

参考资料