낙서장이자 오답 노트이자 컨닝 페이퍼

패스트캠퍼스 환급챌린지 14일차 : 코드팩토리의 백엔드 아카데미 : 한 번에 끝내는 NestJS 패키지 - 기초부터 MSA까지 강의 후기 본문

NestJS

패스트캠퍼스 환급챌린지 14일차 : 코드팩토리의 백엔드 아카데미 : 한 번에 끝내는 NestJS 패키지 - 기초부터 MSA까지 강의 후기

NangIn 2025. 4. 14. 21:22

본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성하였습니다.

 

강의 내용 정리   

 

Entity Embedding & Entity Inheritance 실습

 

실습 목표

  • Movie 엔티티에 공통 메타데이터 필드 도입
    • 필드: createdAt, updatedAt, version
    • 방식 2가지 비교:
      1. Entity Embedding
      2. Entity Inheritance

 

Entity Embedding 방식

  • BaseEntity 클래스 생성
    • class BaseEntity {
        @CreateDateColumn()
        createdAt: Date;
      
        @UpdateDateColumn()
        updatedAt: Date;
      
        @VersionColumn()
        version: number;
      }
      
  • Movie 엔티티에 임베딩 적용
    • @Entity()
      class Movie {
        @PrimaryGeneratedColumn()
        id: number;
      
        @Column()
        title: string;
      
        @Column()
        genre: string;
      
        @Column(() => BaseEntity)
        base: BaseEntity;
      }
      
  • 결과 (DB 및 응답)
    • DB에는 칼럼: baseCreatedAt, baseUpdatedAt, baseVersion 형태로 생성됨
    • JSON 응답에서는 네스팅되어 응답
    • {
        "id": 1,
        "title": "Inception",
        "genre": "Sci-Fi",
        { "base": { "createdAt", "updatedAt", "version" } }
      }
      
    • 장점: 구조적으로 명확함
    • 단점: 응답 시 불필요한 중첩 구조

 

Entity Inheritance 방식

  • BaseEntity 클래스 생성
    • class BaseEntity {
        @CreateDateColumn()
        createdAt: Date;
      
        @UpdateDateColumn()
        updatedAt: Date;
      
        @VersionColumn()
        version: number;
      }
      
  • Movie 클래스에서 상속 적용
    • @Entity()
      class Movie extends BaseEntity {
        @PrimaryGeneratedColumn()
        id: number;
      
        @Column()
        title: string;
      
        @Column()
        genre: string;
      }
      
  • 결과 (DB 및 응답)
    • DB에는 칼럼: createdAt, updatedAt, version 으로 깔끔하게 생성
    • JSON 응답도 중첩 없이 1단계로 바로 출력
    • {
        "id": 1,
        "title": "Inception",
        "genre": "Sci-Fi",
        "createdAt": "...",
        "updatedAt": "...",
        "version": 1
      }
      
    • 장점: 깔끔한 응답 구조, 직관적인 설계
    • 단점: OOP에 익숙하지 않으면 상속 구조가 다소 생소할 수 있음

 

결론 요약  

항목 Entity Embedding Entity Inheritance
응답 구조 중첩됨 (base.createdAt) 평평하게 노출 (createdAt)
DB 칼럼 접두어 붙음 (baseCreatedAt) 필드명 그대로 생성
코드 구조 컴포지션 구조 상속 구조
주 용도 필드 그룹화 공통 프로퍼티 재사용
선호도 단순 재사용 시 적합 실무에서 더 많이 사용

 

  • 기존 DB에 데이터가 있는 상태에서 칼럼 변경 시 에러 발생 가능 → 이럴 땐 테이블 드랍 후 재생성 필요
  • 실무에서는 BaseEntity를 common 디렉토리로 분리해 재사용
  • 상속 방식이 실제 사용성과 유지보수 측면에서 더 유리함

 

Single Table Inheritance 실습

 

Single Table Inheritance 설계 개념

  • 목적: Movie와 Series를 하나의 테이블(Content)로 관리하기 위한 구조 구성
  • 전제:
    • Movie → runtime 필드 보유 (예: 상영 시간)
    • Series → seriesCount 필드 보유 (예: 총 몇 부작인지)
    • 둘 다 Content라는 상위 개념으로 묶기
  • 실무에선 STI는 잘 사용하지 않지만 교육 목적상 실습 진행

 

