dev-guide
Drizzle ORM 완벽 가이드 — TypeScript-first 데이터베이스 쿼리 빌더
Drizzle ORM의 타입 안전 스키마 정의, 쿼리 빌더 패턴, 마이그레이션 워크플로우, Next.js와의 통합 방법을 실무 예제와 함께 정리하였다.
- ·Drizzle ORM: TypeScript-first 경량 ORM
- ·SQL과 거의 동일한 문법으로 타입 안전 쿼리 작성 가능
- ·Prisma 대비 번들 크기가 훨씬 작고 런타임 오버헤드 최소화
- ·PostgreSQL, MySQL, SQLite, Cloudflare D1 지원
Prisma로 운영하던 프로젝트를 Drizzle ORM으로 전환하면서 초기에 스키마 파일을 별도로 유지해야 한다는 점에 어색함을 느꼈다. 그러나 SQL에 가까운 문법 덕분에 복잡한 조인 쿼리를 작성할 때 ORM의 추상화에 갇히는 답답함이 사라졌고, 타입 추론이 자동으로 이루어져 별도의 타입 선언 파일을 관리하지 않아도 되었다.
Drizzle ORM이란 무엇인가
Drizzle ORM과 Prisma의 핵심 차이
Drizzle ORM은 TypeScript-first 설계를 유지하면서도 SQL에 매우 가까운 API를 제공하는 경량 ORM이다. Prisma는 별도의 스키마 언어(.prisma 파일)를 사용하고 런타임 쿼리 엔진을 포함하여 번들 크기가 크지만, Drizzle은 순수 TypeScript로 스키마를 정의하고 SQL을 직접 생성하므로 번들 크기가 수십 배 작다. Serverless, Edge Runtime, Cloudflare Workers처럼 번들 크기에 민감한 환경에서 Drizzle이 선택되는 주된 이유이다. 또한 생성된 SQL을 개발자가 직접 확인하고 제어할 수 있어 예측 불가능한 쿼리가 실행되는 상황을 방지할 수 있다.
// schema.ts — TypeScript로 스키마 정의
import { pgTable, serial, text, timestamp, integer } from 'drizzle-orm/pg-core'
export const posts = pgTable('posts', {
id: serial('id').primaryKey(),
title: text('title').notNull(),
content: text('content'),
authorId: integer('author_id').references(() => users.id),
createdAt: timestamp('created_at').defaultNow(),
})
export const users = pgTable('users', {
id: serial('id').primaryKey(),
email: text('email').notNull().unique(),
name: text('name').notNull(),
})Drizzle ORM 타입 안전 쿼리 빌더
Drizzle의 쿼리 API는 SQL 구조와 거의 1:1로 대응하여 SQL을 아는 개발자라면 별도의 학습 없이 바로 사용할 수 있다. db.select().from(posts).where(eq(posts.id, 1))처럼 메서드 체이닝으로 쿼리를 구성하며, 반환 타입이 스키마 정의에서 자동으로 추론된다. innerJoin, leftJoin, groupBy, orderBy 등 SQL의 모든 주요 절을 타입 안전하게 표현할 수 있으며, 컬럼명 오타나 잘못된 타입 비교는 컴파일 타임에 감지된다.
관계형 쿼리와 실전 패턴
Drizzle ORM Relations API로 N+1 문제 방지
Drizzle의 relations 함수로 테이블 간 관계를 선언하면, db.query.posts.findMany({ with: { author: true } }) 형태로 관련 데이터를 한 번의 최적화된 쿼리로 가져올 수 있다. 이 방식은 N+1 쿼리 문제를 방지하면서도 반환 타입이 정확히 추론된다. 중첩 관계 로딩, 조건부 포함, 컬럼 선택도 모두 타입 안전하게 지원하며, 실제 실행되는 SQL은 로깅 옵션으로 확인할 수 있다.
Drizzle ORM drizzle-kit 마이그레이션
drizzle-kit generate는 현재 스키마와 이전 스냅샷을 비교하여 변경사항에 해당하는 SQL 마이그레이션 파일을 자동 생성한다. 생성된 SQL을 직접 검토하고 필요 시 수정한 뒤 drizzle-kit migrate로 적용한다. Prisma의 자동 마이그레이션과 달리 개발자가 SQL을 명시적으로 승인하는 흐름이므로 의도치 않은 데이터 손실을 방지하기 쉽다. CI/CD 파이프라인에서는 마이그레이션 파일을 Git으로 관리하고 배포 시 자동 적용하는 방식을 권장한다.
Next.js와 서버리스 환경 통합
Drizzle ORM Next.js App Router와의 통합
Next.js Server Components와 Server Actions에서 Drizzle을 직접 사용할 수 있다. 연결 인스턴스를 모듈 레벨에서 싱글턴으로 생성하고 Server Component에서 임포트하여 사용한다. Serverless 환경에서는 매 요청마다 새 커넥션이 생성되는 문제를 방지하기 위해 Neon의 HTTP 드라이버나 PlanetScale의 서버리스 드라이버를 사용하는 것이 권장된다. Vercel 배포 환경에서는 @neondatabase/serverless와 Drizzle을 함께 사용하는 조합이 가장 일반적이다.
Drizzle ORM Cloudflare D1과의 통합
Cloudflare D1은 SQLite 기반의 엣지 데이터베이스로, Drizzle은 D1 드라이버를 공식 지원한다. Cloudflare Workers 환경에서 drizzle(env.DB) 한 줄로 연결하고 동일한 쿼리 API를 사용할 수 있다. 번들 크기 제약이 엄격한 Workers 환경에서 Prisma 대신 Drizzle이 사실상 표준으로 자리 잡은 이유이다. wrangler의 D1 마이그레이션 명령과 drizzle-kit을 함께 사용하여 마이그레이션 워크플로우를 구성할 수 있다.
자주 묻는 질문
Drizzle과 Prisma 중 무엇을 선택해야 하나요?+
Serverless, Edge, Cloudflare Workers 환경이라면 Drizzle이 유리합니다. SQL을 직접 다루는 것이 익숙하고 번들 크기가 중요하다면 Drizzle, 스키마 우선 개발과 강력한 GUI 도구(Prisma Studio)가 필요하다면 Prisma를 선택하세요.
Drizzle은 MongoDB를 지원하나요?+
현재 Drizzle은 관계형 데이터베이스(PostgreSQL, MySQL, SQLite)만 지원합니다. MongoDB 같은 문서형 데이터베이스는 지원하지 않으며, 향후 로드맵에도 포함되어 있지 않습니다.