🗄️ TypeORM8. 이론 & 대안 (Prisma · Drizzle · MikroORM)📖 개요

08 — 이론 & 대안 (Theory & Alternatives)

이 챕터가 답하는 질문: TypeORM은 어떤 종류의 도구이고, Prisma·Drizzle·MikroORM·Sequelize와 비교했을 때 언제 옳은가? 그리고 어디서 손해를 보는가? 한 줄 답 (Pyramid Top): “Prisma는 스키마 → 클라이언트 코드젠, Drizzle은 SQL DSL, TypeORM은 데코레이터. 셋은 서로 다른 트레이드오프를 산다 — 어느 손해를 견딜 수 있느냐가 결정의 본질이다.”


한 문장 답 (Pyramid Top)

*“어느 ORM이 좋은가”*는 항상 잘못된 질문이다 — 네 가지 도구는 서로 다른 축에서 다른 손해를 감수한다. TypeORM데코레이터 한 줄로 컴파일 타임 타입과 런타임 메타데이터를 동시에 얻지만 — 타입 정확도는 부분적이다. Prisma스키마 → 코드젠으로 완전한 타입을 얻지만 — 별도 빌드 스텝Rust 엔진 바이너리를 산다. DrizzleSQL DSL런타임 제로 코스트를 얻지만 — ORM 추상화가 거의 없어 SQL을 직접 알아야 한다. MikroORM진짜 Unit of Work + Identity Map을 구현했지만 — 학습 곡선복잡도가 비싸다. 이 챕터는 그 손해의 을 하나씩 그어준다.


챕터 지도 (Mermaid)


Why — 왜 이 챕터가 마지막 직전에 오나

00~07을 따라오면 TypeORM이 어떻게 동작하는지는 충분히 다뤘다. 그러나 production에 올리기 직전, 모든 팀이 같은 질문을 다시 만난다.

“우리 케이스에 진짜 TypeORM이 맞나? Prisma가 더 빠르다던데? Drizzle은 더 가볍다던데? MikroORM은 더 제대로라던데?”

이 질문에 *“TypeORM이 무조건 좋다”*고 답하는 자료는 거의 영업 자료다. 현실의 답은 항상 **“무엇과 무엇을 어떤 축에서 비교하느냐”**부터 정리해야 풀린다. 이 챕터의 8개 문서는 그 을 하나씩 그어준다.

  • 왜 ORM 자체가 존재하는가: 01 — impedance mismatch와 Martin Fowler의 정의
  • 흔한 비교: 02(Prisma) · 03(Drizzle) · 04(MikroORM) · 05(Sequelize)
  • 피해야 할 자리: 06 — 강한 타입·ESM·OLAP·raw SQL 우선
  • 결정 매트릭스: 07 — 4축 × 4도구

How — 어떻게 읽나

세 가지 경로가 있다.

독자추천 순서
”TypeORM을 쓸지 말지 고민 중”060702 (현실 적합성 먼저)
“Prisma·Drizzle 중 갈아탈지 비교”020307 (구체 비교 + 매트릭스)
“ORM 패턴 자체를 이해하고 싶다”010405 (이론 + 친척 + 역사)
#파일읽는 데핵심 키워드
0101-orm-as-a-pattern.mdx12분impedance mismatch · Martin Fowler · DataMapper · Unit of Work
0202-typeorm-vs-prisma.mdx14분데코레이터 · 코드젠 · 타입 정확도 · Rust 엔진
0303-typeorm-vs-drizzle.mdx12분SQL DSL · 런타임 제로 코스트 · 메타데이터
0404-typeorm-vs-mikroorm.mdx10분Identity Map · Unit of Work · em.flush · 친척
0505-typeorm-vs-sequelize.mdx10분JS 시대 · Model.init · 타입 정확도 · 역사
0606-when-not-to-use-typeorm.mdx12분ESM · OLAP · raw SQL · 강타입 정확도
0707-decision-matrix.mdx10분팀 규모 · 타입 요구 · SQL 친밀도 · 마이그레이션 빈도

도구 비교 매트릭스 (한 페이지 요약)

TypeORMPrismaDrizzleMikroORMSequelize
모델 정의데코레이터 (TS class)자체 DSL (schema.prisma)TS 객체 (table())데코레이터 (TS class)Model.init (JS class)
메타데이터reflect-metadata (런타임)코드젠 (빌드 타임)TS inference (컴파일 타임)reflect-metadata인스턴스 attribute
패턴DataMapper (느슨)DataMapper (코드젠)SQL DSL (ORM 아님)DataMapper (정통)ActiveRecord
Unit of Work부분적 (cascade)없음 (명시적 호출)없음완전 (em.flush)없음
Identity Map부분적없음없음완전없음
타입 정확도부분적완전완전부분적낮음
마이그레이션migration:generate (CLI)prisma migrate (DSL diff)drizzle-kit generatemigration:createumzug 통합
raw SQL escape hatchmanager.query$queryRaw기본이 SQLem.getConnection().executesequelize.query
ESM 친화도낮음 (CJS 친화)중간높음중간낮음
런타임 오버헤드메타데이터 + 변환 비용엔진 IPC거의 0메타데이터 + UoW인스턴스 변환
NestJS 통합@nestjs/typeorm (1급)nestjs-prisma (커뮤니티)직접 모듈@mikro-orm/nestjs@nestjs/sequelize
GitHub stars (2024)~33k~37k~20k~8k~29k
최초 release20162019 (v1)202220182010
잘 맞는 자리데코레이터 친숙·NestJS·OOP 도메인강한 타입 요구·풀스택 TSSQL 친숙·서버리스·엣지DDD·복잡 도메인·UoW 필요레거시 JS 코드베이스
안 맞는 자리완전 타입 요구·ESM 우선·OLAPRust 바이너리 거부·DSL 거부ORM 추상 필요·OOP 도메인학습 비용 부담새 TS 프로젝트