STI 구현 과정

  • 공통 상위 클래스 정의
    • @Entity()
      @TableInheritance({ column: { type: 'varchar', name: 'type' } })
      export class Content extends BaseEntity {
        @PrimaryGeneratedColumn()
        id: number;
      
        @Column()
        title: string;
      
        @Column()
        genre: string;
      }
      
      • @Entity()는 부모(Content)에만 붙임
      • @TableInheritance()로 상속 전략 정의
      • 공통 필드: id, title, genre (BaseEntity에서 메타필드 상속)
  • 하위 자식 클래스 정의
    • @ChildEntity()
      export class Movie extends Content {
        @Column({ nullable: true })
        runtime: number;
      }
      
      @ChildEntity()
      export class Series extends Content {
        @Column({ nullable: true })
        seriesCount: number;
      }
      
      • @ChildEntity()를 붙여 상속 선언
      • 자식 고유 컬럼은 반드시 nullable: true 설정
  • 모듈에 등록
    • TypeOrmModule.forFeature([Content, Movie, Series])
      
      • AppModule 또는 해당 모듈에 3개 엔티티 모두 등록

 

테이블 생성 결과

  • 테이블 이름: content
  • 포함된 컬럼:
    • 공통 필드: id, title, genre, type (STI 구분용)
    • Movie 전용: runtime
    • Series 전용: seriesCount
  • 실제 데이터:
    • Movie → type = 'Movie', runtime = 100, seriesCount = null
    • Series → type = 'Series', seriesCount = 16, runtime = null

 

요약

  • STI는 복잡한 상속 구조를 하나의 테이블로 관리 가능하나, 유연성 부족nullable 필드 증가 단점 존재
  • 실무에선 보통 Entity Inheritance(테이블 분리) 방식 선호
  • 강의에서는 교육 목적상 STI 구조를 직접 구현 → 테스트 → 제거하는 흐름으로 마무리됨

 

학습 후기         

 

이번 실습에서는 Entity Embedding, Entity Inheritance, Single Table Inheritance라는 세 가지 설계 방식을 직접 구현해보며 각각의 특징과 장단점을 비교해볼 수 있었습니다.

 

먼저 Entity Embedding 방식은 공통 필드를 컴포지션 방식으로 묶어 재사용할 수 있다는 장점이 있었지만, 실제 응답 데이터 구조가 중첩되고 DB 칼럼에도 접두어가 붙어 실무에서는 다소 번거롭게 느껴졌습니다. 특히 프론트엔드와 데이터 구조를 협의할 때 불필요한 깊이로 인해 직관성이 떨어질 수 있다는 점이 단점으로 다가왔습니다.

 

반면 Entity Inheritance 방식은 OOP스럽게 공통 필드를 상속받아 사용할 수 있고, 응답에서도 별도 중첩 없이 평탄화된 구조로 제공되어 유지보수와 협업 측면에서 훨씬 더 효율적이라고 느껴졌습니다. 중복 없이 코드 재사용도 가능하고, 구조적으로도 깔끔하게 관리된다는 점에서 실무에 적합한 방식임을 체감할 수 있었습니다.

 

STI 방식은 하나의 테이블에 상속받은 자식 엔티티들을 모두 넣어 관리할 수 있다는 점은 흥미로웠지만, 자식 엔티티마다 nullable 필드가 생기고 테이블이 불필요하게 비대해지는 구조라 유연성이 떨어졌습니다. 강의에서도 언급했듯 실제로는 잘 사용되지 않으며, 학습 목적으로 개념만 이해하고 넘어가는 것이 좋다고 판단됩니다.

 

이번 과정을 통해 ORM을 설계할 때 단순히 코드 작성이 아닌, 실제로 어떤 방식이 데이터 구조와 서비스 아키텍처에 적절한지 고민해야 한다는 점을 배울 수 있었습니다. 특히 관계형 설계에서의 중복 제거, 응답 구조의 일관성, 유지보수성까지 모두 고려해야 하는 점에서 큰 인사이트를 얻었습니다.

 

학습 인증샷       

                       

수강 인증 사진
학습 인증샷
공부 시작 시간
공부 종료 시간

https://abit.ly/lisbva