Drizzle ORM:TypeScript 生态中冉冉升起的数据库工具链引言

一、什么是 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 几乎一一映射:

TypeScript 复制代码
// 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 能自动推导出关联数据的嵌套类型。来看一个直观对比:

TypeScript 复制代码
// 定义关系
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 的抽象层更友好)。


四、具体使用方式

环境准备

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

第一步:定义 Schema

创建 src/db/schema.ts:

TypeScript 复制代码
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 中追加:

TypeScript 复制代码
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:

TypeScript 复制代码
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 });

第四步:执行迁移

bash 复制代码
# 生成迁移文件
npx drizzle-kit generate

# 执行迁移
npx drizzle-kit push

第五步:编写业务代码

TypeScript 复制代码
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 可视化

bash 复制代码
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"的流畅感,试过就很难回去了。

相关推荐
ECT-OS-JiuHuaShan2 小时前
什么是对和错?——“有针对性定义域的逻辑值的真伪”:认识论终极追问的公理化裁决
数据库·人工智能·算法·机器学习·数学建模
旺王雪饼 www2 小时前
localStorage 和 sessionStorage区别与联系
服务器·前端·javascript
乐维_lwops2 小时前
多类型数据库如何高效监控?
数据库·数据库监控·运维监控
齐潇宇2 小时前
Redis数据库基础
linux·数据库·redis·缓存
এ慕ོ冬℘゜2 小时前
【双月日期范围选择器】博客(可直接交作业 / 上线)
前端·javascript·交互·jquery
VidDown3 小时前
VidDown 使用介绍:一个免费、本地化的在线工具集
javascript·编辑器·音视频·视频编解码·视频
三更两点3 小时前
AI拉呱-技术洞察 - 2026-06-01
数据库·人工智能·技术洞察
程序边界3 小时前
KES查询优化与运维实战:从表空间到SQL内核那些让DBA少加班的事
数据库
Lyyaoo.3 小时前
【MySQL】存储引擎
数据库·mysql