1. Flyway 概述

1.1 Flyway 是什么

Flyway 是一款开源的数据库版本控制工具,采用 “约定优于配置” 的设计哲学,将数据库脚本的变更纳入版本管理,使数据库的演进与应用程序代码的迭代保持同步。它通过扫描指定路径下的迁移脚本,自动计算当前数据库版本与目标版本之间的差异,并按顺序执行未应用的迁移,从而确保开发、测试、生产环境的数据库结构始终一致。

核心定位:Flyway 不是数据库客户端,而是一个数据库迁移引擎。它不关心 SQL 的具体内容,只关心迁移脚本的版本号、顺序和校验和,从而保证迁移过程的可重复性和可追溯性。

Flyway 支持 Java、Maven、Gradle、命令行等多种集成方式,可无缝嵌入 Spring Boot、Quarkus 等主流框架,是微服务架构中数据库持续交付的标准组件之一。

1.2 核心概念

Flyway 定义了三种迁移类型,分别对应不同的变更场景:

迁移类型 命名格式 执行时机 校验和 典型场景
版本化迁移 V<版本号>__<描述>.sql 按版本号升序执行,每个版本仅执行一次 记录校验和,禁止修改已执行脚本 建表、加字段、创建索引等结构性变更
可重复迁移 R__<描述>.sql 每次校验和发生变化时重新执行 校验和变化即触发重新执行 视图、存储过程、函数、物化视图
撤销迁移 U<版本号>__<描述>.sql 手动触发,回退指定版本 与对应版本化迁移配对 紧急回滚、开发环境重置
实践建议:版本化迁移是生产环境的主力,每个迁移脚本应只包含一个原子变更(如一张表或一个索引),便于回滚和问题定位。可重复迁移适合管理视图和函数,但要注意其执行顺序不受版本号控制,如果视图之间存在依赖,需在脚本内通过 DROP IF EXISTS + CREATE 的方式保证幂等性。

Flyway 通过一张名为 flyway_schema_history 的元数据表来记录所有已执行的迁移记录,包括版本号、描述、脚本类型、校验和、执行时间等关键信息。每次启动时,Flyway 会对比文件系统中的脚本与元数据表中的记录,决定哪些脚本需要执行。

1.3 与传统数据库脚本管理的对比

传统数据库脚本管理通常依赖 DBA 手动执行或通过简单的 SQL 文件归档,存在以下痛点:

  • 版本混乱:脚本文件散落在不同目录,缺乏统一的版本标识,难以追溯哪个脚本在哪个环境执行过。
  • 重复执行风险:同一脚本在多个环境重复执行,导致 ORA-00955: name is already used by an existing object 等错误。
  • 协作困难:多人并行开发时,脚本合并冲突频繁,且无法自动检测依赖顺序。
  • 回滚无标准:回滚操作依赖人工编写反向 SQL,容易遗漏或出错。

Flyway 通过版本化、校验和、元数据表等机制,从根本上解决了上述问题。以下对比表可以直观展示差异:

对比维度 传统脚本管理 Flyway 管理
版本标识 文件名或注释,无强制规范 版本号 + 描述,严格升序
执行记录 无或手动记录 自动写入 flyway_schema_history
重复执行防护 依赖人工判断或 IF NOT EXISTS 校验和 + 已执行标记,自动跳过
回滚能力 手动编写反向 SQL 撤销迁移脚本,版本配对回滚
多环境一致性 依赖人工同步 脚本即配置,自动同步
协作冲突 频繁冲突,手动解决 版本号隔离,冲突可检测
Flyway 核心架构与迁移流程 迁移脚本文件 V1__init.sql V2__add_column.sql R__view_order.sql Flyway 迁移引擎 版本号排序 校验和计算 依赖检测 锁定机制 目标数据库 应用 DDL/DML 写入元数据表 记录执行时间 flyway_schema_history 元数据表 installed_rank | version | description | type | checksum | installed_on 1 | 1 | init | SQL | 123456789 | 2025-01-15 10:00:00 2 | 2 | add_column | SQL | 987654321 | 2025-01-15 10:05:00 核心设计原则 版本号不可重复 已执行脚本不可修改
常见误区:不要将 Flyway 与 Liquibase 混淆。Flyway 使用原生 SQL 脚本,学习成本低;Liquibase 使用 XML/YAML/JSON 描述变更,更灵活但语法更重。选择哪个取决于团队对 SQL 的掌控力和对声明式配置的偏好。在微服务场景下,Flyway 的轻量级和 Spring Boot 原生集成使其更受欢迎。