CodeRoadMap
首页路线题库资源库文章社区
CodeRoadMap

程序员的学习成长路线图。内容免费开放,登录后可同步路线图与课时进度。

由 程序员柏风 独立维护 · 关于作者

学习

  • 路线图
  • 课程
  • 面试题
  • 文章
  • 我

更多

  • 资源
  • 社区
  • 关于作者
  • 内容说明

© 2026 CodeRoadMap

津ICP备2026012044号-1·津公网安备12011002026155号·coderoadmap@126.com
PostgreSQL 实战/课时/迁移与 Flyway
RawBlame
课时目录12 节

PostgreSQL 实战

  1. 01PostgreSQL 是什么
  2. 02安装与 psql
  3. 03DDL 与约束
  4. 04数据类型
  5. 05JSONB
  6. 06索引与 EXPLAIN
  7. 07事务与 MVCC
  8. 08Spring Boot 接入
  9. 09迁移与 Flyway
  10. 10选型:PG vs MySQL
  11. 11Docker 运行 PG
  12. 12综合练习

迁移与 Flyway

schema 版本化、与 backend 迁移思路。

30 分钟

迁移与 Flyway

这一课你将能做到

  1. 说明 Flyway versioned migration 的文件命名与「已执行不可改」规则
  2. 对照本站 backend/src/main/resources/migration/(或 db/migration)理解演进方式
  3. 为 PG 练习库写出 V1__init_app_schema.sql 级别的首条迁移,并知道与 MySQL 方言分文件

为什么要学

手改库结构无法协作:谁改了什么、生产有没有跑过、回滚如何追踪,都会糊成一团。Flyway(或 Liquibase)把 schema 变更变成版本化脚本,Spring Boot 启动时可自动迁移。

本站用迁移目录管理 MySQL 变更。学 PG 时,逻辑相同、SQL 方言不同——自增、布尔、注释写法都要改。官方 Flyway 文档与 PostgreSQL DDL 章是本课对标。

先建立图像

resources/db/migration/
  V1__init_schema.sql          ← 只跑一次,记入历史表
  V2__add_track_metadata.sql
  V3__index_metadata_gin.sql

启动应用 → Flyway 读 flyway_schema_history
         → 按版本号执行「还没跑过」的脚本
         → 记录成功校验和
规则含义
V{数字}__{描述}.sql版本化迁移命名
已成功执行的脚本禁止改内容;只能新增更高版本
校验和文件被改会启动失败(防漂移)
baseline对已有库可标记基线再往前迁

跟着做

步骤 1:浏览本站迁移习惯

打开仓库中的迁移目录(常见为 backend/src/main/resources/migration/ 下 V*.sql)与 schema.sql。笔记:

  • 基线 schema 与增量 V* 如何分工
  • 某次为 cf_track 加列的脚本长什么样(MySQL 方言)

步骤 2:理解 Spring 配置意图

spring:
  flyway:
    enabled: true
    locations: classpath:db/migration
    baseline-on-migrate: true

依赖:spring-boot-starter-flyway + 对应 JDBC 驱动。实验 PG 时,locations 可指到 classpath:db/migration-pg,与 MySQL 脚本隔离。

步骤 3:编写 PG 版 V1

在练习目录创建(路径按你的实验模块调整):

-- V1__init_app_schema.sql  (PostgreSQL)
CREATE SCHEMA IF NOT EXISTS app;

CREATE TABLE app.cf_track (
    id          BIGSERIAL PRIMARY KEY,
    slug        VARCHAR(64) NOT NULL,
    title       VARCHAR(255) NOT NULL,
    description TEXT,
    category    VARCHAR(32) NOT NULL DEFAULT 'language',
    level       VARCHAR(16) NOT NULL DEFAULT 'beginner',
    sort_order  INT NOT NULL DEFAULT 0,
    is_member   BOOLEAN NOT NULL DEFAULT FALSE,
    metadata    JSONB NOT NULL DEFAULT '{}'::jsonb,
    created_at  TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at  TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    CONSTRAINT uq_track_slug UNIQUE (slug)
);

