一、什么是 Drizzle ORM

Drizzle ORM 是一个面向 TypeScript 的轻量级数据库工具链,它同时具备:

  • Schema 定义能力——用纯 TypeScript 声明表结构
  • Query Builder——链式 API 构建 SQL 查询
  • Migration 工具——基于 Schema 差异自动生成迁移文件
  • 类型安全贯穿全链路——从 Schema 定义到查询结果,TypeScript 编译器全程保驾护航

与 Prisma 的自定义 Schema 语言(.prisma 文件)不同,Drizzle 回归了"一切皆 TypeScript 代码"的理念,开发者无需学习额外的 DSL,也无需引入代码生成步骤。


二、核心优点

1. 零代码生成,极致编译速度

Prisma 需要 prisma generate 将 Schema 编译为客户端代码,项目越大耗时越长。Drizzle 完全跳过这一步——Schema 本身就是 TypeScript 代码,类型推导由 TypeScript 编译器原生完成,无需中间层。

2. SQL 优先,不隐藏底层

Drizzle 的查询 API 与原生 SQL 几乎一一映射:

// Drizzle 查询
db.select().from(users).where(eq(users.email, "test@example.com"));

// 对应的 SQL
// SELECT * FROM users WHERE email = 'test@example.com';

对于熟悉 SQL 的开发者,几乎没有心智负担。遇到复杂查询时,还可以直接嵌入原生 SQL 片段,不会被 ORM 的抽象层束缚。

3. 运行时极致轻量

Drizzle 的核心包体积极小(gzip 后约 7KB),冷启动几乎不增加额外延迟。相比之下,Prisma Client 动辄数 MB 的运行时在 Serverless 环境下可能成为性能瓶颈。

4. 多数据库统一接口

Drizzle 支持 PostgreSQL、MySQL、SQLite、PlanetScale、Neon、Turso、Cloudflare D1 等主流数据库,切换数据库只需更换对应的驱动适配器,Schema 和查询语法保持一致。

5. 关系查询的类型推导

Drizzle 的 relations API 能自动推导出关联数据的嵌套类型。来看一个直观对比:

// 定义关系
const usersRelations = relations(users, ({ many }) => ({
  posts: many(posts),
}));

// 查询用户及其所有文章——结果类型自动推导为 { id, name, posts: Post[] }
const result = await db.query.users.findMany({
  with: { posts: true },
});
// result[0].posts 的类型自动推导,无需手动声明

6. Drizzle Kit:可视化的数据库管理

Drizzle Kit 是配套的 CLI 工具,提供:

  • Introspect:从已有数据库反向生成 TypeScript Schema
  • Generate:对比 Schema 变更自动生成 SQL 迁移文件
  • Push:直接将 Schema 变更应用到数据库(适合开发阶段快速迭代)
  • Studio:内置的数据库可视化管理面板(npx drizzle-kit studio)

三、适用场景

场景 说明
Serverless 应用 轻量运行时不拖累冷启动,适配 Cloudflare Workers / AWS Lambda 等
边缘计算 原生支持 Cloudflare D1、Turso 等边缘数据库
类型敏感型项目 追求全链路类型安全,希望编译期拦截 SQL 错误
SQL 经验丰富的团队 不想被 ORM 屏蔽 SQL 细节,需要灵活拼接复杂查询
微服务 / 中小型项目 Schema 不复杂但需要高效率开发,讨厌代码生成环节
已有数据库的项目 通过 Introspect 反向生成 Schema,渐进式引入

暂不适合的场景:团队完全不懂 SQL、需要 ORM 完全隐藏数据库细节(此时 Prisma 的抽象层更友好)。


四、具体使用方式

环境准备

# 初始化项目
npm init -y
npm install drizzle-orm better-sqlite3
npm install -D drizzle-kit @types/better-sqlite3

第一步:定义 Schema

创建 src/db/schema.ts:

