読み込み中...
TypeScript ORMの選択は、プロジェクトの開発効率とパフォーマンスに大きく影響します。本記事では、2025年時点で最も人気のあるDrizzle ORMとPrismaを、実際の使用例を交えながら徹底比較します。
| 項目 | Drizzle ORM | Prisma |
|---|---|---|
| 初回リリース | 2022年 | 2019年 |
| GitHub Stars | 18,000+ | 36,000+ |
| 型安全性 | 完全 | 完全 |
| パフォーマンス | 非常に高速 | 中程度 |
| 学習曲線 | 緩やか(SQLライク) | 中程度 |
| マイグレーション | SQLベース | 宣言的スキーマ |
| エッジランタイム対応 | ✅ | 一部制限あり |
npm install drizzle-orm pg
npm install -D drizzle-kit @types/pgスキーマ定義:
// db/schema.ts
import { pgTable, uuid, text, timestamp, integer } from 'drizzle-orm/pg-core'
export const users = pgTable('users', {
id: uuid('id').primaryKey().defaultRandom(),
name: text('name').notNull(),
email: text('email').notNull().unique(),
age: integer('age'),
createdAt: timestamp('created_at').defaultNow(),
})
export const posts = pgTable('posts', {
id: uuid('id').primaryKey().defaultRandom(),
title: text('title').notNull(),
content: text('content'),
authorId: uuid('author_id').references(() => users.id),
createdAt: timestamp('created_at').defaultNow(),
})npm install @prisma/client
npm install -D prisma
npx prisma initスキーマ定義:
// prisma/schema.prisma
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
generator client {
provider = "prisma-client-js"
}
model User {
id String @id @default(uuid())
name String
email String @unique
age Int?
createdAt DateTime @default(now()) @map("created_at")
posts Post[]
@@map("users")
}
model Post {
id String @id @default(uuid())
title String
content String?
authorId String @map("author_id")
author User @relation(fields: [authorId], references: [id])
createdAt DateTime @default(now()) @map("created_at")
@@map("posts")
}Drizzle ORM:
import { db } from './db'
import { users, posts } from './schema'
import { eq, and, gte } from 'drizzle-orm'
// 単純なSELECT
const allUsers = await db.select().from(users)
// 条件付きSELECT
const adultUsers = await db
.select()
.from(users)
.where(gte(users.age, 18))
// JOIN
const usersWithPosts = await db
.select({
userId: users.id,
userName: users.name,
postTitle: posts.title,
})
.from(users)
.leftJoin(posts, eq(users.id, posts.authorId))
// 複雑なクエリ
const result = await db
.select()
.from(users)
.where(
and(
gte(users.age, 18),
eq(users.email, 'test@example.com')
)
)
.limit(10)
.offset(20)Prisma:
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
// 単純なSELECT
const allUsers = await prisma.user.findMany()
// 条件付きSELECT
const adultUsers = await prisma.user.findMany({
where: {
age: {
gte: 18,
},
},
})
// JOIN(リレーション)
const usersWithPosts = await prisma.user.findMany({
include: {
posts: true,
},
})
// 複雑なクエリ
const result = await prisma.user.findMany({
where: {
AND: [
{ age: { gte: 18 } },
{ email: 'test@example.com' },
],
},
skip: 20,
take: 10,
})Drizzle ORM:
// 単一レコードの挿入
const newUser = await db
.insert(users)
.values({
name: 'Alice',
email: 'alice@example.com',
age: 25,
})
.returning()
// 複数レコードの挿入
const newUsers = await db
.insert(users)
.values([
{ name: 'Bob', email: 'bob@example.com', age: 30 },
{ name: 'Charlie', email: 'charlie@example.com', age: 35 },
])
.returning()Prisma:
// 単一レコードの挿入
const newUser = await prisma.user.create({
data: {
name: 'Alice',
email: 'alice@example.com',
age: 25,
},
})
// 複数レコードの挿入
const newUsers = await prisma.user.createMany({
data: [
{ name: 'Bob', email: 'bob@example.com', age: 30 },
{ name: 'Charlie', email: 'charlie@example.com', age: 35 },
],
})Drizzle ORM:
// UPDATE
const updated = await db
.update(users)
.set({ age: 26 })
.where(eq(users.email, 'alice@example.com'))
.returning()
// 複数カラムの更新
const updated2 = await db
.update(users)
.set({
name: 'Alice Smith',
age: 26,
})
.where(eq(users.id, userId))
.returning()Prisma:
// UPDATE
const updated = await prisma.user.update({
where: { email: 'alice@example.com' },
data: { age: 26 },
})
// 複数カラムの更新
const updated2 = await prisma.user.update({
where: { id: userId },
data: {
name: 'Alice Smith',
age: 26,
},
})Drizzle ORM:
await db.transaction(async (tx) => {
const user = await tx
.insert(users)
.values({ name: 'Alice', email: 'alice@example.com' })
.returning()
await tx
.insert(posts)
.values({
title: 'First Post',
content: 'Hello World',
authorId: user[0].id,
})
})Prisma:
await prisma.$transaction(async (tx) => {
const user = await tx.user.create({
data: { name: 'Alice', email: 'alice@example.com' },
})
await tx.post.create({
data: {
title: 'First Post',
content: 'Hello World',
authorId: user.id,
},
})
})# マイグレーションファイルの生成
npx drizzle-kit generate:pg
# マイグレーションの実行
npx drizzle-kit push:pg生成されるマイグレーションファイル:
-- migrations/0001_initial.sql
CREATE TABLE IF NOT EXISTS "users" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid(),
"name" text NOT NULL,
"email" text NOT NULL UNIQUE,
"age" integer,
"created_at" timestamp DEFAULT now()
);
CREATE TABLE IF NOT EXISTS "posts" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid(),
"title" text NOT NULL,
"content" text,
"author_id" uuid REFERENCES "users"("id"),
"created_at" timestamp DEFAULT now()
);# マイグレーションファイルの生成
npx prisma migrate dev --name init
# 本番環境へのマイグレーション適用
npx prisma migrate deploy| ORM | 実行時間 | メモリ使用量 |
|---|---|---|
| Drizzle ORM | 145ms | 12MB |
| Prisma | 380ms | 45MB |
| Raw SQL | 95ms | 8MB |
テストコード(Drizzle):
console.time('drizzle')
const users = await db.select().from(usersTable).limit(10000)
console.timeEnd('drizzle')テストコード(Prisma):
console.time('prisma')
const users = await prisma.user.findMany({ take: 10000 })
console.timeEnd('prisma')import { drizzle } from 'drizzle-orm/d1'
import { users } from './schema'
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const db = drizzle(env.DB)
const allUsers = await db.select().from(users)
return new Response(JSON.stringify(allUsers), {
headers: { 'Content-Type': 'application/json' },
})
},
}import { PrismaClient } from '@prisma/client/edge'
import { withAccelerate } from '@prisma/extension-accelerate'
const prisma = new PrismaClient().$extends(withAccelerate())
export const config = {
runtime: 'edge',
}
export default async function handler(req: Request) {
const users = await prisma.user.findMany({
cacheStrategy: { ttl: 60 },
})
return new Response(JSON.stringify(users))
}注意: PrismaでEdge Functionsを使用するには、Prisma Accelerateが必要(有料)
✅ パフォーマンスが非常に高い
✅ SQLライクな記法で学習コストが低い
✅ エッジランタイムで制限なく動作
✅ 軽量(バンドルサイズが小さい)
✅ 生SQLへのフォールバックが簡単
❌ エコシステムがPrismaより小さい
❌ GUIツールが少ない
❌ マイグレーション機能がシンプル
✅ 豊富なエコシステム
✅ Prisma Studioによる直感的なDB管理
✅ 強力なマイグレーション機能
✅ ドキュメントが充実
✅ 大規模コミュニティ
❌ パフォーマンスがDrizzleより劣る
❌ バンドルサイズが大きい
❌ Edge Functionsで制限あり(Accelerate必要)
❌ 複雑なクエリが書きにくい
2025年時点での推奨:
新規プロジェクト: Drizzle ORM
既存プロジェクト(Prisma使用中): そのまま継続
エンタープライズ: Prisma
どちらも優れたORMですが、プロジェクトの要件に応じて選択することが重要です。
コメント