[Spring]반정규화를 통한 조회 성능 최적화하기(좋아요, 태그)
2023. 11. 10. 15:13
상황
좋아요 테이블 반정규화
- 그 전 글을 통해 좋아요 기능을 구현할 때 테이블을 어떻게 설계해야할지에 대해 많은 고민을 했다는 사실을 알 수 있을 것이다.
- 좋아요를 구현할 때 좋아요 테이블을 만드는 것은 당연하다. 하지만 그 좋아요가 여러 개에 해당할 때에는? 테이블을 어떻게 해야할 것인지에 대해 많은 고민을 하였다.
- 결국 나는 테이블을 나누는 정규화 대신, 반정규화를 이용하여 테이블을 합쳤다.
데이터 중복을 견디고 조회 성능을 선택하다..
태그
- 비슷한 예시로 태그가 있다.
- 예비부부, 플래너, 포트폴리오, 아이템에서 태그를 참조하고 있다. 기본적으로 N:M 관계이기 때문에 현재는 중간테이블을 두어 태그 테이블과 연결하는 방식을 사용하였다.
- 하지만 이는 과도하게 테이블이 많아지는 결과를 초래하고 성능 향상을 위해서 반 정규화를 활용하였다.
중간 테이블 없이 String으로 태그를 받아 관리하기
- 인스타그램 등이 사용하고 있는 방식이며, 해당 방식을 사용하면 유저 커스텀 태그로도 검색 가능하다.
장점 : 중간 테이블이 필요 없어 테이블 구조 간소화 / 유저 커스텀 태그로도 손쉽게 검색 가능 - string 검색도 mysql의 full text search를 활용하면 파싱과 같은 유연한 검색이 가능하다.
태그 기존 코드의 단점
- 기존 방법에서는 중간테이블을 거쳐야만 원하는 데이터에 접근이 가능했다.
potfolio.getPortfolioTag().tag().getCategory()
- 카테고리에 접근하기 위해서 이렇게 까지해야했다.
- 이런 과정에서 n+1문제가 발생하기 쉽다!
- 현재 방법에서는 portfolio.getPortfolioTag()에서 끝!
- 이는 데미테르 법칙을 지키기도 한다!
느낀점
- 학교 DB 수업시간에 정규화에 대해 몇단계씩 배우다보니 정규화보다 오히려 반 정규화가 성능 향상에 도움이 될 수 있다는 점이 좀 생소했다.
- 반정규화는 다대다 관계에서 중복되는 테이블이 많은 경우, 그래서 과도하게 많은 테이블이 생성되는 경우에 사용하면 좋을 것 같다.
- N+1문제를 해결하기 위해서는 참조 횟수 자체를 줄이는 것도 좋은 방법인 것 같다.
참조
'Spring Boot' 카테고리의 다른 글
[Spring] 검색 시 MySQL full text search 적용하기 (0) | 2023.11.15 |
---|---|
[Spring] serviceImpl 패턴을 활용한 likeService 리팩토링(객체지향원칙) (0) | 2023.11.10 |
[Spring] @Transactional(readOnly = true)를 왜 붙여야 하나요? (0) | 2023.11.10 |
[Spring] Redis Redisson과 AOP를 이용하여 분산락 구현하기 (0) | 2023.10.13 |
[Spring] 좋아요 기능 구현 시 테이블 설계 고민과 성능 테스트 결과 (0) | 2023.10.11 |