Vibe Tutorial
数据持久化与数据库

7.6 数据库迁移实战

Tip

学会管理数据库的生命周期,让你的每一次数据库变更都可追踪、可回滚。


1. 为什么要学这个?

你在本地给用户表加了一个 age 字段,代码跑得很开心。 然后你把代码部署到线上。

注意看:线上的代码更新了,但线上的数据库还没变! 线上代码试图去读取 age,但数据库里根本没这个列。 程序当场崩溃。

你可能会想:"那我手动去线上数据库加个列不就行了?" 这就像你在玩游戏时不做存档,直接去改游戏文件。 一旦你手抖删错了一列,或者把测试数据污染到了生产环境,没有任何后悔药可吃

掌握 Migration(迁移),就像给数据库装了"时光机"——每一次修改都被自动记录为历史存档,如果你搞砸了,随时可以回滚。


2. 核心概念

Migration (迁移) 体现为你的项目里的一堆 .sql 文件。 通常在 prisma/migrations 文件夹里。

不再"裸奔"

它解决了**"版本同步"**的问题。你的代码用 Git 管理,你的数据库结构用 Migration 管理。这样,你的数据库就能跟上代码的步伐,永远保持步调一致。

没有 Migration (裸奔): 你需要拿个小本本记着:"上线前记得去数据库执行 ALTER TABLE ADD COLUMN age..."。如果忘了,线上就炸。

有了 Migration (全自动): 你只需要运行一个命令,Prisma 会自动检测:"哦,你上次存档是版本3,现在是版本4,我来帮你把数据库自动升级到版本4。"

核心流程图

graph TD
    Local[你的电脑] -->|修改 schema| Code["schema.prisma"]
    Code -->|生成存档| SQL["SQL文件 (Migration)"]
    
    SQL -->|上传| Git["Git 仓库"]
    
    Git -->|部署| Server[线上服务器]
    Server -->|自动执行 SQL| DB_Prod[线上数据库]
    
    style DB_Prod fill:#e3f2fd,stroke:#1565c0

3. 实战体验

第一步:修改设计

你在 schema.prisma 里加了个字段:

model User {
  id    Int    @id
  name  String
  age   Int?   // 新加的
}

第二步:生成存档

运行命令: npx prisma migrate dev --name add_age

这时候 Prisma 会做两件事:

  1. 自动在 migrations 文件夹里生成一个 SQL 文件(比如 20240101_add_age.sql)。
  2. 自动把这个 SQL 执行到你的本地数据库

第三步:上线

当你把代码推送到线上,云平台会自动检测到这个新生成的 SQL 文件,并把它应用到线上数据库


4. 避坑指南

❌ 不要这样做 ✅ 应该这样做 💡 为什么
migrations 文件夹加入 .gitignore 必须把 migrations 提交到 Git 它是数据库的"历史档案",队友和线上环境都需要它来同步数据库结构。
手动去数据库改表结构 永远通过修改 schema.prisma 来改 手动改了,Prisma 不知道,下次生成迁移文件时会冲突报错。
在生产环境运行 migrate dev 生产环境用 migrate deploy dev 命令会尝试重置数据库(清空数据!),这是新手把生产库删库的头号原因

5. 真实案例

Story

Knight Capital 的 4.4 亿美元蒸发事故 (2012)

2012年,美国骑士资本 (Knight Capital) 在一次软件更新中犯了一个致命错误:工程师手动部署了新代码,却忘记更新服务器上的一个旧配置(这就像你改了 schema 但忘了跑 migrate)。 这个看似微不足道的环境不一致问题,导致新代码逻辑错乱,开始疯狂地在市场上高价买入、低价卖出股票。 仅仅 45 分钟,公司就亏损了 4.4 亿美元,直接导致这家华尔街巨头破产被收购。

Vibe 心法:人为操作是最大的安全隐患。Migration 是保证所有环境(开发、测试、生产)绝对一致的唯一手段。不要相信你的记忆,要相信代码生成的 SQL 文件。


6. 本章小结

  1. 时光机:Migration 就是数据库的历史存档。
  2. 🤖 自动化:用代码去管理数据库结构,而不是手动去改。
  3. 🚨 生死命令:本地用 dev,线上用 deploy,记不住就把它写进部署脚本里。