4. 迁移文件命名规范:版本号前缀、分隔符、描述、双下划线规则、版本排序逻辑

Flyway 通过约定优于配置的方式识别并执行迁移脚本。文件名是 Flyway 判断迁移类型、版本顺序、校验和匹配的核心依据。一个标准的 Flyway 迁移文件名由四个部分组成:前缀、版本号、分隔符、描述。理解并严格遵守这套命名规范,是构建可维护、可追溯的数据库版本链的第一步。

4.1 文件名结构总览

Flyway 迁移文件的标准命名格式如下:

[Prefix][Version]__[Description].sql

其中,__(双下划线)是版本号与描述之间的固定分隔符。以下是一个具体示例:

V2.1.3__add_user_email_column.sql
组成部分 示例值 说明
前缀(Prefix) V 标识迁移类型,区分版本化迁移、可重复迁移、撤销迁移
版本号(Version) 2.1.3 数字或点分数字序列,用于排序和唯一标识
分隔符(Separator) __ 固定为双下划线,将版本号与描述隔开
描述(Description) add_user_email_column 简短、可读的英文单词,用下划线或空格连接
最佳实践:描述部分建议使用小写英文字母和下划线,避免使用中文、特殊字符或过长短语。描述应清晰表达本次迁移的意图,如 create_user_table、add_index_on_email。

4.2 前缀规则:区分迁移类型

Flyway 支持三种前缀,分别对应不同的迁移生命周期:

前缀 迁移类型 执行特性 典型场景
V 版本化迁移(Versioned Migration) 每个版本仅执行一次,按版本号顺序执行,不可修改 DDL 变更、新增表、新增字段
R 可重复迁移(Repeatable Migration) 每次校验和变化时重新执行,不依赖版本号排序 视图、存储过程、函数、物化视图
U 撤销迁移(Undo Migration) 用于回滚指定版本化迁移,需与对应 V 版本号一致 紧急回滚、版本撤销
注意:撤销迁移(U 前缀)在 Flyway 社区版中默认不启用,且官方建议谨慎使用。生产环境中更推荐通过 V 版本化迁移的“向前修复”策略来处理错误,而非依赖撤销迁移。

4.3 版本号规则与排序逻辑

版本号是 Flyway 排序和执行的核心依据。版本号可以是一个简单的整数,也可以是由点分隔的多级数字序列。

4.3.1 版本号组成规则

  • 允许字符:数字(0-9)和点(.)。
  • 禁止字符:字母、下划线、连字符、空格、前导零(如 01.2 不推荐)。
  • 多级版本:支持任意层级,如 1、2.1、3.0.1、2024.11.01。
  • 唯一性:每个版本号在同一个 Flyway 项目中必须唯一,不可重复。

4.3.2 版本排序逻辑

Flyway 对版本号采用数值逐段比较的排序算法,而非字符串字典序。这意味着 V2.10 会排在 V2.9 之后,而不是像字符串排序那样排在 V2.9 之前。

文件名 版本号 排序位置 说明
V1__init.sql 1 1 基础版本
V2__add_users.sql 2 2 整数版本
V2.1__add_email.sql 2.1 3 次版本
V2.10__add_index.sql 2.10 4 数值比较,10 > 1
V3__add_roles.sql 3 5 主版本升级
关键结论:版本号 2.10 在排序中大于 2.9 也大于 2.1,因为 Flyway 逐段比较数字:2 == 2,然后 10 > 9 且 10 > 1。这一特性要求团队在规划版本号时预留足够的数字空间,避免版本冲突。

4.4 双下划线分隔符规则

Flyway 使用 双下划线(__) 作为版本号与描述之间的固定分隔符。这一设计有明确的工程考量:

  • 唯一性:双下划线在文件名中极少出现,便于 Flyway 解析器精确切割版本号和描述。
  • 避免歧义:单下划线在版本号或描述中可能被使用(如 V2_1 或 add_user),双下划线确保分隔符不会被误读为版本号或描述的一部分。
  • 可读性:双下划线在视觉上形成明显的断点,开发者可以快速定位版本号和描述的分界。
