# Prisma 增量迁移指南

## 📋 概述

Prisma 的迁移机制**已经内置了增量执行功能**。当你运行迁移命令时，Prisma 会自动：

- ✅ 只执行**新增的、未应用的**迁移
- ✅ **跳过**已经执行过的迁移
- ✅ 通过 `_prisma_migrations` 表跟踪迁移状态

---

## 🔍 Prisma 如何跟踪迁移状态

Prisma 在数据库中维护一个特殊的表 `_prisma_migrations`，用于记录：

- 迁移名称（migration_name）
- 应用时间（applied_at）
- 迁移文件内容（checksum）
- 其他元数据

每次迁移执行后，Prisma 会在这个表中记录一条记录，确保不会重复执行。

---

## 🚀 迁移命令对比

### 1. `prisma migrate deploy`（生产环境推荐）

**特点**：

- ✅ **只执行未应用的迁移**
- ✅ 不会创建新迁移
- ✅ 不会重置数据库
- ✅ 适合生产环境

**使用场景**：

- 生产环境部署
- CI/CD 流程
- 多环境同步

**示例**：

```bash
# 生产环境
npm run prisma:migrate:deploy

# 或直接使用
NODE_ENV=production prisma migrate deploy
```

**执行逻辑**：

1. 读取 `prisma/migrations` 目录中的所有迁移文件
2. 查询数据库中的 `_prisma_migrations` 表
3. 对比找出未应用的迁移
4. **只执行未应用的迁移**
5. 在 `_prisma_migrations` 表中记录新应用的迁移

---

### 2. `prisma migrate dev`（开发环境推荐）

**特点**：

- ✅ 创建新迁移（如果有 schema 变更）
- ✅ **只执行未应用的迁移**
- ✅ 可能会重置开发数据库（如果使用 shadow database）
- ✅ 适合开发环境

**使用场景**：

- 本地开发
- Schema 变更后创建迁移

**示例**：

```bash
# 开发环境
npm run prisma:migrate

# 或直接使用
prisma migrate dev
```

**执行逻辑**：

1. 检查 schema.prisma 是否有变更
2. 如果有变更，创建新迁移文件
3. 查询 `_prisma_migrations` 表找出未应用的迁移
4. **只执行未应用的迁移**（包括新创建的）
5. 记录到 `_prisma_migrations` 表

---

## 📊 查看迁移状态

### 检查哪些迁移已应用

```bash
# 查看迁移状态
npx prisma migrate status

# 输出示例：
# ✅ Database schema is up to date!
#
# The following migrations have been applied:
#   - 20251118035205_init
#   - 20251118041000_add_comments
#   - 20251118211424_change_log_content_to_text
```

### 直接查询数据库

```sql
-- 查看所有已应用的迁移
SELECT * FROM _prisma_migrations ORDER BY applied_at DESC;

-- 查看迁移名称和状态
SELECT migration_name, applied_at, finished_at
FROM _prisma_migrations
ORDER BY applied_at DESC;
```

---

## 🎯 实际使用场景

### 场景 1：生产环境部署

**情况**：生产数据库已经有部分迁移，现在要部署新版本

```bash
# 1. 部署新代码（包含新的迁移文件）

# 2. 运行迁移（只会执行新增的迁移）
npm run prisma:migrate:deploy

# Prisma 会自动：
# - 检查 _prisma_migrations 表
# - 找出未应用的迁移（如：20251120000000_new_feature）
# - 只执行这个新迁移
# - 跳过已执行的迁移（如：20251118035205_init）
```

**结果**：

- ✅ 已执行的迁移不会重复执行
- ✅ 只执行新增的迁移
- ✅ 数据库结构同步到最新状态

---

### 场景 2：多环境同步

**情况**：开发环境有 3 个迁移，生产环境只有 2 个

```bash
# 开发环境迁移：
# - 20251118035205_init ✅
# - 20251118041000_add_comments ✅
# - 20251118211424_change_log_content_to_text ✅

# 生产环境迁移：
# - 20251118035205_init ✅
# - 20251118041000_add_comments ✅
# - 20251118211424_change_log_content_to_text ❌（未应用）

# 在生产环境运行：
npm run prisma:migrate:deploy

# Prisma 会：
# - 跳过前两个已应用的迁移
# - 只执行最后一个未应用的迁移
```

