2023. 2. 18. 00:08ㆍ프로젝트/8주차 실전 프로젝트
https://ksw0627.tistory.com/101
1. 기술 스택 선정에 대한 고찰 -1편-
1. TypeScript(이하 TS) 앞서 두 프로젝트(미니 프로젝트/클론 코딩)의 경우에는 Node.js로 작성되었다. JavaScript(이하 JS)를 이용하여 Node.js를 통해 서비스를 개발하면서 가장 많이 직면했던 문제점이 있
ksw0627.tistory.com
이전 포스팅에서는 TypeScript, Nest.js 를 선택하게 된 이유와 사용하면서 든 장점, 단점, 알게된 문제나 해결점에 대해서 적었었다.
이번 포스팅에서는 DB와 관련된 기술 채택 사항에 대해서 작성할 예정이다.
3. MYSQL
SQL vs NoSQL
당연히 SQL vs NoSQL을 비교하게 되었다.

여기에는 실제 서비스에는 적용하지 못한 비하인드 스토리가 있다.(그곳엔 슬픈 전설이 있어...)
마지막 편으로 구현하려 했으나 구현하지 못한 기술들에 대해서 설명하게 될 것 같다.
간단하게 말하면(예고편?) 실제 계좌 연동 서비스를 구현하려고 했었고, 그렇기 때문에 명확하게 스키마를 정의하고 데이터 무결성을 보장해야할 필요가 있었다. 그렇다보니 MySQL을 선택하게 되었다.
사실 실제로 적용하지 못했다면 ERD를 삭제하는 것이 당연했겠지만 서비스 마지막까지 구현을 고민했고 그렇지만 적용을 하지 못했기 때문에 남아있게 되었다..
4. TypeORM
( TypeORM vs Sequelize ) vs Raw Query
앞서 두 프로젝트는 Sequelize를 사용해서 ORM을 활용했다. 그러면서 느낀 점이 있었는데 DB Column 수정할 때마다 migration을 drop - create 해야한다는 불편함이 있었고, TypeORM은 간단하게 synchronize: true 옵션으로 entity의 변화가 있으면 자동적으로 적용해주는 것이 장점이라 느껴졌다. 그리고 선언? 적용하기가 좀 더 쉽고 성능 상으로 TypeORM이 더 낫다는 글을 보기도 했다.
[ORM] Node.js에서 ORM 사용하기
Node.js에서 지원하는 ORM의 종류와 차이점 찾아보기
kyungyeon.dev
Nest.JS의 문서에서도 TypeORM을 추천하는 문구가 존재했다.

성능과 편의성의 이슈 그리고 Sequelize를 사용했으니 이번에는 TypeORM을 사용해보자! 라는 의견도 있어서 적용하게 되었다.(이번 프로젝트는 많은 것을 도전 해보는 경험이었다.)
4.1 장점
- Entity의 변화가 자동적으로 적용된다.
- 그 외에는 사실 잘 모르겠다
Sequelize를 사용할때는 Column이 변경될 때마다 migration을 하는 것이 불편했는데 TypeORM을 사용할 때는 변화를 감지해서 자동적으로 적용해주는 옵션이 있어서 굉장히 편했다.
이건 Nest.JS에서 다룰까 하다가 Entity 설정할 때 느낀점이라 여기에 적었다.
데코레이터와 결합해서 식별하기 쉽고 간편하게(?) Column을 설정하고 관계 설정이 알아보기 쉬워서 좋았던 것 같다.
물론 반대로 관계 설정에 대해서 처음에 잘 알지 못했기 때문에 헤맸었던 것 같다.
다대다 관계에서 문제가 있었으나 이는 트러블 슈팅에서 다루게 될 것 같다.
성능 상으로 이점이 있다고 말하지만, 방대한 데이터도 아니고 크게 체감할 일은 없었던 것 같다. 오히려 성능상의 이슈는 내 알고리즘의 시간복잡도를 개선하는 것이 더 나은 것 같다고 생각이 들었다.
그리고 해당 테이블의 전체 데이터를 가져오는데 TypeORM이 지원하는 Eager loading과 Lazy loading은 그 자체의 장점도 있었지만 단점도 있었다.
N+1 문제
이 문제에 대해 따로 포스팅을 하고 싶었으나 더 조리있고 자세히 설명하기가 어려워 참고했던 블로그 포스트를 남겨두었다.
https://dawitblog.tistory.com/186
[TypeORM] N+1 문제와 Eager and Lazy Relations
N+1 문제 ORM을 사용하면서 항상 주의해야 할 문제점 중 하나가 N + 1 문제이다. N + 1 문제란, 어떤 테이블의 참조된 데이터를 가져오기 위해 해당 (테이블 조회(1) + 참조된 데이터 조회(N)) 회의 쿼리
dawitblog.tistory.com
예기치 못한 복병이었는데 Query Builder에서 이야기 하겠다.
5. Query Builder
TypeORM을 사용하다보니 자연스럽게 생긴 문제가 있었다.
Sequelize를 사용할때 Join하는 Table의 컬럼을 선별적으로 가져와서 사용할 수 있었는데 TypeORM은 불가능했다.(물론 내가 모르는 방법도 존재할 수 있겠지만 열심히 찾아본 바에 의하면 그렇다.)
RefreshToken과 pinCode(2차 비밀번호)를 이용한 AccessToken 재발급, 그리고 실제 계좌와 관련된 ID, PW를 입력 받았기 때문에, 연결된 테이블의 데이터를 전부 가져오는 것도 보안상 좋지 않아보였고, 가져온 데이터를 재가공해서 프론트로 JSON 형태로 보내주는 것은 불필요한 낭비라고 생각되었다.
필요한 데이터만을 선별적으로 가져올 방법을 찾다보니 Query Builder의 사용이 불가피하다는 것을 알게 되었다.
5.1 장점
- 레고 조립하듯이 원하는 메서드만 사용
사실 강제 아닌 강제로 사용한 것이라 QueryBuilder만의 장점! 같은 느낌은 없었다. 하지만 여러 메소드를 조합(메소드 체이닝!)해서 원하는 데이터를 가져오는 것은 좋았던 것 같다. (하지만 Raw Query를 짤 줄 알았다면...)
5.2 단점
- 초심자에겐 미칠듯이 어려운 학습(원하는 대로 데이터를 뽑아내기가 쉽지 않았다...)
- Raw Query보다 비효율적으로 보이는 Query 실행문들..
처음 사용한 것이라 그런 것일지도 모르겠지만 학습 난이도가 높은 편이었다.(이걸 러닝 커브라고 하던가?)
내가 원하는 대로 데이터를 뽑아내기 위해서 문서를 정독을 몇번이나 하고도 계속 문서와 usage를 뒤지고 다녔던 것 같다. 중꺾마로 이겨냈다.