한 회사가 여러 도구를 동시에 쓰는 일도 흔하다 — 어느 자리에 어느 도구를 쓰느냐가 진짜 결정.


What — 한 페이지 요약 (모든 문서의 핵심 한 줄)

문서한 줄 결론
01ORM은 객체와 관계형의 impedance mismatch를 메우려는 패턴이고 — TypeORM은 그중 DataMapper느슨한 구현이다.
02Prisma는 스키마 → 코드젠으로 완전한 타입을 얻고, TypeORM은 데코레이터부분 타입유연성을 얻는다.
03Drizzle은 ORM이 아니라 SQL DSL이다 — 런타임에 메타가 0이고, TypeORM은 런타임 메타로 모든 마법을 한다.
04MikroORM은 진짜 Unit of Work + Identity Map을 구현했다 — TypeORM이 가장 닮고 싶었던 모습이지만 못 한 부분이다.
05Sequelize는 JavaScript 시대의 ORM이고 TypeORM은 TypeScript 시대의 ORM이다 — 타입 지원 격차가 근본적이다.
06TypeORM을 쓰지 말 자리: 완전 타입 정확도가 매출에 직결될 때, ESM 우선 스택, raw SQL이 즉시 필요한 OLAP, 데코레이터 spec 변동성에 민감할 때.
074축(팀 규모 · 타입 요구 · SQL 친밀도 · 마이그레이션 빈도) × 4도구 매트릭스로 한 페이지 결정.

What-if — 이 챕터를 건너뛰면

  • “TypeORM은 무조건 좋다”고 믿으면: 강한 타입이 필요한 결제·핀테크 도메인에서 부분 타입의 빈틈이 production 버그로 돌아온다. 6개월 뒤 Prisma로 이주.
  • “ORM은 다 똑같다”고 믿으면: MikroORM의 Unit of Work가 풀어주는 N+1과 cascade 문제를 TypeORM에서 수동으로 다 짜다 무너진다.
  • “Drizzle은 ORM이다”라고 믿으면: ORM의 추상 레이어를 기대하다 그냥 SQL DSL임을 깨닫고 — 자기 도메인 모델을 맨손으로 다시 만들어야 한다.
  • “Sequelize도 충분히 type-safe하다”고 믿으면: Model.findAll<...>제네릭 누수가 production에서 any를 통과시켜 런타임 에러로 돌아온다.

Insight — 한 단락 이야기

“네 가지 ORM, 네 가지 다른 손해”

2016년 TypeORM이 등장했을 때 — TypeScript 진영의 ORM은 사실상 Sequelize 하나였다. 데코레이터 + reflect-metadata라는 TC39 Stage 1 실험을 ORM에 적용한 시도는 대담했고 시기적절했다. NestJS가 같은 패턴을 받아들이면서 TypeORM은 사실상 표준이 되었다.

그러나 2019년 Prisma가 *“메타데이터를 런타임에 두지 말고, 빌드 타임에 코드를 생성하자”*라는 정반대 선택을 하면서 — 완전한 타입 정확도라는 TypeORM이 끝까지 닿을 수 없던 자리를 차지했다.

2022년 Drizzle은 또 다른 길을 보였다 — “ORM 추상을 버리고, SQL DSL을 TypeScript로 표현하자”. 런타임 메타데이터가 0이라 서버리스·엣지에서 cold start가 사라졌다.

그리고 그 사이, MikroORM은 조용히 TypeORM이 못 한 Unit of Work를 구현했다 — DDD 진영의 사람들이 진짜 ORM이라 부르는 그 자리.

네 가지 도구가 네 가지 다른 손해를 산다 — TypeORM의 손해는 완전 타입의 절반이지만, 그 대신 데코레이터 한 줄의 익숙함을 얻는다. 이게 무거운지 가벼운지는 팀의 결제 정확도가 매출에 직결되는지에 달렸다.


한 단락 요약

ORM은 객체-관계 impedance mismatch를 메우는 패턴(01)이고 — 그 안에서 TypeORM은 데코레이터, Prisma는 코드젠(02), Drizzle은 SQL DSL(03), MikroORM은 정통 DataMapper(04), Sequelize는 JS 시대 유산(05)이라는 서로 다른 손해를 산다. 피해야 할 자리06이 정리하고, 4축 결정 매트릭스07이 그린다. 이 챕터를 끝내면 *“TypeORM이 좋은가”*가 아니라 *“이 자리에 TypeORM의 손해가 견딜만한가”*를 묻게 된다. 다음 챕터(09-real-world-cases)는 이 매트릭스를 실제 회사들이 어떻게 적용했는지를 본다.