카테고리 없음

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

Laftel 2025. 4. 16. 17:45
반응형
import { Transform } from "class-transformer";
import { version } from "os";
import { Column, CreateDateColumn, Entity, PrimaryGeneratedColumn, UpdateDateColumn, VersionColumn } from "typeorm";
export class BaseEntity{
  @CreateDateColumn()
  createdAt: Date;
  @UpdateDateColumn()
  updatedAt: Date;

  @VersionColumn()
  version: number;
}
@Entity()
@TableInheritance({
  column:
    type: 'varchar',
    name: 'type',
})
export class Content extends BaseEntity{
  @PrimaryGeneratedColumn()

  id: number;
  @Column()
  title: string;
  @Column()
  genre: string;
  
  @Column()
  runtime: number;
 }
@ChildEntity()
export class Movie extends Content{
 
}
@ChildEntity()
export class Series extends Content{
 
  @Column()
  seriesCount : number;
}

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



TypeORM Single Table Inheritance (STI) 학습 후 느낀 점과 인사이트

STI는 상속 관계에 있는 여러 엔티티 클래스의 모든 속성을 하나의 데이터베이스 테이블에 저장하는 전략입니다. 이를 통해 데이터베이스 스키마를 단순화하고, 특정 유형의 데이터를 조회하는 성능을 향상시킬 수 있습니다.

  • BaseEntity: createdAt, updatedAt, version과 같은 공통 속성을 정의하는 추상 클래스입니다.
  • Content: @Entity() 데코레이터로 정의된 기본 엔티티이며, BaseEntity를 상속받습니다. id, title, genre, runtime과 같은 공통 속성을 가집니다.
  • @TableInheritance({...}): Content 클래스에 적용된 이 데코레이터는 해당 엔티티가 상속 구조의 루트임을 나타내고, STI 전략을 사용하도록 TypeORM에 지시합니다.
    • column: { type: 'varchar', name: 'type' }: 이 설정은 데이터베이스 테이블에 type이라는 varchar 타입의 컬럼을 추가하여 각 레코드의 실제 엔티티 유형(Movie 또는 Series)을 저장하는 데 사용됩니다.
  • @ChildEntity(): Movie와 Series 클래스에 적용된 이 데코레이터는 각각 Content를 상속받는 자식 엔티티임을 나타냅니다. Movie는 추가적인 속성이 없지만, Series는 seriesCount라는 고유한 속성을 가집니다.

STI의 작동 방식:
TypeORM은 위와 같은 설정을 기반으로 다음과 같은 방식으로 STI를 구현합니다.

  1. 단일 테이블 생성: Content, Movie, Series 엔티티의 모든 속성을 포함하는 하나의 테이블이 데이터베이스에 생성됩니다. 이 테이블은 id, title, genre, runtime, createdAt, updatedAt, version, 그리고 STI 설정을 통해 추가된 type 컬럼과 자식 엔티티의 고유 속성(seriesCount)을 모두 포함합니다.
  2. type 컬럼을 이용한 구분: 데이터베이스에 저장되는 각 레코드는 해당 레코드의 실제 엔티티 유형(Movie 또는 Series)을 나타내는 값을 type 컬럼에 가집니다. 예를 들어, Movie 엔티티의 인스턴스가 저장되면 type 컬럼의 값은 'movie' (기본적으로 클래스 이름을 소문자로 변환한 값)가 되고, Series 엔티티의 인스턴스는 'series'가 됩니다.
  3. 조회 시 필터링: 특정 자식 엔티티(Movie 또는 Series)를 조회할 때, TypeORM은 where 조건에 type 컬럼의 값을 자동으로 추가하여 해당 유형의 레코드만 필터링합니다.

TypeORM Single Table Inheritance (STI) 학습 후 느낀 점과 인사이트

제공해주신 코드는 TypeORM의 Single Table Inheritance (STI) 전략을 보여주는 예시입니다. STI는 상속 관계에 있는 여러 엔티티 클래스의 모든 속성을 하나의 데이터베이스 테이블에 저장하는 전략입니다. 이를 통해 데이터베이스 스키마를 단순화하고, 특정 유형의 데이터를 조회하는 성능을 향상시킬 수 있습니다.
코드 분석:

  • BaseEntity: createdAt, updatedAt, version과 같은 공통 속성을 정의하는 추상 클래스입니다.
  • Content: @Entity() 데코레이터로 정의된 기본 엔티티이며, BaseEntity를 상속받습니다. id, title, genre, runtime과 같은 공통 속성을 가집니다.
  • @TableInheritance({...}): Content 클래스에 적용된 이 데코레이터는 해당 엔티티가 상속 구조의 루트임을 나타내고, STI 전략을 사용하도록 TypeORM에 지시합니다.
    • column: { type: 'varchar', name: 'type' }: 이 설정은 데이터베이스 테이블에 type이라는 varchar 타입의 컬럼을 추가하여 각 레코드의 실제 엔티티 유형(Movie 또는 Series)을 저장하는 데 사용됩니다.
  • @ChildEntity(): Movie와 Series 클래스에 적용된 이 데코레이터는 각각 Content를 상속받는 자식 엔티티임을 나타냅니다. Movie는 추가적인 속성이 없지만, Series는 seriesCount라는 고유한 속성을 가집니다.