CREATE TABLE app.cf_lesson (
    id          BIGSERIAL PRIMARY KEY,
    track_id    BIGINT NOT NULL REFERENCES app.cf_track (id) ON DELETE CASCADE,
    slug        VARCHAR(64) NOT NULL,
    title       VARCHAR(255) NOT NULL,
    order_index INT NOT NULL DEFAULT 0,
    content_md  TEXT,
    status      VARCHAR(16) NOT NULL DEFAULT 'draft',
    created_at  TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    CONSTRAINT uq_lesson_track_slug UNIQUE (track_id, slug)
);

CREATE INDEX idx_track_metadata_gin ON app.cf_track USING GIN (metadata);

可先在 psql 手动执行验证,再纳入 Flyway。

步骤 4:写一条增量 V2

-- V2__add_track_source_type.sql
ALTER TABLE app.cf_track
  ADD COLUMN IF NOT EXISTS source_type VARCHAR(16) NOT NULL DEFAULT 'imported';

对比 MySQL 版常见写法:TINYINT(1)、无 IF NOT EXISTS 等差异——不要把同一文件指望两边跑通。

步骤 5:模拟「禁止改历史」

  1. 假设 V1 已在历史表登记
  2. 若回头改 V1 加一列 → 校验和失败
  3. 正确做法:新增 V3__…sql

把这条规则写进笔记,比任何工具配置都重要。

步骤 6:注释方言

-- PostgreSQL 列注释
COMMENT ON COLUMN app.cf_track.slug IS '对外 URL 键';

-- MySQL 常在列定义写 COMMENT '…'

团队选一种引擎后,注释风格跟随方言。

讲清楚要点

  1. 迁移是代码:评审、CI、与发版绑定;禁止「只在生产手改」。
  2. 因为 校验和防漂移,所以 已上线脚本只追加新版本。
  3. 方言分目录或分仓库:MySQL 与 PG 脚本分开,避免条件分支宏变成难维护怪物。
  4. 本地可重建:开发库可丢数据重建;生产迁移必须可转发、可观察。
  5. Flyway 不管数据修复的全部哲学:大批量回填可另脚本,注意锁与窗口。
  6. 与本站关系:学完能读懂现有 V*.sql;PG 练习用自己的 migration-pg,不替换生产链。

你可能会懵的地方

  • schema.sql 和 Flyway 谁说了算?
    视项目约定:有的用 schema 初始化再 baseline;有的纯 Flyway。入门先统一「增量都进 V*」。

  • IF NOT EXISTS 是否永远正确?
    便于重跑实验;严格迁移有时故意失败以暴露环境漂移。团队定风格。

  • undo 脚本?
    Flyway Community 以向前迁移为主;回滚靠备份或写反向 Vn。别假设点一下就时空倒流。

  • 多服务共用一库?
    迁移所有权要清晰,避免两服务抢同一历史表。

  • Liquibase 呢?
    同属迁移工具;本课以 Flyway 为例,概念可迁移。

错法对照

错法问题正解
修改已执行的 V1校验失败/环境不一致新增 V2
MySQL 与 PG 共用一份 SQL语法处处炸分目录分方言
生产关 Flyway 手改无法审计保持启用并走脚本
迁移里做超长锁表操作无窗口业务卡住拆步、在线 DDL 策略、低峰
把密钥写进迁移文件泄露用环境变量/密钥管理

自测三问

  1. 为什么不能改已经在 flyway_schema_history 里成功的脚本内容?
  2. PG 的 BOOLEAN / JSONB 在迁移里相对本站 MySQL 意味着什么?
  3. 如何避免实验 PG 迁移误伤生产 MySQL 脚本目录?

小结一句话

Flyway 让 schema 像代码一样版本化;换 PostgreSQL 时主要改 SQL 方言并隔离脚本目录。

官方延伸

  • Flyway 文档
  • PostgreSQL:ALTER TABLE
加载本节练习…
← 上一课Spring Boot 接入下一课 →选型:PG vs MySQL