← [ BACK_TO_NOTES ]

Drizzle Schema、Relations 与 Migrations 的关系

把 Drizzle 中 TypeScript Schema、数据库约束、Relations 查询声明与 Drizzle Kit Migration 放在同一张图里,区分“代码关系”“数据库约束”“历史演进”三个层次。

#synthesis #growing #backend #database #typescript

[!info] related notes

Drizzle Schema、Relations 与 Migrations 的关系

为什么这三个概念必须分开

Drizzle 项目里常见三类“看起来都在描述关系”的东西:

TypeScript Schema
→ 当前代码认为表和列长什么样

Database Constraints
→ 数据库真正强制执行的合法状态

Relations
→ ORM 查询层如何方便地导航关联数据

Migration History
→ 数据库怎样从旧结构一步步演进到当前结构

它们相关,但不是同一个东西。

Schema:当前结构声明

export const posts = pgTable('posts', {
  id: serial('id').primaryKey(),
  authorId: integer('author_id')
    .notNull()
    .references(() => users.id),
})

Schema 让 TypeScript 查询获得类型信息,也可作为 Drizzle Kit 生成 migration 的输入。

但代码里的类型不会自动修复线上数据库;真正数据库结构必须通过 migration 等方式同步。

Foreign Key:数据库完整性

posts.author_id
→ references users.id

FK 是数据库层约束,负责阻止非法引用。

它解决:

这条引用在 durable state 中是否合法?

而不是:

ORM 查询时如何方便展开 post.author?

Relations:查询层导航

Drizzle Relations 用来声明实体之间的查询关系,使 relational query API 可以表达嵌套读取。

Foreign Key
→ database integrity

Drizzle Relation
→ query/navigation convenience

不能因为声明了 ORM relation,就认为数据库一定存在对应 FK;反过来也不能认为有 FK 就自动拥有所有 ORM 关系查询定义。

Migration:历史演进,而不是“当前 Schema 的复制品”

典型流程:

修改 schema.ts
      ↓
drizzle-kit generate
      ↓
生成 versioned SQL migration
      ↓
review SQL
      ↓
drizzle-kit migrate / deployment migration step
      ↓
Database schema changes

Migration 文件的价值是保存演进历史:

v1 → v2 → v3 → ... → current

因此 migration 不应被当作“随时根据当前 schema 重算即可”的临时产物。

为什么生产环境不要只依赖 push

开发环境中直接同步 schema 很方便,但生产环境更需要:

  • 可审查 SQL
  • 明确执行顺序
  • 可追踪版本
  • 数据回填步骤
  • expand-and-contract 兼容窗口

所以稳定发布通常更偏向 versioned migration,而不是把当前代码结构直接强推到生产数据库。

Relation Query 与 JOIN

例如要读用户及其文章:

users
  ↓ relation
posts

ORM 可以提供嵌套 API,但底层仍可能生成 JOIN 或多查询策略。

真正需要关注:

  • SQL 形状
  • query count
  • projection 宽度
  • N+1
  • index

因此:

漂亮的 nested object
≠ 自动高效 SQL

一张统一图

Domain requirement
      ↓
Table / Column / Constraint design
      ↓
Drizzle TypeScript Schema
      ├─→ typed query API
      ├─→ Relations declaration
      └─→ Drizzle Kit diff
                ↓
         Versioned Migration
                ↓
         Real Database Schema
                ↓
         Runtime Query / JOIN

最短记忆

Schema = current structure in code
Constraint = database-enforced invariant
Relation = ORM query navigation
Migration = structure history

Relation ≠ Foreign Key
Schema type ≠ DB constraint
Current schema ≠ migration history

这四层分开后,Drizzle 就不会变成“又一个神秘 ORM”,而只是把既有数据库概念映射到 TypeScript 工具链。

创建于 2026/9/16 更新于 2026/9/16
Digital Biome
Access

键盘导航

j / k / ↑ / ↓
选择对象
Enter / o
打开选择
/ 或 Ctrl+K
全站搜索
i / f / 1–4
筛选当前列表
g → h / l / p / t / a
首页 / 笔记 / 项目 / 工具 / About
r → 1–9
打开所选对象的关联
u
返回上一页
Esc
关闭浮层 / 取消命令;输入框内清空文本