본문 바로가기
개발 기초 다지기

예매 가능여부 반환(메모리 내 계산 vs 데이터베이스 필드)

by 너의고래 2024. 7. 8.

예매 상세페이지에서 현재 티켓이 예매가 가능한지 여부를 반환하는 코드를 구현해야 했다. 구현을 위해 머릿속에는 두가지 방법이 생각났다. 1. 조회 시점마다 남아있는 좌석 수를 확인해서 반환 할 것이냐 2. 데이터베이스 테이블 내에 가능 여부 필드를 따로 생성할 것인가 이다.

 

 

메모리 내 계산 vs 데이터베이스 필드 생성

결정하기 전 각각의 장단점에 대해 알아보았다.

1.  메모리 내에서 계산하여 추가 속성 반환

장점

  • 유연성: isAvailable 필드를 필요에 따라 동적으로 계산할 수 있어, 조건이 변하더라도 쉽게 변경할 수 있다.
  • 데이터베이스 일관성: 데이터베이스 스키마에 영향을 주지 않으며, 추가 필드로 인한 데이터베이스 수정이 필요 없다.
  • 간단한 유지보수: 코드 내에서 필요한 필드를 추가하므로, 데이터베이스를 다시 마이그레이션하거나 스키마를 변경할 필요가 없다.

단점

  • 성능 이슈: 데이터가 많아질수록 서버 메모리에서 계산하는 비용이 증가할 수 있다.
  • 일관성 보장 어려움: 여러 곳에서 isAvailable을 계산해야 할 경우, 코드 중복이나 일관성 문제가 발생할 수 있다.

2. 데이터베이스 테이블에 isAvailable 필드 추가

장점

  • 성능 최적화: 데이터베이스가 직접 계산하고 저장하므로, 조회 시점에 계산하는 비용이 줄어든다.
  • 일관성 유지: 데이터베이스에 isAvailable 필드가 존재하므로, 항상 동일한 값을 반환할 수 있다.
  • 복잡한 쿼리 지원: 복잡한 조건을 데이터베이스에서 처리할 수 있으며, 이를 통해 더 효율적인 쿼리를 작성할 수 있다.

단점

  • 스키마 변경 필요: 테이블에 새로운 필드를 추가하려면 데이터베이스 스키마를 변경해야 하며, 이는 마이그레이션 과정이 필요다.
  • 추가 유지보수 비용: isAvailable 필드를 항상 최신 상태로 유지하기 위해 추가 로직이 필요, 데이터베이스 트리거나 애플리케이션 로직으로 구현해야 한다.
  • 데이터 일관성 관리: isAvailable 필드를 항상 최신 상태로 유지해야 하므로, 예매나 취소 등의 트랜잭션에서 이를 관리하는 추가 작업 필요.

 

어떤 방식이 내 과제에 더 적합할까?

우선 나같은 경우, 예매 가능 여부를 맨 처음 ERD를 짤 때 고려하지 못했던 상황이다. 코드를 작성하고 발제 문서를 확인하던 중 발견한 부분.. 그렇기 때문에 데이터가 많지 않은 개인 과제 중이고 데이터베이스의 변경이 필요 없는 메모리 내에서 계산하여 추가 속성을 반환하는 방법을 선택하였다.

하지만 추후 성능 최적화가 필요한 프로젝트를 진행중이라면, 데이터베이스 테이블에 필드를 추가하는 방법을 선택할 것 같다. 무엇보다 이 부분은 취소표가 풀리고 그 티켓을 차지하기 위해 여부가 빠르게 변하는 과정에 중요한 부분을 차지할텐데, 일관성 부분에서 문제가 생긴다면 정말 끔찍할 것 같다. 

 

구현 코드

  //공연 상세 조회
  async findOne(performanceId: number): Promise<Partial<Performance>> {
    const performance = await this.performanceRepository.findOne({
        where: {performanceId},
        relations: ['schedules']
    });

    if(!performance){
        throw new NotFoundException('공연을 찾을 수 없습니다.');
    }

    const AvailableSchedule = performance.schedules.map(schedule => ({
        ...schedule,
        isAvailable: schedule.remainingSeats>0
    }))

    return {
        performanceId: performance.performanceId,
        title: performance.title,
        description: performance.description,
        category: performance.category,
        location: performance.location,
        price: performance.price,
        img: performance.img,
        schedules: AvailableSchedule,
        createdAt: performance.createdAt,
        updatedAt: performance.updatedAt,
    };
  }

 

공연 상세 조회시, performaneId로 performance 테이블에서 공연 정보와 schedules 데이터를 가져온다.

가져온 schedules 배열을 map을 통해 순회하며, 해당 배열의 remainingSeats의 수가 0보다 클 경우, 예매가 가능하도록 true 값을 갖는 isAvailable 객체를 추가해준다. 그리고 AvailableSchedule로 정의.

반환할 때 기본적인 공연 정보와 함께 일정과 예매 가능여부를 함께 가지고 있는 AvailableSchedule 함께 반환한다.

 

 

 

과제를 진행중이기에 시간이 많지 않았고, 처음부터 이 부분을 고려하지 못했어서 메모리 내에서 계산하여 추가 속성을 반환하는 선택을 했다. 이러한 상황이 아니라면, 추후 현업에서는 데이터베이스에 필드를 따로 생성하는 상황이 더 많이 쓰일 것 같기에 추후 이 부분에 대한 코드도 작성해봐야겠다.

 

 

 

댓글