import { sqliteTable, text, integer } from "drizzle-orm/sqlite-core";

export const users = sqliteTable("users", {
  id: integer("id").primaryKey({ autoIncrement: true }),
  name: text("name").notNull(),
  email: text("email").notNull().unique(),
  createdAt: integer("created_at", { mode: "timestamp" })
    .notNull()
    .default(sql`(unixepoch())`),
});

export const posts = sqliteTable("posts", {
  id: integer("id").primaryKey({ autoIncrement: true }),
  title: text("title").notNull(),
  content: text("content").notNull(),
  authorId: integer("author_id")
    .notNull()
    .references(() => users.id),
  publishedAt: integer("published_at", { mode: "timestamp" }),
});

第二步:定义关系(可选但推荐)

在 src/db/schema.ts 中追加:

import { relations, sql } from "drizzle-orm";

export const usersRelations = relations(users, ({ many }) => ({
  posts: many(posts),
}));

export const postsRelations = relations(posts, ({ one }) => ({
  author: one(users, {
    fields: [posts.authorId],
    references: [users.id],
  }),
}));

第三步:初始化数据库连接

创建 src/db/index.ts:

import { drizzle } from "drizzle-orm/better-sqlite3";
import Database from "better-sqlite3";
import * as schema from "./schema";

const sqlite = new Database("local.db");
export const db = drizzle(sqlite, { schema });

第四步:执行迁移

# 生成迁移文件
npx drizzle-kit generate

# 执行迁移
npx drizzle-kit push

第五步:编写业务代码

import { db } from "./db";
import { users, posts } from "./db/schema";
import { eq, and, like, desc } from "drizzle-orm";

// 插入用户
const [newUser] = await db.insert(users).values({
  name: "张三",
  email: "zhangsan@example.com",
}).returning();

// 查询(全链路类型推导)
const allUsers = await db.select().from(users);

// 条件查询
const matched = await db.select()
  .from(users)
  .where(like(users.name, "%张%"));

// 联表查询(利用 relations)
const usersWithPosts = await db.query.users.findMany({
  with: { posts: true },
  where: eq(users.name, "张三"),
});
// usersWithPosts[0].posts 类型自动推导为 Post[]

// 更新
await db.update(users)
  .set({ name: "张三丰" })
  .where(eq(users.id, newUser.id));

// 删除
await db.delete(posts).where(eq(posts.id, 1));

第六步:使用 Drizzle Studio 可视化

npx drizzle-kit studio

浏览器打开 https://local.drizzle.studio,即可在图形界面中浏览和编辑数据。


五、与主流方案对比

维度 Drizzle ORM Prisma TypeORM Knex
Schema 定义 TypeScript 原生 自定义 DSL 装饰器/代码 无 Schema 层
代码生成 不需要 需要 需要 不需要
类型安全 全链路 强(生成后) 中等
SQL 控制力 极高 极高
运行时体积 ~7KB ~5MB+ ~1MB ~200KB
学习曲线 平缓(懂 SQL 即上手) 需要学 DSL 陡峭 平缓
Edge Runtime 原生支持 部分支持 不支持 支持

六、总结

Drizzle ORM 的出现改变了 TypeScript 数据库工具链的格局。它在"类型安全"与"贴近 SQL"之间找到了精准的平衡点:不像 Prisma 那样试图用抽象层包裹一切,也不像 Knex 那样完全放弃类型推导。

对于追求轻量、极速、类型安全且对 SQL 有基本掌握的团队,Drizzle ORM 是一个值得在生产环境投入的选择。它的生态仍在快速演进中——Drizzle Kit Studio、Seeding 工具、Zod Schema 联动等周边能力正持续完善。

如果你正在新建一个 TypeScript 后端项目,不妨给它 30 分钟尝试一次 drizzle-kit introspect 或从零建一个 Schema——那种"写 TypeScript 就是写 Schema"的流畅感,试过就很难回去了。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