~/VibeHandbook
免费 PDF

14 · 04

迁移:安全地更改 Schema

你的 schema 会变化——你会添加一列、重命名一张表、加一个索引。把它想象成对一份共享文档的修订追踪:每一次更改都按顺序记录下来,于是每个人的副本都能用同样的方式更新到最新。一次**迁移(migration)**是一个版本化的、可重复的脚本,描述这样一次更改。迁移之所以重要,是因为你笔记本上的 schema、你队友笔记本上的 schema,以及生产环境里的 schema 必须保持完全一致。

让迁移保持安全的规则:

  • 绝不要在生产环境里手动改数据库。 写一次迁移。
  • 迁移只往前走。 每一次都是一个新文件;你不要去重写那些已经运行过的旧文件。
  • 谨慎进行破坏性更改。 删除一列或一张表会永久删除数据。先有一份备份。
  • 追加式更改最安全。 添加一个可空的列很少会破坏什么;重命名或移除一个列则可能破坏正在运行的代码。

迁移构成一条有序的链:每一次都是一个编号步骤,把数据库的每一份副本从一个已知状态推进到下一个,于是你的笔记本、队友的笔记本和生产环境最终都完全一致:

   空数据库
      │
      ▼
  ┌────────────┐   ┌────────────┐   ┌────────────┐   ┌────────────┐
  │ 001_init   │ ▶ │ 002_add    │ ▶ │ 003_index  │ ▶ │ 004_bio    │
  │ users      │   │ posts      │   │ on author  │   │ 列         │
  └────────────┘   └────────────┘   └────────────┘   └────────────┘
   按顺序应用 ────────────────────────────────────────▶ 当前
   切勿编辑已运行过的步骤 — 新增一个

像 Prisma、Drizzle,或 Rails 迁移这样的工具会为你生成并跟踪这些。让它们去做。

一次迁移由两半组成:要应用的更改(up)和如何撤销它(down)。一个值得信赖的工具会把两者都生成出来,这样一次糟糕的部署就能干净地回滚:

-- up: 添加一个可选的 bio,可在线上安全地应用
ALTER TABLE users ADD COLUMN bio TEXT;

-- down: 把它反转回去
ALTER TABLE users DROP COLUMN bio;

真正危险的迁移是重命名类型更改,因为旧代码和新 schema 会短暂地相互矛盾。专业的做法是把它们拆成追加式的步骤:添加新列、回填它、把代码切换到读取它,只有在之后的一次部署里、当没有任何东西再引用旧列时,才把旧列删掉。它感觉很慢,但这正是一次平滑发布与部署途中每个用户都看到 500 错误激增之间的区别。

想离线阅读?

免费下载整本书的 PDF 或 EPUB。