命名示例对比:
✅ 正确:V2.1.3__add_user_email_column.sql
❌ 错误:V2.1.3_add_user_email_column.sql(单下划线,Flyway 无法正确解析)
❌ 错误:V2.1.3--add_user_email_column.sql(连字符,不符合规范)

4.5 描述规则与可读性

描述部分用于向开发者传达本次迁移的意图。虽然 Flyway 对描述内容没有严格的语法限制,但良好的描述习惯能显著提升项目的可维护性。

规则 推荐做法 示例
语言 使用英文小写 create_user_table
单词连接 使用下划线(_) add_index_on_email
长度 不超过 50 个字符 update_order_status_trigger
动词开头 使用 add、create、update、drop drop_old_deprecated_columns
禁止内容 避免中文、空格、特殊符号 ❌ 添加用户表 ❌ add user table

4.6 版本排序逻辑与执行顺序

Flyway 在启动时会扫描所有迁移文件,并按照以下规则确定执行顺序:

  1. 按前缀分组:先处理 V 前缀的版本化迁移,再处理 R 前缀的可重复迁移。
  2. 版本号数值排序:对 V 前缀的迁移,按版本号逐段数值比较升序排列。
  3. 描述不参与排序:描述仅用于日志和记录,不影响执行顺序。
  4. 已执行版本跳过:如果 flyway_schema_history 表中已记录某版本,则跳过该文件。
排序示例:
假设有以下文件:
V1__init.sql、V2.1__add_users.sql、V2.10__add_index.sql、V2.2__add_roles.sql、V3__final.sql
实际执行顺序为:V1 → V2.1 → V2.2 → V2.10 → V3
注意 V2.2 排在 V2.10 之前,因为第二段数值 2 < 10。

4.7 命名规范常见错误与避坑指南

错误类型 错误示例 后果 正确做法
单下划线分隔 V1_init.sql Flyway 无法解析版本号,抛出异常 V1__init.sql
版本号含字母 V1a__fix.sql 解析失败或排序异常 V1.1__fix.sql
版本号前导零 V01__init.sql 数值比较时 01 被当作 1,可能引发歧义 V1__init.sql
描述含空格 V2__add user.sql 部分操作系统或工具无法正确处理空格 V2__add_user.sql
版本号重复 两个文件都叫 V2__xxx.sql Flyway 报唯一性冲突,迁移失败 确保每个版本号唯一

4.8 命名规范架构总览

以下 SVG 图展示了 Flyway 迁移文件命名规范的完整结构、排序逻辑以及常见错误对照:

Flyway 迁移文件命名规范架构 标准文件名结构 [Prefix] [Version] __ [Description] .sql 前缀 (Prefix) V / R / U 版本号 (Version) 1 / 2.1 / 3.0.1 分隔符 __ (双下划线) 描述 (Description) add_user_table 版本排序逻辑(数值逐段比较) V1__init.sql → 版本 1 V2.1__add_users.sql → 版本 2.1 V2.2__add_roles.sql → 版本 2.2 V2.10__add_index.sql → 版本 2.10 执行顺序:1 → 2.1 → 2.2 → 2.10 注意:2.2 排在 2.10 之前 因为 2 < 10(数值比较) 常见错误 ❌ V1_init.sql(单下划线) ❌ V1a__fix.sql(版本号含字母) ❌ V01__init.sql(前导零) 正确示例 ✅ V1__init.sql ✅ V2.1.3__add_user_email_column.sql ✅ V2024.11.01__release.sql

4.9 团队命名规范建议

在团队协作中,建议将命名规范写入项目 CONTRIBUTING.md 或 README.md,并配合以下措施确保一致性:

  • 代码审查:在 PR 审查中检查迁移文件名是否符合规范。
  • 自动化校验:使用 CI 脚本或 Flyway 的 validate 命令检查文件名格式。
  • 版本号规划:采用语义化版本(如 1.0.0、2.1.0)或基于日期的版本(如 2024.11.01),避免版本号冲突。
  • 描述模板:统一使用 动词_名词_修饰语 的格式,如 create_user_table、add_index_on_email。
推荐工具:可以使用 flyway-helper 或自定义脚本自动生成符合规范的迁移文件名模板,减少手动命名错误。