数据库版本管理:Flyway 迁移实战
David Ng | 2026-08-27T20:55:26 | Spring Boot, Database
使用 Flyway 管理数据库 Schema 变更,涵盖版本命名规范、回滚策略、多环境管理和 CI 集成。
# 数据库版本管理:Flyway 迁移实战 ## 为什么需要数据库迁移? 手动执行 SQL 脚本容易遗漏、顺序错乱、无法追溯。数据库迁移工具让 Schema 变更像代码一样可版本化、可追溯、可回滚。 ## Spring Boot 集成 ```xml org.flywaydb flyway-core org.flywaydb flyway-mysql ``` ```yaml # application.yml spring: flyway: enabled: true locations: classpath:db/migration baseline-on-migrate: true baseline-version: '0' ``` ## 迁移脚本命名规范 ``` db/migration/ V1__create_users_table.sql V2__create_orders_table.sql V3__add_email_to_users.sql V4__create_index_on_orders.sql R__refresh_views.sql -- R 开头:可重复执行的脚本 ``` 命名规则:`V{版本号}__{描述}.sql`,双下划线分隔。 ## 迁移脚本示例 ```sql -- V1__create_users_table.sql CREATE TABLE users ( id BIGINT AUTO_INCREMENT PRIMARY KEY, username VARCHAR(50) NOT NULL UNIQUE, email VARCHAR(100) NOT NULL, password VARCHAR(255) NOT NULL, status TINYINT DEFAULT 1 COMMENT '0-禁用 1-正常', created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, INDEX idx_email (email) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- V2__create_orders_table.sql CREATE TABLE orders ( id BIGINT AUTO_INCREMENT PRIMARY KEY, user_id BIGINT NOT NULL, order_no VARCHAR(32) NOT NULL UNIQUE, amount DECIMAL(12,2) NOT NULL, status VARCHAR(20) DEFAULT 'pending', created_at DATETIME DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (user_id) REFERENCES users(id), INDEX idx_user_id (user_id), INDEX idx_status_created (status, created_at) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- V3__add_email_to_users.sql ALTER TABLE users ADD COLUMN phone VARCHAR(20) AFTER email; ALTER TABLE users ADD INDEX idx_phone (phone); ``` ## 安全变更原则 ```sql -- 安全:添加列(不锁表) ALTER TABLE users ADD COLUMN avatar VARCHAR(255); -- 危险:修改列类型(可能锁表) -- ALTER TABLE users MODIFY COLUMN username VARCHAR(100); -- 建议:先创建新列 -> 迁移数据 -> 删除旧列 -- 安全:创建索引(MySQL 5.6+ Online DDL) ALTER TABLE orders ADD INDEX idx_amount (amount), ALGORITHM=INPLACE, LOCK=NONE; ``` ## 多环境管理 ``` db/migration/ V1__base_schema.sql -- 所有环境 db/migration-test/ V1000__insert_test_data.sql -- 仅测试环境 ``` ```yaml # application-test.yml spring: flyway: locations: classpath:db/migration,classpath:db/migration-test ``` ## 常用命令 ```bash # Maven 插件执行 mvn flyway:info # 查看迁移状态 mvn flyway:migrate # 执行迁移 mvn flyway:validate # 验证脚本一致性 mvn flyway:repair # 修复失败记录 mvn flyway:clean # 清空数据库(危险!) ``` ## CI 集成 ```yaml # GitHub Actions - name: Run DB Migration run: | mvn flyway:validate -Dflyway.url=jdbc:mysql://localhost:3306/testdb mvn flyway:migrate -Dflyway.url=jdbc:mysql://localhost:3306/testdb ``` ## 与 Liquibase 对比 | 特性 | Flyway | Liquibase | |------|--------|-----------| | 脚本格式 | SQL | XML/YAML/SQL | | 学习曲线 | 低 | 中 | | 回滚 | 收费版 | 免费 | | 多数据库 | 好 | 更好 | Flyway 更简单直接,适合纯 SQL 管理。Liquibase 更灵活,适合需要跨数据库兼容的场景。