Prisma 和 Drizzle 对比

9月 24, 2025
ByAI, Frontend, Database, ORM

Prisma 和 Drizzle 确实是同类工具,它们都属于 现代 TypeScript/JavaScript ORM(对象关系映射),但在设计哲学、功能特性和使用方式上有显著差异。

核心定位对比#

特性PrismaDrizzle
类型安全🔥 强类型,自动生成 TypeScript 类型🔥 强类型,基于 TypeScript 推断
查询语法声明式,类 GraphQL 风格类 SQL 的表达式语法
架构定义专属的 .prisma schema 文件TypeScript 代码定义或配置文件
迁移管理内置完整的迁移系统支持迁移,但更灵活
运行时大小较大(~1.5MB)轻量(~20KB)
学习曲线中等,需要学习 Prisma 特有语法较低,对 SQL 用户友好

代码示例对比#

1. 架构定义#

Prisma Schema:

// schema.prisma
model User {
  id        Int      @id @default(autoincrement())
  email     String   @unique
  name      String?
  posts     Post[]
  createdAt DateTime @default(now())
}

model Post {
  id        Int      @id @default(autoincrement())
  title     String
  content   String?
  published Boolean  @default(false)
  author    User     @relation(fields: [authorId], references: [id])
  authorId  Int
}

Drizzle Schema:

// schema.ts
import { pgTable, serial, varchar, boolean, integer, timestamp } from 'drizzle-orm/pg-core';

export const users = pgTable('users', {
  id: serial('id').primaryKey(),
  email: varchar('email', { length: 255 }).unique().notNull(),
  name: varchar('name', { length: 255 }),
  createdAt: timestamp('created_at').defaultNow(),
});

export const posts = pgTable('posts', {
  id: serial('id').primaryKey(),
  title: varchar('title', { length: 255 }).notNull(),
  content: varchar('content', { length: 1000 }),
  published: boolean('published').default(false),
  authorId: integer('author_id').references(() => users.id),
});

2. 查询语法对比#

Prisma 查询:

// 声明式,类似 GraphQL
const userWithPosts = await prisma.user.findUnique({
  where: { email: 'user@example.com' },
  include: {
    posts: {
      where: { published: true },
      select: { title: true, createdAt: true }
    }
  }
});

Drizzle 查询:

// 类 SQL 的表达式语法
import { eq, and, desc } from 'drizzle-orm';

const userWithPosts = await db
  .select({
    user: users,
    posts: {
      title: posts.title,
      createdAt: posts.createdAt
    }
  })
  .from(users)
  .leftJoin(posts, eq(users.id, posts.authorId))
  .where(
    and(
      eq(users.email, 'user@example.com'),
      eq(posts.published, true)
    )
  )
  .orderBy(desc(posts.createdAt));

主要差异深度分析#

1. 设计哲学#

  • Prisma: “数据库客户端”,提供高层抽象,隐藏 SQL 细节
  • Drizzle: “类型安全的 SQL 查询构建器”,更接近原生 SQL

2. 类型安全实现#

  • Prisma: 通过代码生成器自动生成完整的 TypeScript 类型
  • Drizzle: 利用 TypeScript 的泛型和类型推断,无代码生成

3. 关系处理#

// Prisma - 自动处理关系
await prisma.user.create({
  data: {
    email: 'test@example.com',
    posts: {
      create: [
        { title: 'Post 1', content: '...' },
        { title: 'Post 2', content: '...' }
      ]
    }
  }
});

// Drizzle - 需要显式处理关系(事务)
await db.transaction(async (tx) => {
  const [user] = await tx.insert(users).values({
    email: 'test@example.com'
  }).returning();

  await tx.insert(posts).values([
    { title: 'Post 1', authorId: user.id },
    { title: 'Post 2', authorId: user.id }
  ]);
});

选择建议#

选择 Prisma 的情况:#

  • ✅ 团队偏好声明式 API
  • ✅ 需要完整的迁移管理系统
  • ✅ 项目复杂度高,需要强大的关系处理
  • ✅ 与非技术成员协作(Prisma Studio 很友好)

选择 Drizzle 的情况:#

  • ✅ 团队熟悉 SQL,希望更直接的掌控力
  • ✅ 对包大小敏感(边缘计算、Serverless)
  • ✅ 需要高度定制化的查询优化
  • ✅ 偏好零代码生成的开发体验

性能考虑:#

// Drizzle 在复杂查询中通常有更好性能
const analytics = await db
  .select({
    userId: users.id,
    postCount: sql<number>`count(${posts.id})`,
    lastPost: sql<string>`max(${posts.createdAt})`
  })
  .from(users)
  .leftJoin(posts, eq(users.id, posts.authorId))
  .groupBy(users.id)
  .having(gt(sql`count(${posts.id})`, 5));

实际项目配置示例#

Prisma 项目设置:#

// prisma/client.ts
import { PrismaClient } from '@prisma/client';

const globalForPrisma = globalThis as unknown as {
  prisma: PrismaClient | undefined;
};

export const prisma = globalForPrisma.prisma ?? new PrismaClient();

if (process.env.NODE_ENV !== 'production') {
  globalForPrisma.prisma = prisma;
}

Drizzle 项目设置:#

// lib/db.ts
import { drizzle } from 'drizzle-orm/node-postgres';
import { Pool } from 'pg';

const pool = new Pool({
  connectionString: process.env.DATABASE_URL!
});

export const db = drizzle(pool, { schema });

// 类型导出用于前端
export type * from './schema';

总结#

Prisma 和 Drizzle 都是优秀的现代 ORM,但它们面向不同的使用场景和开发者偏好:

  • Prisma 更适合追求开发效率、需要完整解决方案的团队
  • Drizzle 更适合追求性能、控制力和轻量级的场景

两者都在快速发展中,选择时建议考虑团队的技术栈偏好、性能需求和长期维护成本。

本文共 1099 字,上次修改于 Sep 25, 2025,以 CC 署名-非商业性使用-禁止演绎 4.0 国际 协议进行许可。

相关文章

» Cookie 机制

» JWT 介绍和场景示例

» 零宽度空格与 CSS 换行行为

» 理解和使用 CSS 自定义属性(CSS 变量)

» 了解下自定义数据属性 data-*