---

### 场景 3：回滚和修复

**情况**：某个迁移执行失败，需要修复

```bash
# 1. 检查迁移状态
npx prisma migrate status

# 2. 如果迁移失败，_prisma_migrations 表中不会有记录
# 3. 修复迁移文件后，重新运行
npm run prisma:migrate:deploy

# Prisma 会：
# - 检查失败的迁移是否已记录
# - 如果没有记录，会重新执行
# - 如果已记录，会跳过
```

---

## ⚠️ 注意事项

### 1. 不要手动修改 `_prisma_migrations` 表

这个表由 Prisma 自动管理，手动修改可能导致迁移状态不一致。

### 2. 迁移文件不要删除

即使迁移已执行，也不要删除 `prisma/migrations` 目录中的迁移文件。这些文件是迁移历史的一部分。

### 3. 生产环境使用 `migrate deploy`

```bash
# ✅ 正确：生产环境
prisma migrate deploy

# ❌ 错误：生产环境不要使用
prisma migrate dev  # 可能会重置数据库
```

### 4. 迁移文件顺序很重要

Prisma 按照迁移文件名（时间戳）的顺序执行迁移。确保迁移文件名的时间戳顺序正确。

---

## 🔧 故障排查

### 问题 1：迁移状态不一致

**症状**：`prisma migrate status` 显示状态不一致

**解决**：

```bash
# 1. 检查 _prisma_migrations 表
SELECT * FROM _prisma_migrations;

# 2. 检查迁移文件
ls -la prisma/migrations/

# 3. 如果迁移文件存在但未记录，手动标记（谨慎操作）
# 或者重新运行迁移
prisma migrate deploy
```

### 问题 2：迁移重复执行

**症状**：迁移被重复执行

**原因**：`_prisma_migrations` 表中没有记录

**解决**：

```bash
# 检查迁移记录
npx prisma migrate status

# 如果显示迁移未应用，但数据库结构已存在
# 可能需要手动标记迁移为已应用（谨慎操作）
```

### 问题 3：迁移文件丢失

**症状**：迁移文件被删除，但数据库中有记录

**解决**：

```bash
# 1. 从版本控制恢复迁移文件
git checkout prisma/migrations/

# 2. 重新运行迁移检查
npx prisma migrate status
```

---

## 📚 相关命令速查

| 命令                    | 说明                   | 使用场景 |
| ----------------------- | ---------------------- | -------- |
| `prisma migrate deploy` | 只执行未应用的迁移     | 生产环境 |
| `prisma migrate dev`    | 创建并执行迁移         | 开发环境 |
| `prisma migrate status` | 查看迁移状态           | 所有环境 |
| `prisma migrate reset`  | 重置数据库（开发环境） | 开发环境 |
| `prisma db push`        | 直接同步 schema        | 快速原型 |

---

## ✅ 总结

**Prisma 迁移机制的核心特点**：

1. ✅ **自动增量执行**：只执行未应用的迁移
2. ✅ **状态跟踪**：通过 `_prisma_migrations` 表跟踪
3. ✅ **安全可靠**：不会重复执行已应用的迁移
4. ✅ **环境区分**：`migrate deploy` 用于生产，`migrate dev` 用于开发

**最佳实践**：

- 🎯 生产环境：使用 `prisma migrate deploy`
- 🎯 开发环境：使用 `prisma migrate dev`
- 🎯 定期检查：使用 `prisma migrate status` 查看状态
- 🎯 版本控制：提交所有迁移文件到 Git

---

## 🔗 相关文档

- [Prisma 官方迁移文档](https://www.prisma.io/docs/concepts/components/prisma-migrate)
- [SCHEMA_CHANGE_GUIDE.md](./SCHEMA_CHANGE_GUIDE.md) - Schema 修改指南
- [DATABASE_SETUP.md](./DATABASE_SETUP.md) - 数据库设置指南
