Skip to content

数据库迁移


Flyway(类比 Laravel Migrations)

Flyway 是 Java 生态中最流行的数据库迁移工具,Spring Boot 对其有开箱即用的支持。

对比

LaravelFlyway
database/migrations/src/main/resources/db/migration/
php artisan make:migration手动创建 SQL 文件
php artisan migrate应用启动时自动执行
php artisan migrate:rollback不支持回滚(需写 undo SQL)
迁移文件是 PHP 类迁移文件是纯 SQL

配置

yaml
# application.yml
spring:
  flyway:
    enabled: true
    locations: classpath:db/migration    # 迁移文件目录
    baseline-on-migrate: true            # 对已有数据库启用基线

添加依赖:

xml
<dependency>
    <groupId>org.flywaydb</groupId>
    <artifactId>flyway-core</artifactId>
</dependency>
<dependency>
    <groupId>org.flywaydb</groupId>
    <artifactId>flyway-mysql</artifactId>
</dependency>

迁移文件命名规则

V1__create_users_table.sql
V2__add_email_to_users.sql
V3__create_posts_table.sql

命名格式:V{版本号}__{描述}.sql

  • 版本号:数字,递增(如 11_12
  • 双下划线 __:分隔符
  • 描述:简短英文,单词用下划线连接

迁移文件内容

sql
-- V1__create_users_table.sql
CREATE TABLE users (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(100) NOT NULL,
    email VARCHAR(255) NOT NULL UNIQUE,
    age INT,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

-- V2__add_email_verified.sql
ALTER TABLE users ADD COLUMN email_verified_at DATETIME NULL;

和 Laravel 不同,Flyway 不提供 Schema Builder(Schema::create('users', function($t) { ... })),你直接写原生 SQL。

好处:SQL 在所有环境完全一致,不会因为 PHP 版本差异导致生成不同 SQL。 坏处:没有 IDE 提示,需要自己记住字段类型语法。

执行时机

Spring Boot 应用启动时自动执行尚未运行过的迁移文件,不需要手动 php artisan migrate

java
@SpringBootApplication
public class DemoApplication {
    public static void main(String[] args) {
        // 启动过程中会:
        // 1. 检查 db/migration/ 目录下未执行的 SQL
        // 2. 按版本号顺序执行
        // 3. 记录执行历史到 flyway_schema_history 表
        // 4. 启动完成,可正常使用数据库
        SpringApplication.run(DemoApplication.class, args);
    }
}

状态查看

sql
-- flyway 会在数据库中创建一张历史记录表
SELECT version, description, installed_on, success
FROM flyway_schema_history;
versiondescriptioninstalled_onsuccess
1create users table2026-04-25 10:00:001
2add email to users2026-04-25 10:00:051

Liquibase(Flyway 的替代方案)

另一个流行的迁移工具。Flyway 用 SQL 文件,Liquibase 用 XML/YAML/JSON 描述变更。

特性FlywayLiquibase
文件格式纯 SQLXML / YAML / JSON / SQL
学习成本低(直接用 SQL)高(需要学 DSL)
回滚需手工写 undo SQL支持自动生成回滚
社区
Spring Boot 整合自动配置自动配置

⚠️ 常见坑

1. 修改已执行过的迁移文件会报错

Flyway 检查文件的 checksum,如果你修改了已执行过的 V1__xxx.sql 并重启,会报:

Migration checksum mismatch for migration version 1

解决方案:

  • 开发阶段:删掉 flyway_schema_history 表对应记录,重新执行
  • 生产环境:永远不要修改已执行的迁移文件,写新的 V2__xxx.sql 来变更

2. 没有 down 方法

Laravel 的 down() 方法允许回滚,Flyway 没有回滚概念。如果需要回滚:

  • 开发中:删库重建(反正没数据)
  • 生产中:写 V2__undo_add_email_to_users.sql 手动做反向操作

3. 多环境数据库基线问题

如果项目已经有一个线上数据库(没有用 Flyway 管理),需要配置 baseline-on-migrate: true,Flyway 会以当前数据库状态为基线,后续迁移基于这个基线运行。

另一种方案:手动在 flyway_schema_history 表中插入一条基线记录,告诉 Flyway "当前版本是 V1"。

4. Spring Boot + Flyway 版本要匹配

Spring Boot 3.x 需要 Flyway 9.x+。版本不匹配时会报兼容性错误。

面向 PHP 开发者的 Spring Boot 文档