STI의 작동 방식:
TypeORM은 위와 같은 설정을 기반으로 다음과 같은 방식으로 STI를 구현합니다.

  1. 단일 테이블 생성: Content, Movie, Series 엔티티의 모든 속성을 포함하는 하나의 테이블이 데이터베이스에 생성됩니다. 이 테이블은 id, title, genre, runtime, createdAt, updatedAt, version, 그리고 STI 설정을 통해 추가된 type 컬럼과 자식 엔티티의 고유 속성(seriesCount)을 모두 포함합니다.
  2. type 컬럼을 이용한 구분: 데이터베이스에 저장되는 각 레코드는 해당 레코드의 실제 엔티티 유형(Movie 또는 Series)을 나타내는 값을 type 컬럼에 가집니다. 예를 들어, Movie 엔티티의 인스턴스가 저장되면 type 컬럼의 값은 'movie' (기본적으로 클래스 이름을 소문자로 변환한 값)가 되고, Series 엔티티의 인스턴스는 'series'가 됩니다.
  3. 조회 시 필터링: 특정 자식 엔티티(Movie 또는 Series)를 조회할 때, TypeORM은 where 조건에 type 컬럼의 값을 자동으로 추가하여 해당 유형의 레코드만 필터링합니다.

STI 학습 후 느낀 점과 인사이트:
첫째, 데이터베이스 스키마 단순화의 매력과 잠재적인 단점을 동시에 느꼈습니다. STI는 여러 엔티티를 하나의 테이블로 관리함으로써 데이터베이스 스키마를 직관적이고 단순하게 만들어줍니다. 이는 개발 초기 단계나 간단한 상속 구조에서 관리가 용이하다는 장점을 제공합니다. 하지만, 자식 엔티티가 늘어나고 각 엔티티의 고유 속성이 많아질수록 테이블의 컬럼 수가 증가하고, 특정 엔티티에만 의미 있는 컬럼들이 NULL 값을 가지게 되어 데이터베이스 공간의 비효율성을 초래할 수 있다는 점을 인지했습니다. 마치 하나의 큰 서랍장에 다양한 종류의 물건을 모두 넣어 관리하는 것과 같아서, 처음에는 편리하지만 물건의 종류가 많아질수록 찾기가 어려워지고 공간 활용도가 떨어질 수 있다는 것을 깨달았습니다.
둘째, 조회 성능 최적화의 가능성과 주의할 점을 이해했습니다. STI 환경에서 특정 유형의 데이터를 조회할 때, 조인은 필요하지 않으므로 조인으로 인한 성능 저하를 방지할 수 있습니다. 이는 조회 성능이 중요한 경우 STI가 유리한 선택이 될 수 있음을 시사합니다. 하지만, 테이블이 너무 커지거나 인덱싱이 제대로 이루어지지 않으면 오히려 성능 저하가 발생할 수도 있다는 점을 간과해서는 안 됩니다. 마치 모든 정보를 하나의 거대한 문서 파일에 저장하는 것과 같아서, 특정 정보를 빠르게 찾기 위해서는 적절한 목차와 색인 관리가 필수적인 것처럼 느껴졌습니다.
셋째, 객체 지향 상속 모델과 데이터베이스 테이블 간의 매핑 전략 선택의 중요성을 깨달았습니다. STI는 객체 지향 프로그래밍의 상속 개념을 데이터베이스 테이블에 직접적으로 반영하는 전략 중 하나입니다. 하지만, STI가 모든 상속 관계에 최적의 해결책은 아니라는 것을 이해했습니다. 상속 구조가 깊어지거나 자식 엔티티 간의 속성이 크게 다를 경우에는 Class Table Inheritance (CTI)나 Joined Table Inheritance (JTI)와 같은 다른 상속 전략이 더 적합할 수 있습니다. 따라서 애플리케이션의 도메인 모델과 데이터 접근 패턴을 종합적으로 고려하여 가장 적절한 상속 전략을 선택하는 것이 중요하다는 인사이트를 얻었습니다. 마치 다양한 건축 공법 중에서 건물의 용도, 규모, 지형 조건 등을 고려하여 가장 적합한 공법을 선택하는 것과 유사한 고민이 필요하다는 것을 느꼈습니다.
넷째, TypeORM의 @TableInheritance와 @ChildEntity 데코레이터의 역할과 사용법을 명확히 이해하게 되었습니다. 이러한 데코레이터들을 통해 TypeORM에게 상속 구조와 STI 전략을 명시적으로 알려줌으로써, 개발자는 TypeORM이 제공하는 편리한 ORM 기능을 활용하여 상속 관계를 데이터베이스에 효과적으로 매핑할 수 있습니다. 이는 개발 생산성을 높이고, 데이터베이스 관련 코드를 더욱 직관적으로 만들 수 있도록 돕는 중요한 메커니즘이라고 생각합니다. 마치 프로그래밍 언어의 문법 규칙을 이해하고 사용하는 것처럼, TypeORM이 제공하는 데코레이터와 설정 옵션들을 정확히 이해하고 활용하는 것이 효율적인 개발의 핵심이라는 것을 깨달았습니다.
이번 STI 학습을 통해 데이터 모델링에 상속 개념을 적용하는 다양한 방법 중 하나를 이해하고, 각 전략의 장단점을 고려하여 상황에 맞는 선택을 하는 것이 중요하다는 것을 배웠습니다. 앞으로 다른 상속 전략들도 학습하고, 실제 프로젝트에서 다양한 상속 구조를 모델링해보면서 더욱 깊이 있는 이해와 숙련도를 쌓아가고 싶습니다.


#패스트캠퍼스 #직장인자기계발 #직장인공부 #환급챌린지 #패스트캠퍼스후기 #오공완
https://bit.ly/4hTSJNB

반응형