API를 실행할때도, 테스트할때도 콘솔 창에 보이는 Query 문을 보면 간결하지 못하고 비효율적인 부분이 보인 것 같았다. ~ as ~, 와 같이, Join을 할때 이 테이블의 이부분과, 저 테이블의 저 부분을 가져와서 ~라고 정의해서 출력한다를 하면 될 것 같았지만, 쿼리 실행문이 너무 길어지다보니 내가 원하는 데이터를 가져오지 못해 어디가 문제인지 확인하려 하니 가독성이 떨어져서 문제해결에 애로사항이 있었다.

이것도 단점이라고 해야할진 모르겠지만, 사용하면서 불편한 점이 있었다면 .createQueryBuilder('g')로 가져온 데이터를 쿼리 안에서 가공해서 데이터를 뽑아 올 수 없었다.(내가 모르는 방법이 있을지도 모른다.) g로 해당 테이블 전체 데이터를 가져오고 + left Join의 특정 컬럼을 추가해서 데이터를 가져오는 것은 생각보다 신경이 쓰이는 일이었다..
여러 불편한 점을 해결하기 위해 열심히 구글링을 했으나 내가 정확히 해결하고자 하는 방법은 찾지 못했고 다른 점을 생각해보게 되는 계기가 되기도 했다.
예를 들면 ORM을 프로젝트에 도입할 때 주의할 점이라던지.. 좀 더 깊게 생각해볼 주제인 것 같아서 아직 이해못했지만 남겨놓았다.
https://itchallenger.tistory.com/494
[TypeOrm]ORM을 프로젝트에 도입할 때 주의할점
ORM에 대한 찬반양론 JPA와 TypeORM이 꽤 많이 쓰이는 것으로 인식되고 있지만, ORM의 효용성 여부는 아직까지도 실무자들 사이에 큰 논란이 되고 있다. https://martinfowler.com/bliki/OrmHate.html bliki: OrmHate Ob
itchallenger.tistory.com
'프로젝트 > 8주차 실전 프로젝트' 카테고리의 다른 글
| 1. 기술 스택 선정에 대한 고찰 -5편 그 외 기술, 구현되지 못한 기술- (0) | 2023.02.18 |
|---|---|
| 1. 기술 스택 선정에 대한 고찰 -4편 유저 인증- (0) | 2023.02.18 |
| 1. 기술 스택 선정에 대한 고찰 -3편 웹 서버- (0) | 2023.02.18 |
| 1. 기술 스택 선정에 대한 고찰 -1편 개발 언어- (2) | 2023.02.17 |
| 8주차 실전 프로젝트 "티끌모아 태산" (0) | 2023.02.17 |