2. 核心概念:数据库 Schema、API 契约、版本号语义化(SemVer)、向前兼容与向后兼容

在构建数据库迁移与 API 版本对齐的体系时,必须首先统一四个核心概念的语言。它们是整个蓝图的地基:数据库 Schema 定义了数据的静态结构;API 契约 约定了服务间的交互边界;语义化版本号 提供了可计算的演进规则;兼容性方向 决定了迁移是否安全。下面逐一拆解。

2.1 数据库 Schema:数据的静态骨架

数据库 Schema 是对数据库结构的形式化描述,包括表、列、数据类型、约束、索引、视图、存储过程等。在迁移语境中,Schema 是“源”与“目标”之间的差异度量单位。

Schema 元素 示例 变更影响
表结构 CREATE TABLE users (id INT, name VARCHAR) 增删列、修改类型、调整约束
索引 CREATE INDEX idx_email ON users(email) 查询性能变化,不改变数据语义
约束 FOREIGN KEY (dept_id) REFERENCES dept(id) 引用完整性规则变化
视图/存储过程 CREATE VIEW active_users AS ... 逻辑层抽象变化,可能影响上游查询
实践要点: 每次迁移都应生成一份 Schema 差异清单(diff),作为版本号变更的输入依据。只改索引不增删列,通常只需补丁版本;增删列则至少需要次版本。

2.2 API 契约:服务间的正式约定

API 契约是服务提供方与消费方之间的双边协议,通常以 OpenAPI(Swagger)、gRPC Proto、GraphQL Schema 或 JSON Schema 等形式定义。契约包含:端点路径、请求参数、响应结构、错误码、认证方式。

在数据库迁移场景中,API 契约是“保护层”——它决定了数据库 Schema 的变化能否被安全地暴露给客户端。如果契约不变,数据库 Schema 的变更必须被封装在服务内部;如果契约必须变,则版本号必须升级。

关键原则: 数据库 Schema 是内部实现,API 契约是外部承诺。两者可以不同步,但每次 API 版本变更都必须有对应的数据库 Schema 版本作为支撑。

2.3 版本号语义化(SemVer):可计算的演进规则

语义化版本号(SemVer)采用 MAJOR.MINOR.PATCH 格式,为每个版本赋予明确的兼容性含义。在数据库迁移与 API 对齐的上下文中,SemVer 的语义需要映射到 Schema 和契约的变化类型。

SemVer 段 数据库 Schema 变化 API 契约变化 升级动作
MAJOR 删除列、修改列类型、破坏性约束变更 删除端点、修改请求/响应结构(不兼容) 必须同步升级,客户端需改造
MINOR 新增列(可空或有默认值)、新增索引 新增端点、新增可选字段 向后兼容,客户端可逐步升级
PATCH 修改注释、调整索引类型、性能优化 修复文档、调整错误消息 完全透明,无需客户端配合
常见陷阱: 只改数据库不改 API 版本号,或只改 API 版本号不改数据库版本号,都会导致版本信息失真。建议采用双版本号追踪:数据库 Schema 版本 + API 契约版本,两者独立演进但通过迁移脚本关联。

2.4 向前兼容与向后兼容:两个方向的安全网

兼容性方向是迁移决策的核心判断依据。两个方向的定义常被混淆,这里给出精确区分:

  • 向后兼容(Backward Compatible): 新版本的消费者可以正确处理旧版本提供者返回的数据。即:新客户端 → 旧服务 能正常工作。
  • 向前兼容(Forward Compatible): 旧版本的消费者可以正确处理新版本提供者返回的数据。即:旧客户端 → 新服务 能正常工作。

在数据库迁移中,向后兼容通常更容易实现(只加不减、只扩不缩);向前兼容则要求服务端在返回新字段时,旧客户端能忽略未知字段(如 JSON 的 additionalProperties 或 Protobuf 的字段编号预留)。

兼容性方向:向后兼容 vs 向前兼容 向后兼容(Backward Compatible) 新客户端 旧服务 / 旧 DB 请求 响应 ✓ 新客户端能理解旧服务的数据 常见做法:只加字段、不删字段 数据库:新增列必须可空或有默认值 向前兼容(Forward Compatible) 旧客户端 新服务 / 新 DB 请求 响应 ✓ 旧客户端能忽略新服务的新字段 实现难度更高:需预留字段编号 数据库:旧查询不能因新列而报错

2.5 四个概念的关系矩阵

将上述四个概念整合到一个关系矩阵中,可以快速判断一次迁移的风险等级:

场景 Schema 变化 契约变化 SemVer 建议 兼容性 风险
新增可空列 MINOR 无变化 MINOR / PATCH 向后兼容 低
新增必填列 MINOR MINOR(新增字段) MINOR 向后兼容 中
删除列 MAJOR MAJOR(删除字段) MAJOR 破坏性 高
修改列类型(如 INT→BIGINT) MAJOR MAJOR(类型变更) MAJOR 破坏性 高
新增索引 PATCH 无变化 PATCH 完全透明 极低
核心结论: 数据库 Schema 的每一次变更,都应该映射到 API 契约的版本号上。使用 SemVer 作为共同语言,用向后兼容和向前兼容作为安全边界,才能构建可审计、可回滚的迁移体系。