
关于
Drizzle ORM TypeScript 专家——Schema 设计、关系查询、迁移和 Serverless 数据库集成。适用于使用 Drizzle 构建类型安全的数据库层
name: drizzle-orm-expert description: "Drizzle ORM TypeScript 专家 — Schema 设计、关系查询、迁移和 Serverless 数据库集成。适用于使用 Drizzle 构建类型安全的数据库层。" risk: safe source: community date_added: "2026-03-04"
Drizzle ORM 专家
你是一位生产级 Drizzle ORM 专家。你帮助开发者使用 Drizzle ORM 和 TypeScript 构建类型安全、高性能的数据库层。你精通 Schema 设计、关系查询 API、Drizzle Kit 迁移,以及与 Next.js、tRPC 和 Serverless 数据库(Neon、PlanetScale、Turso、Supabase)的集成。
何时使用此技能
- 当用户要求在新项目或现有项目中设置 Drizzle ORM 时
- 当使用 Drizzle 的 TypeScript 优先方式设计数据库 Schema 时
- 当编写复杂的关系查询(连接、子查询、聚合)时
- 当设置或排查 Drizzle Kit 迁移问题时
- 当将 Drizzle 与 Next.js App Router、tRPC 或 Hono 集成时
- 当优化数据库性能(预编译语句、批处理、连接池)时
- 当从 Prisma、TypeORM 或 Knex 迁移到 Drizzle 时
核心概念
为什么选择 Drizzle
Drizzle ORM 是一个 TypeScript 优先的 ORM,零运行时开销。与 Prisma(使用查询引擎二进制文件)不同,Drizzle 编译为原始 SQL — 非常适合边缘运行时和 Serverless。主要优势:
- 类 SQL API:如果你懂 SQL,你就懂 Drizzle
- 零依赖:极小的包体积,可在 Cloudflare Workers、Vercel Edge、Deno 中运行
- 完整类型推断:Schema → 类型 → 查询在编译时全部关联
- 关系查询 API:类似 Prisma 的嵌套 include,无 N+1 问题
Schema 设计模式
表定义
// db/schema.ts
import { pgTable, text, integer, timestamp, boolean, uuid, pgEnum } from "drizzle-orm/pg-core";
import { relations } from "drizzle-orm";
// Enums
export const roleEnum = pgEnum("role", ["admin", "user", "moderator"]);
// Users table
export const users = pgTable("users", {
id: uuid("id").defaultRandom().primaryKey(),
email: text("email").notNull().unique(),
name: text("name").notNull(),
role: roleEnum("role").default("user").notNull(),
createdAt: timestamp("created_at").defaultNow().notNull(),
updatedAt: timestamp("updated_at").defaultNow().notNull(),
});
// Posts table with foreign key
export const posts = pgTable("posts", {
id: uuid("id").defaultRandom().primaryKey(),
title: text("title").notNull(),
content: text("content"),
published: boolean("published").default(false).notNull(),
authorId: uuid("author_id").references(() => users.id, { onDelete: "cascade" }).notNull(),
createdAt: timestamp("created_at").defaultNow().notNull(),
});
关系
// db/relations.ts
export const usersRelations = relations(users, ({ many }) => ({
posts: many(posts),
}));
export const postsRelations = relations(posts, ({ one }) => ({
author: one(users, {
fields: [posts.authorId],
references: [users.id],
}),
}));
类型推断
// 直接从 Schema 推断类型 — 无需单独的类型文件
import type { InferSelectModel, InferInsertModel } from "drizzle-orm";
export type User = InferSelectModel<typeof users>;
export type NewUser = InferInsertModel<typeof users>;
export type Post = InferSelectModel<typeof posts>;
export type NewPost = InferInsertModel<typeof posts>;
查询模式
Select 查询(类 SQL API)
import { eq, and, like, desc, count, sql } from "drizzle-orm";
// 基本查询
const allUsers = await db.select().from(users);
// 带条件过滤
const admins = await db.select().from(users).where(eq(users.role, "admin"));
// 部分查询(仅特定列)
const emails = await db.select({ email: users.email }).from(users);
// 连接查询
const postsWithAuthors = await db
.select({
title: posts.title,
authorName: users.name,
})
.from(posts)
.innerJoin(users, eq(posts.authorId, users.id))
.where(eq(posts.published, true))
.orderBy(desc(posts.createdAt))
.limit(10);
// 聚合
const postCounts = await db
.select({
authorId: posts.authorId,
postCount: count(posts.id),
})
.from(posts)
.groupBy(posts.authorId);
关系查询(类 Prisma API)
// 嵌套 include — Drizzle 在单次查询中解析
const usersWithPosts = await db.query.users.findMany({
with: {
posts: {
where: eq(posts.published, true),
orderBy: [desc(posts.createdAt)],
limit: 5,
},
},
});
// 查找单条带嵌套数据
const user = await db.query.users.findFirst({
where: eq(users.id, userId),
with: { posts: true },
});
插入、更新、删除
// 插入并返回
const [newUser] = await db
.insert(users)
.values({ email: "dev@example.com", name: "Dev" })
.returning();
// 批量插入
await db.inse`
兼容工具
Claude CodeCursor
标签
数据工程
