해결된 질문
작성
·
95
0
안녕하세요.
예전부터 목록 조회 관련 궁금한게 있었는데 어떻게 설계하는게 좋은지 몰라서 문의드립니다.
강의의 예제처럼 하나의 테이블에 대해서 게시글 목록을 보여주는 기능들은 어떻게 해야하는지 잘 이해가 됩니다.
근데 보통 개발을 하다 보면 리스트를 보여주는 경우가 많잖아요.
그런 ux들을 보면 3~4개 이상의 테이블을 join하고, 여러 테이블에 대한 필터링도 하고, 여러 테이블의 여러 컬럼에 대해서도 정렬까지 하고, 페이지네이션까지 해야 하는 경우가 많았던 것 같습니다.
거기에 N:M구조를 join하는 경우가 있다면...
이런 기능들을 구현하려면 아무리 머리를 굴려도 full scan이 발생할 수 밖에 없을 거 같은데요.
필터링이나 정렬이 각각 다른 테이블 기준으로 선택이 된다면 속도가 나올 수 없어 보입니다.
대책을 생각해보면
그냥 원래 느리니까 db 성능을 믿고 그냥 join해서 보여줄수도 있고,
아니면 전체를 join 한 새로운 테이블을 만들기도 하는건지 궁금하네요. 근데 만약 새로운 테이블을 만들었더라도 N:M구조가 있었다면 또 1:N 구조가 여전히 남아있을테니 또 성능이 좋지 않을것이기에 생각이 많아지네요.
답변 2
2
굿데이님, 안녕하세요!
강의에서 채택한 프로젝트 구조가 MSA/DDD/분산 DB이기 때문에,
코드와 데이터가 모두 물리적으로 분리되어 있어서 그러한 어려움이 더욱 크게 와닿을 것 같습니다.
말씀주신 내용은 실무에서도 계속 부딪치는 어려움이고, 여러 해결 전략 간 트레이드오프 적절히 판단하여 채택하는 과정이 필요하기 때문에, 충분히 궁금증이 생길만한 내용입니다.
다만, 여러가지 이론과 방법론, 경험, 전략들을 모두 통틀어서 활용해야 하기 때문에 어디서부터 설명을 드려야할지.. 여기서 잠깐의 답변으로 풀어내는게 쉽진 않네요..!
제 다른 강의 중에 "분산 데이터 모델링"이 있는데, 이것도 빙산의 일각이지만 약간의 참고는 될 수 있을 것 같습니다. (짧고 별 내용 없어보이지만, 이러한 고민을 해본 단계에 와서야 들었을 때 효용이 있기 때문에, 난이도는 아주 높을 수 있습니다.)
감이 잡힐 만한 몇 가지 관점에 대해서만 두서 없이 나열해보겠습니다.
JOIN은 반드시 데이터베이스의 기능이 아님. 애플리케이션에서 JOIN할 수도 있음.
하지만 정렬/필터링에 대해서는 반드시 데이터 자체가 정렬 또는 필터링 되어 있어야함. 이러한 부분은 애플리케이션에서 처리할 수 없음(풀스캔에 대한 성능 이슈는 인지하고 계신 것 같아서 생략. 반드시 DB 테이블 풀스캔뿐만 아니라, 애플리케이션으로 모두 불러와서 직접 정렬/필터링하는 것도 풀스캔이라고 볼 수 있습니다.)
정렬/필터링이 필요하다면, 식별자와 정렬/필터링에 필요한 컬럼만 뽑아내서, 인덱스를 위한 별도 테이블을 만들 수도 있음.
어떤 도메인이 인덱스 테이블의 관리 주체가 되는지에 대한 고민은 필요함(분산 데이터 모델링 강의 참고)
애플리케이션에서 처리할 수 없는 정렬/필터링에 대한 쿼리는 인덱스 테이블에서 조회하여 식별자만 뽑아오고, 이후에는 식별자를 이용하여 필요한 데이터들을 분산 환경에서 하나씩 가져오면 됨.
다만 이러한 조합 과정이 많아질수록 I/O가 복잡하고 많아지므로, 성능을 고려한 개발이 필요함.
웹플럭스 또는 멀티스레드를 이용하여 병렬로 처리할 수도 있고, CQRS 개념을 활용하여 비정규화된 쿼리 모델(전체를 조인할 수도 있고, 일부만 조인할 수도 있고)을 만들어둘 수도 있음. I/O 자체를 줄이고 싶다면, 적절한 판단 하에 단일 DB 또는 단일 애플리케이션으로 데이터를 합쳐서 질의 비용을 낮출 수도 있음.
복잡한 클라이언트 요구사항(보통 서비스 화면)을 만족하는 쿼리를 위해서는 여러 도메인에 질의가 필요할 수 있음.
데이터 조합을 위한 하나의 레이어를 만들 수도 있고, 클라이언트에 도메인별 분리 호출을 요청해서 화면 단에서 직접 조인을 수행할 수도 있음.
또는, 도메인 간 단방향성을 유지한다면 API에서 필요한 응답을 모두 만들어낼 수도 있음. 양방향이 생긴다면, 이벤트 또는 데이터 푸시를 통해서 질의를 받는 마이크로서비스가 화면에 필요한 모든 데이터를 복제하여 가지고 있을 수도 있음. 또는, 도메인에 대한 관점을 달리하여, 타 도메인에 분산되어 있던 데이터를 현 도메인으로 통합해올 수도 있음.
정리하면, 성능 이슈가 생기는 정렬/필터링에 대해서는 이를 위한 인덱스 테이블을 별도로 만들어두고, 필요한 데이터는 애플리케이션 조인해서 내려준다. 이 때, 성능을 고려한 개발은 필요하다. 그리고 복잡한 클라이언트 요구사항을 위해서는, 데이터 조합 레이어/클라이언트에서 분리 호출/이벤트를 활용한 데이터 복제/도메인 관점 달리하기 등 다양한 방법을 통해서 데이터를 조인할 수 있다.
문제를 해결하기 위한 여러가지 방법이 있지만, 각각 장단점이 있고, 화면마다 또는 상황마다 또는 클라이언트와의 협의 방식에 따라서 모두 달라질 수 있는 부분이라, 구체적인 기준을 만들기는 어려운 것 같습니다.
이러한 관점을 이해하고 직접 경험해나가야 더욱 와닿을 수 있는 부분인 것 같네요!
0
안녕하세요, 인프런 AI 인턴입니다. 굿데이님.
복잡한 조인 쿼리와 테이블 설계에 대한 질문을 주셨네요. 데이터베이스 설계와 조인 최적화는 특히 대규모 시스템에서 중요한 고려 사항입니다. 몇 가지 관점에서 접근해보겠습니다.
인덱스(Index) 설정:
쓰기 부담을 줄이는 방법:
데이터 중복(De-Normalization):
뷰(View) 사용:
조인의 종류 및 방법:
외부 툴 및 캐시 사용:
이와 관련해서 중앙 문제를 다룬 기존 답변들을 참조하실 수 있습니다:
- 복잡한 조인 쿼리 최적화 전략 (게시글 제목)
- 다중 테이블 및 N:M 관계를 다루는 방법 (게시글 제목)
현재 제공하는 답변이 다소 일반적인 것이며, 구체적인 설계는 실제 응용에서의 요구사항에 따라 최적화되어야 할 것입니다.
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.
친절한 답변 감사드립니다.
많은 도움이 됩니다.