1658 字
约 5 分钟
1
Flyway 数据库迁移入门
Flyway 数据库迁移入门
1. 一句话简介
Flyway 是一个开源的数据库版本控制 / 迁移工具。它把数据库的每一次结构变更(建表、加字段、改造索引等)写成一份带版本号的 SQL 脚本,统一放在 classpath:db/migration 目录下,应用启动时由 Flyway 自动比对并执行尚未执行的脚本。
核心解决两个问题:一是「人肉维护建表脚本」导致的多环境表结构不一致、部署时忘了执行某条 DDL;二是「数据库结构如何跟随代码一起进版本库、可回溯、可审计」。如本 demo 所示,引入 flyway-core 并在 application.yml 配置数据源后,启动类无需任何额外代码,MySQL 中即可自动生成用户表 t_user 和记录迁移历史的状态表 flyway_schema_history,实现从 V1_0 建表到 V1_1 修改表注释的增量演进。
2. 什么时候使用
✅ 适用场景
- 多环境数据库一致性:开发、测试、预发、生产多套库,希望每次部署都保证表结构与代码版本严格对应,靠 Flyway 自动补齐未执行的脚本。
- 代码化、可版本控制的数据库变更:让 DDL/SQL 进 Git 版本库,随代码分支管理,评审时能 diff 出本次变更了哪些结构。
- 增量与幂等部署:生产环境不能每次
DROP TABLE重建,需要只执行比当前版本高、且从未执行过的脚本。demo 中 Flyway 通过flyway_schema_history记录已执行版本,V1_0执行过一次后不再重复,V1_1按顺序补执行(对应日志 "Current version of schema ... is up to date")。 - 历史可审计、可回溯:状态表记录每次迁移的版本、脚本、校验和与执行时间,出问题时可据此定位是哪一次迁移导致。
- 无需写 Java 代码的轻量集成:Spring Boot 通过
FlywayAutoConfiguration自动配置,只要放好 SQL、改好yml即可,适合 SQL 熟练团队快速上手。
❌ 不适用 / 需谨慎
- 脚本不可修改的约束:
V开头脚本只执行一次,且默认会做 checksum 校验(validate-on-migrate: true)。一旦某版本脚本已在某环境执行,再去编辑原始文件会导致启动报校验失败,需操作历史表或改用新的增量版本,团队需要建立「只增不删改」的脚本纪律。 - 社区版回滚缺失:demo 使用的社区版 Flyway 不支持自动回滚,结构变更出错需要人工编写逆向 SQL 处理。
- 生产环境误操作风险:默认
clean会清空数据库(demo 通过clean-disabled: true关闭),若误配置仍可能造成清零事故,需严格按生产配置约束。 - 不适用的大改造 / 高风险变更:超大表加索引、数据重写等操作若做成迁移脚本会长时间锁表或阻塞,这类变更宜走专门的发版流程而非启动时自动执行。
3. 常见业务场景
- 项目初始化建表:新项目第一次落地时,把完整的建表 SQL 写成
V1_0__INIT.sql(demo 中即创建含主键、唯一索引、默认值的t_user表),应用首次启动即自动完成数据库初始化,省去手工执行脚本的人为疏漏。 - 结构体的渐进式演进:业务迭代需要给表加字段、改约束、更新元信息时,新增高版本脚本(如
V1_1__ALTER.sql执行ALTER TABLE t_user COMMENT = '用户 v1.1'),Flyway 只增量执行,绝不触碰已稳定的历史脚本,实现优雅的线上结构演进。 - 生产环境的幂等发布:灰度、滚动发布多实例时,多个实例同时启动,Flyway 内部处理保证同一版本脚本只执行一次,表结构升级随应用发布自动完成,无需运维单独执行 SQL 或协调停机窗口。
- 团队协作与代码评审:数据库变更作为可读的 SQL 文件参与 Git PR/评审,任何一次「改了库结构」都留下明确可追溯的 commit,降低多人并行开发时的结构冲突。
- CI/CD 集成与回滚准备:在流水线中把 Flyway 校验/迁移作为构建步骤,发布前提前发现高版本脚本的语法或校验问题,配合
flyway_schema_history历史实现问题定位。
4. 同类技术对比
| 维度 | Flyway(Community) | Liquibase | 自定义启动初始化(Spring Boot schema.sql/data.sql) |
|---|---|---|---|
| 脚本格式 | 原生 SQL | XML / YAML / JSON / SQL 抽象 DSL | 原生 SQL |
| 学习成本 | 低,直接写 SQL | 中等,需学习变更集 DSL | 低 |
| 版本控制 | 内置 flyway_schema_history 状态表 |
内置 DATABASECHANGELOG 状态表 |
无状态表,无版本管理 |
| 幂等/增量执行 | 支持,V 前缀仅执行一次 | 支持,changeSet 记录执行 | 每次启动按 spring.sql.init.mode 重复执行或需自行判断 |
| 回滚支持 | 社区版不支持 | 支持(rollback) | 不支持 |
| 多数据库适配 | 支持主流数据库 | 更广,抽象 DSL 跨库移植性强 | 依赖具体 SQL |
| Spring Boot 集成 | 自动配置,零代码 | 深度集成较好但配置略复杂 | 内置支持 |
| 适用规模 / 场景 | 中小型项目、SQL 熟练、敏捷迭代团队 | 大型项目、多数据库平台、需强回滚与复杂变更的组织 | 脚本极简的临时原型,不建议生产依赖 |
选型建议
- 中小型项目、团队 SQL 扎实、追求快速上手和零配置,选 Flyway——与 Spring Boot 集成最顺,直接写 SQL 成本最低,demo 即代表这一典型路径。
- 大型组织、需要跨多种数据库移植脚本、强依赖变更回滚与复杂变更编排,选 Liquibase,其抽象 DSL 和 rollback 能力在规范治理场景更占优。
- 仅需一次性初始化的极简场景或临时环境,可用 Spring Boot 内置的
schema.sql/data.sql;因其无版本状态表、每次启动会重复执行,生产环境的结构演进不建议依赖它。
评论
0 条
还没有评论,先写一条吧。