이슈 발생
NestJS, Prisma, MySQL 환경의 프로젝트에서 MySQL 테이블의 컬럼을 삭제하는 작업을 진행했다.
(이하에서는 해당 컬럼을 "컬럼a"라고 칭하겠다.)
애플리케이션 코드에서도 컬럼a를 참조하는 모든 코드를 확인하고,
컬럼a를 사용하지 않도록 수정했다.
수정된 코드가 포함된 API들은 배치 작업 용이었어서,
배포 도중 실시간 트래픽이 없어
DB 스키마 변경과 애플리케이션 코드 배포 사이 시간 동안의 이슈는 고려하지 않았다.
그런데 컬럼a를 전혀 참조하지 않는 실시간 트래픽이 많은 API에서
해당 시간 동안 에러가 발생했다.
원인
처음엔 컬럼a를 명시적으로 사용하는 곳이 없는 API라 에러가 발생한 이유를 이해할 수 없었다.
그런데 Prisma가 생성하는 쿼리를 확인해보니,
원인을 알 수 있었다.
이슈의 원인은 Prisma의 find 메서드 동작 방식에 있다.
Prisma의 find 메서드에서 아래와 같이 select 대상 컬럼을 명시하지 않으면,
테이블의 모든 컬럼을 조회하게 된다.
const employee = await this.prisma.employees.findUnique({
where: { id: employeeId }
});
이때 DB에 전달되는 쿼리가 아래와 같을 것이라 기대했다.
SELECT *
FROM employees
WHERE id = ${employeeId};
그러나 실제로 Prisma가 생성하는 쿼리는 아래와 같다.
(정확히 이와 동일한 쿼리가 실행되는 것은 아님, 설명을 위해 단순화함)
SELECT id, name, phone_number, weight, height, age
FROM employees
WHERE id = ${employeeId};
테이블 내 모든 컬럼을 SELECT 문에서 명시하는 것이다.
이 때문에 컬럼a를 삭제했을 때,
어플리케이션 코드 상에서는 컬럼a를 사용하는 곳이 없었는데도
DB에서 컬럼a가 삭제된 후 컬럼a를 조회하는 쿼리가 실행되어
에러가 발생한 것이다.
해결 방안
해결 방안은 간단하다.
컬럼이 삭제될 것을 고려하여 find 문을 사용할 때 select 프로퍼티를 명시적으로 작성하여,
의도치 않은 컬럼이 SELECT 절에 포함되지 않도록 하는 것이다.
const employee = await this.prisma.employees.findUnique({
select: {
id: true,
age: true
},
where: { id: employeeId }
});
SELECT문에서 필요한 컬럼만 명시하는 것은
컬럼을 삭제할 때 의식하지 못한 에러의 발생을 방지할 뿐만 아니라 아래와 같은 장점들이 있다.
1. 성능 측면
- 네트워크 전송량 감소:
- 불필요한 컬럼까지 가져오지 않으니, DB에서 애플리케이션으로 넘어가는 데이터 크기가 줄어든다.
- 특히 컬럼이 많고 레코드 수가 많을 때 효과가 크다.
- DB 서버의 I/O 부담 감소
- 스토리지에서 읽어야 하는 양이 줄어들어 쿼리 속도가 개선될 수 있다.
2. 애플리케이션 안정성
- 불필요한 데이터 노출 방지
- 민감한 컬럼(예: 비밀번호 해시, 내부 관리용 필드 등)이 의도치 않게 애플리케이션 레이어로 전달되는 것을 막을 수 있다.
- 스키마 변경에 대한 영향 최소화 (컬럼 삭제 등)
- SELECT *는 컬럼이 추가되면 쿼리 결과 구조가 달라지는데, 지정된 컬럼만 가져오면 이런 변경에 덜 민감하다.
3. 코드 가독성 및 유지보수
- 쿼리의 의도가 명확해짐
- 어떤 데이터를 쓰려는지 명시적으로 드러나서 협업 시 이해하기 쉽다.
- 불필요한 매핑/파싱 코드 감소
- ORM이나 DTO 매핑 과정에서 실제로 필요 없는 필드를 다루지 않아도 된다.
4. 비용 효율성 (운영 환경)
- 클라우드 환경에서의 비용 절감
- 네트워크 요금, DB 사용량(쿼리 실행 시간, I/O 비용)이 줄어드는 효과가 있을 수 있다.
'Node.js' 카테고리의 다른 글
ESLint, Prettier 알아보기 (5) | 2025.06.08 |
---|---|
PM2, node.js 상용 배포를 위한 프로세스 매니저 (6) | 2024.09.29 |
node.js 환경에서 java 코드를 사용하는 방법 (npm java) (5) | 2024.08.17 |