# Db Review

> >

- **Type:** Skill
- **Install:** `agentstack add skill-312362115-claude-db-review`
- **Verified:** Pending review
- **Seller:** [312362115](https://agentstack.voostack.com/s/312362115)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [312362115](https://github.com/312362115)
- **Source:** https://github.com/312362115/claude/tree/main/skills/db-review

## Install

```sh
agentstack add skill-312362115-claude-db-review
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# 数据库审查（DB Review）

> 数据库问题的修复成本随阶段指数增长：代码审查  尽早发现，尽早修复。

---

## 第一步：确定审查范围和模式

```
收到审查请求
  │
  ├─ 代码审查模式（改了数据库相关代码）
  │   └─ 检查 SQL 质量 + 查询性能 + 锁风险
  │
  ├─ Migration 审查模式（新增/修改 migration 文件）
  │   └─ 检查安全性 + Schema 漂移 + 回滚方案
  │
  └─ 全量审查（上线前 / 用户主动要求）
      └─ 代码审查 + Migration 审查 + Schema 一致性
```

### 技术栈识别

自动检测项目使用的数据库和 ORM：

| 检测目标 | 检测方式 |
|---------|---------|
| Prisma | `prisma/schema.prisma`、`@prisma/client` |
| TypeORM | `typeorm` 依赖、`@Entity()` 装饰器 |
| Sequelize | `sequelize` 依赖、`.define()` 调用 |
| Drizzle | `drizzle-orm` 依赖、`drizzle.config.ts` |
| SQLAlchemy | `sqlalchemy` 依赖、`Base.metadata` |
| 原生 SQL | `.sql` 文件、`query()` / `execute()` 调用 |
| 数据库类型 | 连接字符串、驱动依赖（`pg`/`mysql2`/`better-sqlite3`） |

---

## 第二步：代码审查 — SQL 质量与性能

### 检查维度 1：慢 SQL 模式

**逐条检查以下反模式**，对每个发现标注风险等级：

| 反模式 | 问题 | 正确做法 |
|--------|------|---------|
| `SELECT *` | 取了不需要的列，浪费 IO 和内存 | 明确列出需要的字段 |
| 无 WHERE 的全表查询 | 数据量大时直接拖垮 DB | 加条件过滤，分页查询 |
| WHERE 中对列使用函数 | `WHERE YEAR(created_at) = 2026` 无法走索引 | 改为范围查询 `WHERE created_at >= '2026-01-01'` |
| `LIKE '%keyword%'` | 前缀通配符无法走索引 | 考虑全文索引或搜索引擎 |
| `OR` 条件跨列 | 优化器难以使用索引 | 拆成 UNION 或调整索引策略 |
| 子查询在 WHERE 中 | `WHERE id IN (SELECT ...)` 可能逐行执行 | 改为 JOIN |
| `ORDER BY` 无索引支撑 | 大表排序触发 filesort | 确保排序字段有索引 |
| `DISTINCT` 掩盖重复 | 通常是 JOIN 写错的信号 | 检查 JOIN 条件是否正确 |

**审查方法**：
1. 搜索所有 SQL 语句（原生查询、ORM 的 raw query、query builder）
2. 对每条 SQL 判断是否命中上述反模式
3. ORM 调用也要检查——`findAll()` 没加条件等价于 `SELECT *` 全表扫描

### 检查维度 2：N+1 查询

**这是 ORM 项目最常见的性能杀手。**

```
# 反模式：循环中查询
users = User.findAll()
for user in users:
    orders = Order.findAll({ where: { userId: user.id } })  # N 次查询

# 正确：预加载/JOIN
users = User.findAll({ include: [Order] })  # 1 次查询
```

**检查方法**：
1. 搜索循环体内的数据库调用（`for`/`forEach`/`map` 中的 `find`/`query`/`select`）
2. 检查 ORM 的关联查询是否使用了 eager loading（`include`/`joinedload`/`with`）
3. 检查 GraphQL resolver 中的数据加载是否使用了 DataLoader

### 检查维度 3：锁表风险

**以下操作在大表上可能导致长时间锁表**：

| 操作 | MySQL 风险 | PostgreSQL 风险 | 安全替代 |
|------|-----------|----------------|---------|
| `ALTER TABLE ADD COLUMN` (有默认值) | 锁表重写（MySQL 10 万行）的 DDL 操作标记为**高风险**

### 检查维度 4：索引审查

| 检查项 | 问题信号 |
|--------|---------|
| 缺失索引 | WHERE/JOIN/ORDER BY 中的列没有索引 |
| 冗余索引 | `INDEX(a)` 和 `INDEX(a, b)` 并存（前者被后者包含） |
| 过多索引 | 单表 >6 个索引，影响写入性能 |
| 索引列顺序 | 复合索引列顺序不符合查询模式（最左前缀原则） |
| 低选择性索引 | 在布尔/状态等低基数列上建索引（通常无效） |
| 未使用索引 | 有索引但查询没走到（函数包裹、类型不匹配） |

**审查方法**：
1. 读取 schema/migration 中的索引定义
2. 对照查询语句的 WHERE/JOIN/ORDER BY 检查索引覆盖
3. ORM 的 `@Index()`/`index: true` 也要检查

### 检查维度 5：事务与并发

| 检查项 | 关注点 |
|--------|--------|
| 事务范围 | 事务是否过大？包含了不必要的操作？ |
| 死锁风险 | 多个事务是否以不同顺序操作同一组表？ |
| 隔离级别 | 是否使用了过高的隔离级别（SERIALIZABLE）？ |
| 连接泄漏 | 事务/连接是否在异常路径中正确释放？ |
| 乐观锁 | 并发更新场景是否有版本号/乐观锁保护？ |

---

## 第三步：Migration 审查 — 安全性与一致性

### 3.1 破坏性操作检查

**以下操作不可逆或有数据丢失风险**，必须标记为高风险：

| 操作 | 风险 | 安全做法 |
|------|------|---------|
| `DROP TABLE` | 数据永久丢失 | 先备份、确认无引用、保留回滚窗口 |
| `DROP COLUMN` | 列数据丢失 | 确认代码已移除引用后再删列 |
| `RENAME TABLE/COLUMN` | 代码引用断裂 | 分步：新建 → 同步 → 切换 → 清理旧的 |
| `TRUNCATE` | 数据清空 | 不应出现在 migration 中 |
| `ALTER COLUMN` 收窄类型 | 数据截断 | 先检查现有数据是否溢出 |
| `NOT NULL` 约束（已有数据列） | 空值行报错 | 先填充默认值再加约束 |

**审查方法**：
1. 逐行读 migration 文件，标记所有 DROP/RENAME/ALTER 操作
2. 每个破坏性操作必须有对应的**回滚方案**（down migration）
3. 检查 down migration 是否真的能回滚（不是空函数）

### 3.2 Schema 漂移检测

> **这是你反复踩坑的问题：本地和服务端 schema 不一致、缺字段。**

**漂移来源**：

```
1. 手动改了数据库但没写 migration（最常见）
2. migration 执行顺序不一致（分支合并后）
3. migration 只跑了一半（报错后手动修了但没记录）
4. ORM 的 model 定义和 migration 不同步
5. 多人开发时 migration 文件冲突
```

**检查流程**：

```
Step 1: 收集当前 Schema 定义来源
  ├─ ORM model/entity 定义（代码中的"应该是什么"）
  ├─ Migration 文件链（"变更历史"）
  └─ 数据库实际状态（如果能连接）

Step 2: 交叉比对
  ├─ Model vs Migration：model 里的字段/类型/约束是否都有对应的 migration？
  ├─ Migration 完整性：migration 链是否连续？有没有遗漏？
  └─ 新增字段检查：最近加的字段有 migration 吗？默认值/可空设置对吗？

Step 3: 输出不一致清单
  每条记录：字段名、model 中的定义、migration 中的定义、差异描述
```

**具体检查项**：

| 检查项 | 方法 |
|--------|------|
| **Model 和 Migration 字段一致** | 遍历 model 所有字段，确认每个字段在 migration 链中有对应的 CREATE/ALTER |
| **类型一致** | model 中的类型（`String`/`Int`/`DateTime`）和 migration 中的 SQL 类型匹配 |
| **可空性一致** | model 标记 `optional`/`nullable` 的字段，migration 中没加 `NOT NULL` |
| **默认值一致** | model 中有 `@default()` 的字段，migration 中有 `DEFAULT` |
| **索引一致** | model 中 `@index`/`@unique` 的字段，migration 中有对应的 INDEX |
| **关联关系一致** | model 中的外键关系，migration 中有对应的 FOREIGN KEY |
| **migration 时间线连续** | 按时间戳排序，检查有没有跳跃或冲突 |

### 3.3 回滚方案检查

每个 migration 必须有可执行的回滚方案：

| 检查项 | 要求 |
|--------|------|
| down/rollback 函数存在 | 不能是空函数或 `throw new Error('not implemented')` |
| down 函数逻辑正确 | `up` 中加的列，`down` 中要删；`up` 中改的类型，`down` 中要改回 |
| 数据恢复 | 破坏性操作的 down 需要说明数据恢复策略（即使无法完全自动恢复） |

### 3.4 Migration 最佳实践

| 实践 | 要求 |
|------|------|
| 单一职责 | 一个 migration 只做一件事（加表、加列、加索引分开） |
| 可重复执行 | migration 应该幂等，重复运行不报错（`IF NOT EXISTS`） |
| 数据迁移分离 | schema 变更和数据填充放在不同的 migration 中 |
| 命名规范 | 文件名能反映操作内容（`add_email_to_users` 而非 `migration_042`） |

---

## 第四步：风险分级与输出

### 风险等级

| 等级 | 标准 | 处理要求 |
|------|------|---------|
| **高危** | 数据丢失、锁表超 30s、schema 漂移（已知不一致）、无回滚方案 | **必须修复**，给出具体方案 |
| **中危** | 性能隐患（N+1、缺索引）、回滚方案不完整、潜在的并发问题 | **建议修复**，给出方向 |
| **低危** | 最佳实践缺失（命名、注释、冗余索引）、小表操作 | **记录**，不阻断 |

### 输出格式

**快速审查**（终端输出）：

```
## DB Review 结果

🔴 高危 x N | 🟡 中危 x N | 🟢 低危 x N

### 高危
1. [锁表风险] migrations/20260409_add_index.sql:15 — 大表加索引未用 CONCURRENTLY
   → 修复：`CREATE INDEX CONCURRENTLY idx_users_email ON users(email);`

### 中危
1. [N+1] src/services/order.ts:42 — 循环内查询用户信息
   → 修复：使用 include/joinedload 预加载

### Schema 漂移
- ⚠️ User.phone: model 中存在(String, optional)，但无对应 migration
- ⚠️ Order.discount: model 类型 Decimal，migration 中为 Float
```

**完整审查**时，生成报告到 `docs/audits/YYYY-MM-DD-db-review.md`。

---

## 与其他 skill 的衔接

```
代码开发中
  │
  ├─ 改了数据库代码？→ task-finish 自检时提示跑 db-review（代码审查模式）
  ├─ 新增 migration？→ 提交前跑 db-review（migration 审查模式）
  │
  ↓ 上线前
  ├─ security-audit 审查注入防护（SQL 注入维度）
  └─ db-review 全量审查（Schema 漂移 + 锁表 + 性能）
```

- **perf-profiling**：发现 DB 慢查询后，交给 db-review 做 SQL 层面的深度分析
- **security-audit**：SQL 注入是安全问题，由 security-audit 负责；查询性能是 db-review 负责
- **task-finish**：改动涉及 migration 文件时，提示跑 db-review

---

## 注意事项

- **先理解业务再审查**：脱离业务的索引建议是无意义的。先搞清楚查询频率和数据量
- **小表不教条**：几百行的配置表不需要纠结索引优化
- **ORM 不是借口**：ORM 生成的 SQL 也可能很烂，必要时看生成的实际 SQL
- **环境差异**：本地 SQLite + 生产 PostgreSQL 时，migration 语法差异是漂移的常见来源
- **不替代 DBA**：复杂的分库分表、主从延迟等架构级问题需要 DBA 介入

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [312362115](https://github.com/312362115)
- **Source:** [312362115/claude](https://github.com/312362115/claude)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: flagged — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-312362115-claude-db-review
- Seller: https://agentstack.voostack.com/s/312362115
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
