2. 核心概念:ChangeLog、ChangeSet、ID、Author、File Encoding、Context、Label

在 Liquibase 的迁移体系中,ChangeLog 是数据库变更的“总谱”,而 ChangeSet 则是谱中的每一个“乐章”。理解这七个核心概念,是编写可维护、可追溯、可协作的数据库版本脚本的基础。

2.1 ChangeLog:变更日志文件

ChangeLog 是 Liquibase 迁移的入口文件,通常以 XML、YAML、JSON 或 SQL 格式编写。它定义了数据库变更的顺序、依赖关系以及执行策略。

  • 根元素:XML 格式下为 <databaseChangeLog>,YAML 格式下为 databaseChangeLog:。
  • 包含关系:一个 ChangeLog 可以引用其他 ChangeLog 文件(通过 <include> 或 <includeAll>),实现模块化管理。
  • 属性声明:可在 ChangeLog 级别声明 logicalFilePath、objectQuotingStrategy 等全局属性。
最佳实践:将 ChangeLog 按业务模块或版本号拆分,避免单个文件过大。例如:v1.0.0/changelog-master.xml、v1.1.0/changelog-feature-orders.xml。

2.2 ChangeSet:变更集

ChangeSet 是 ChangeLog 中的最小执行单元,代表一次原子性的数据库变更。每个 ChangeSet 必须包含 ID 和 Author 两个唯一标识属性。

<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                   xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
                   http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.20.xsd">

    <changeSet id="1" author="zhang.san">
        <createTable tableName="users">
            <column name="id" type="int" autoIncrement="true">
                <constraints primaryKey="true" nullable="false"/>
            </column>
            <column name="username" type="varchar(50)">
                <constraints unique="true" nullable="false"/>
            </column>
        </createTable>
    </changeSet>

</databaseChangeLog>

2.3 ID 与 Author:唯一标识

ID 和 Author 的组合构成了 ChangeSet 在数据库中的唯一键。Liquibase 通过 DATABASECHANGELOG 表记录已执行的 ChangeSet,确保每个变更只执行一次。

属性 说明 示例
ID ChangeSet 的序号或标识符,在同一 ChangeLog 中建议保持唯一 1、V1.0.0-001、add-users-table
Author 变更的作者,通常使用系统用户名或团队约定名称 zhang.san、devops-team、li.si
组合唯一性 ID + Author + filePath 共同决定 ChangeSet 是否已执行 1::zhang.san::changelogs/db.changelog-master.xml
注意:一旦 ChangeSet 被标记为已执行(already executed),严禁修改其 ID 或 Author,否则 Liquibase 会将其视为新的 ChangeSet 并尝试再次执行,导致重复变更或冲突。

2.4 File Encoding:文件编码

ChangeLog 文件的编码方式直接影响 SQL 语句中特殊字符(如中文、表情符号、欧元符号)的解析。Liquibase 默认使用 UTF-8 编码读取文件。

  • 声明方式:在 ChangeLog 根元素中通过 encoding 属性指定。
  • 推荐值:始终使用 UTF-8,确保跨平台、跨团队的一致性。
  • 常见问题:若文件实际编码与声明不一致,Liquibase 会抛出 UnsupportedEncodingException 或产生乱码数据。
<databaseChangeLog encoding="UTF-8" ...>
    <changeSet id="2" author="li.si">
        <sql>
            INSERT INTO users (username) VALUES ('张三');
        </sql>
    </changeSet>
</databaseChangeLog>

2.5 Context:上下文

Context 允许你为 ChangeSet 打上“环境标签”,控制其在特定场景下是否执行。常用于区分开发、测试、生产环境的差异化变更。

  • 定义方式:在 ChangeSet 上添加 context 属性,多个值用逗号分隔。
  • 激活方式:运行 Liquibase 时通过 --contexts 参数指定激活的上下文。
  • 匹配逻辑:ChangeSet 的 context 值只要与激活列表中的任意一个匹配,即会执行。
<changeSet id="3" author="wang.wu" context="dev,test">
    <insert tableName="config">
        <column name="key" value="debug_mode"/>
        <column name="value" value="true"/>
    </insert>
</changeSet>

<changeSet id="4" author="wang.wu" context="prod">
    <insert tableName="config">
        <column name="key" value="debug_mode"/>
        <column name="value" value="false"/>
    </insert>
</changeSet>

2.6 Label:标签

Label 是另一种过滤机制,与 Context 类似但更灵活。Label 支持 逻辑表达式(AND、OR、NOT),适合复杂的执行条件判断。

特性 Context Label
语法 逗号分隔的字符串列表 支持逻辑表达式(!、&、|)
匹配方式 任意一个匹配即执行 表达式整体求值
典型场景 环境区分(dev/test/prod) 功能开关、灰度发布、A/B 测试
示例 context="dev,staging" labels="feature_x & !prod"
<changeSet id="5" author="zhao.liu" labels="migration_v2 & (us_east | eu_west)">
    <addColumn tableName="orders">
        <column name="region" type="varchar(10)"/>
    </addColumn>
</changeSet>
实战建议:使用 Context 做环境隔离,使用 Label 做功能维度隔离。两者可以同时使用,Liquibase 会先过滤 Context,再过滤 Label。

2.7 核心概念关系图

下图展示了 ChangeLog、ChangeSet 及其核心属性之间的层级关系与执行过滤流程:

Liquibase 核心概念关系与执行过滤流程 ChangeLog ChangeSet 唯一标识属性 • ID • Author • File Encoding 执行过滤属性 • Context • Label 执行控制属性 • runOnChange • runAlways • failOnError 执行过滤顺序:Context → Label → ID+Author 唯一性检查 DATABASECHANGELOG 表

2.8 核心概念速查表

概念 作用层级 是否必需 典型值/示例
ChangeLog 文件级 是 db.changelog-master.xml
ChangeSet 变更单元级 是 包含 <createTable>、<addColumn> 等
ID ChangeSet 属性 是 1、V2.0-add-index
Author ChangeSet 属性 是 zhang.san、devops-bot
File Encoding ChangeLog 属性 推荐 UTF-8
Context ChangeSet 属性 否 dev、test,staging
Label ChangeSet 属性 否 feature_x & !prod
记忆口诀:“ChangeLog 是总谱,ChangeSet 是乐句;ID+Author 定身份,Encoding 保不乱码;Context 分环境,Label 做开关。”