ORM은 실제로 유용하다
카테고리
프로그래밍/소프트웨어 개발
서브카테고리
개발 툴
대상자
- 대상: 데이터베이스와 ORM을 사용하는 개발자, TypeScript 프로젝트를 진행하는 팀
- 난이도: 중간 이상 (ORM 사용 경험과 TypeScript 이해 필요)
핵심 요약
- Prisma의 강점: 데이터베이스 스키마를 위한 전용 DSL 제공 (
model User { ... }
),@default
,@relation
등 메타어노테이션으로 타입 안전성 보장 - TypedSQL 지원:
.sql
파일을 통해 완전히 타입화된 원시 SQL 쿼리 생성 가능 (prisma.$queryRawTyped
) - 성능 최적화:
relationLoadStrategy
로 데이터베이스 레벨 조인 지원 (PostgreSQL LATERAL JOIN, MySQL 코어레이티드 서브쿼리)
섹션별 세부 요약
1. **Drizzle vs Prisma 선택 이유**
- Drizzle의 단점: 당시 LLM이 안정적으로 코드 생성 불가, TypeScript 기반 스키마 정의로 인해 복잡한 메타데이터 처리 어려움
- Prisma 선택 이유: DSL 기반 스키마 언어로 인한 간결한 정의, 데이터베이스 스키마와 애플리케이션 코드 분리
2. **Prisma 스키마 언어의 장점**
- 타입 안전성:
@id
,@default
,@relation
등 메타어노테이션으로 스키마 정의 시 자동 타입 추론 - 단일 소스 진실:
model User { ... }
파일로 관계, 제약 조건, 기본값 한눈에 파악 가능 - TypeScript와의 차이:
@decorator
기반 정의 대비 불필요한 임포트, 보일러플레이트 제거
3. **TypedSQL 기능**
- 원시 SQL 타입화:
.sql
파일에서 쿼리 작성 후prisma.$queryRawTyped
로 완전히 타입화된 결과 반환 - 예시:
```sql
-- prisma/sql/searchPosts.sql
SELECT p.*, u.name as author_name, ts_rank(...) as rank
FROM posts p JOIN users u ON p."authorId" = u.id
WHERE to_tsvector(...) @@ query
```
```ts
const results = await prisma.$queryRawTyped(searchPosts(searchTerm));
// results의 rank
필드가 타입 안전하게 인식됨
```
4. **조인 전략 개선 (Prisma 5.8.0)**
- 데이터베이스 레벨 조인:
relationLoadStrategy: "join"
으로 단일 쿼리로 데이터 빌드 - 성능 최적화: JSON 집계로 애플리케이션 서버 계산 절감
- 활성화 방법:
```prisma
generator client {
provider = "prisma-client-js"
previewFeatures = ["relationJoins"]
}```
5. **마이그레이션 편의성**
- 자동 SQL 생성:
prisma migrate dev --name add_user_role
로 스키마 변경 시 타입스크립트 타입 자동 업데이트 - 리팩토링 안전성: 스키마 필드 변경 시 IDE에서 사용처에 대한 에러 즉시 알림
6. **Prisma의 단점과 고려사항**
- 락인 가능성: Prisma 기반 애플리케이션은 재사용성 저하 위험
- 번들 크기: 프로젝트 크기에 따라 성능 영향 가능성
- VC 펀딩: 핵심 인프라에 의존 시 리스크
- 학습 곡선: DSL 언어 추가 학습 필요
결론
- Prisma 선택 시 고려 사항:
relationLoadStrategy
설정,TypedSQL
활용, 마이그레이션 자동화 - ORM의 가치: 95%의 쿼리에 타입 안전성과 생산성 향상, 5%의 복잡 쿼리에 원시 SQL 유연성 제공
- 결론: 정확한 선택과 사용법으로 ORM은 생산성 극대화에 유리한 도구임