2026년 1월 18일

Sequelize vs TypeORM vs Prisma

 

사전 지식

  • 객체 지향 프로그래밍 (OOP): 클래스, 객체, 상속, 연관 관계 등 객체 지향의 기본 개념을 이해해야 한다. 우리가 코드로 짜는 ‘객체’가 어떻게 데이터베이스에 저장될지를 다루기 때문이다.
  • 관계형 데이터베이스 (RDBMS) & SQL: 테이블, PK(기본키), FK(외래키), Join 같은 개념과 SELECT, INSERT, UPDATE 등의 기본적인 SQL 문법을 알아야 한다. ORM이 SQL을 대신 써주긴 하지만, 결국 내부적으로는 SQL이 실행되기 때문이다.
 

2️⃣ ORM의 등장 배경

  • 객체 지향 언어와 관계형 데이터베이스의 생각 방식이 너무 다르기 때문에 등장했다. (객체-관계 패러다임 불일치)
    • 객체: 데이터와 행위(메서드)를 함께 관리하고, 상속이나 참조를 통해 관계를 맺는다.
    • RDBMS: 데이터를 테이블 형태(행과 열)로만 관리하며, 외래키를 사용해 관계를 맺는다.
  • 과거에는 개발자가 직접 자바나 파이썬 코드 안에 복잡한 SQL 문을 문자열로 작성해야 했다. 이는 다음과 같은 문제를 일으켰다.
      1. 반복 작업: 비슷한 SQL 문을 계속 작성해야 한다.
      1. 유지보수 어려움: DB 테이블의 컬럼 하나만 바뀌어도 관련된 모든 SQL 코드를 직접 수정해야 한다.
      1. 객체 지향의 이점 상실: 데이터를 단순히 테이블에 넣고 빼는 용도로만 쓰게 되어 객체 모델링의 힘이 약해진다.
 

3️⃣ ORM 작동 방식

  • ORM(Object-Relational Mapping) 은 말 그대로 객체(Object)관계형 데이터베이스(Relational)연결(Mapping) 해주는 기술이다.

핵심 동작 원리

  • 개발자가 “이 객체를 저장해줘”라고 명령하면, ORM 라이브러리가 중간에서 적절한 SQL을 자동으로 생성해서 DB로 날려준다.
객체 지향 (Code)
관계형 DB (Table)
매핑 개념
Class (클래스)
Table (테이블)
클래스는 하나의 테이블이 됨
Instance (객체)
Row (행)
하나의 객체는 테이블의 한 줄이 됨
Field (변수)
Column (열)
객체의 변수는 테이블의 열이 됨

주요 사용 방식

  • 보통은 프레임워크에서 제공하는 라이브러리를 사용한다.
    • Java: JPA (Hibernate)
    • Python: Django ORM, SQLAlchemy
    • Node.js: Prisma, TypeORM, Sequelize
 

4️⃣ ORM 사용의 장점과 주의할 점

장점

  • 생산성 향상: 반복적인 CRUD SQL을 직접 짤 필요가 없어 비즈니스 로직에 집중할 수 있다.
  • 가독성 및 유지보수: 코드가 간결해지고, 객체 모델이 변경되어도 수정이 상대적으로 용이하다.
  • DBMS 독립성: DB 종류를 바꿔도 설정을 통해 코드를 거의 수정하지 않고 대응할 수 있다.

주의할 점

  • 성능 이슈: ORM이 생성하는 SQL이 항상 최적은 아니다. 특히 N+1 문제와 같은 성능 저하 요인을 이해하지 못하면 서비스가 느려질 수 있다.
  • 학습 곡선: 단순한 사용법은 쉽지만, 복잡한 쿼리나 성능 최적화 단계로 가면 공부할 양이 꽤 많다.
 
💡
ORM은 결국 SQL을 대신 작성해주는 도구일 뿐, 핵심은 데이터베이스 설계에 있다
 

5️⃣ Node.js ORM의 3세대 진화 과정

1. Sequelize

  • Node.js 초기 단계부터 사용된 가장 오래되고 검증된 ORM이다.
  • 배경: 당시에는 JavaScript가 주류였고, SQL을 직접 작성하는 불편함을 해소하기 위해 등장했다.
  • 특징:
    • 문자열 기반: 모델 정의나 쿼리 작성이 대부분 JS 객체와 문자열로 이루어진다.
    • 성숙도: 오랫동안 사용되어 래퍼런스가 매우 많고 안정적이다.
  • 한계: TypeScript가 대세가 되면서 타입 지원이 부실하다는 점이 큰 단점이 되었다. TS와 함께 쓰려면 수동으로 타입을 정의해야 하는 번거로움이 있다.
 

2. TypeORM

  • Java의 Hibernate나 C#의 Entity Framework 같은 전통적인 객체 지향 패턴을 Node.js에 가져온 주인공이다.
  • 배경: TypeScript의 보급과 함께 “데코레이터(@Entity, @Column 등)”를 활용해 코드 레벨에서 데이터베이스 구조를 정의하고 싶은 요구가 커졌다.
  • 특징:
    • 데코레이터 활용: 클래스 위에 @Entity 같은 어노테이션을 붙여 DB 테이블과 매핑한다.
    • 유연성: Active RecordData Mapper 패턴을 모두 지원하여 프로젝트 규모에 맞게 설계할 수 있다.
  • 한계:
    • 코드가 복잡해질수록 설정이 까다롭고, 런타임에 타입이 일치하지 않는 소위 ‘AnyORM’ 현상이 발생하기 쉽다.
    • 예를 들어, DB엔 값이 없는데 코드상에선 타입이 정의되어 있어 에러가 발생하는 경우가 있다.
 

3. Prisma

  • 현재 가장 트렌디한 도구로, 기존 ORM들과는 완전히 다른 ‘스키마 중심’ 접근 방식을 취한다.
  • 배경: “코드와 DB 사이의 불일치를 근본적으로 해결하자”는 목표로 등장했다.
  • 특징:
    • Prisma Schema (DSL): 전용 스키마 파일(.prisma)에 DB 구조를 정의하면, 이를 바탕으로 최적화된 TypeScript 클라이언트를 자동 생성해 준다.
    • 완벽한 타입 추론: 쿼리 결과에 대한 타입을 개발자가 직접 정의할 필요가 없다. Prisma가 생성해 준 클라이언트를 쓰면 오타조차 낼 수 없을 정도로 강력한 자동완성을 지원한다.
  • 한계: 전용 스키마 언어를 새로 배워야 하며, 내부적으로 Rust가 작성된 엔진을 사용하기 때문에 초기 실행 속도나 커스터마이징에 제약이 있을 수 있다.
 

3대 ORM 한눈에 비교하기

구분
Sequelize
TypeORM
Prisma
주요 언어
JavaScript (TS 지원 약함)
TypeScript (기본)
TypeScript (최적화)
정의 방식
코드 내 객체 정의
클래스 & 데코레이터
전용 스키마 파일 (DSL)
타입 안전성
낮음
보통 (수동 설정 필요)
매우 높음 (자동 생성)
학습 곡선
낮음
중간
중간 (새로운 언어 필요)
주요 패턴
Active Record 중심
Data Mapper / Active Record
엔진 중심 (Unique)