[MSA] 어떻게 데이터베이스를 설계할 것인가?

Dev StoryTeller·2025년 3월 27일
post-thumbnail

MSA로 개인 프로젝트를 진행(Kubernetes_Development)하면서 가장 당황했던 부분이었다
포스트 서비스를 구현에서 연관관계 설정할 때 발생한 문제였다


🤔 어떤게 문제인데?

우선 서비스 소개를 간단히 하도록 하겠다
익히 알고있는 블로그 서비스와 동일하며, 웹 에디터(Quill)를 통해 이미지, 글을 작성하고 포스트를 발행하는 그런 간단한 서비스이다
웹 에디터 상에서 이미지 업로드를 통해 서버에 저장하고,
포스트 등록 버튼을 통해 업로드 된 이미지와 글들을 한데 묶어서 포스트로 저장하는 방식이다

해당 서비스를 구축할 때 파일 업로드와 포스트 등록은 별도의 기능으로, 당연히 DB 또한 따로 관리된다
또한 업로드 된 파일들을 하나의 포스트에 속해있는 멤버로 관리되고 있다
여기서 문제는

이미지 업로드와 관련된 파일 DB포스트 자체를 의미하는 포스트 DB에 속해있다

라는 것을 어떻게 표현할 것인가? 였다


🍎 모놀리식 구조의 DB 관계

기존 모놀리식에서는 사실 걱정할 필요가 없다
모두 같은 서버 안에 있기 때문에, 연관관계를 맺어 구축하면 된다

이 부분의 설명은 건너 뛰도록 하겠다


🍊 MSA 구조의 DB 관계

우선 File 서비스는 Post에 속해있지 않은 공통 기능이기에 분리되어야 한다
이 말은 다른 서버로 구축되어야 한다는 것이고, 이는 곧 연관 관계를 맺을 수 없다는 것을 의미한다
우선 결론부터 말하자면 다음과 같이 구축하였다

  • File DB
  • Post DB

이제 위 구조에 대해 의문을 하나씩 해결하며 살펴보자


💡 연관관계 처리 방식?

연관관계를 가진다는 것은 같은 애그리거트에 속한다는 것이고, 이는 즉 강한 결합력을 가진다는 것이다
하지만 파일 기능과 포스트 기능은 당연히 별도로 결합력이 존재해선 안된다

이를 위해 여러 방법을 찾아보았지만, 가장 간편한 방법이 바로 id를 갖는 방식이었다
PostImageEntity의 uuid 컬럼이 바로 그것으로, 포스트 등록 시에 file id를 삽입하여 마치 연관관계와 동일한 효과를 갖는다


💡 FileItem의 mappedBy는 뭐지?

JPA의 연관관계의 주인을 명시한 컬럼이다
사실 DB 입장에선 연관관계의 주인이란 개념은 없다
A 테이블이 B 테이블의 데이터를 가져다 쓴다는 외래키의 개념만이 존재한다
이는 단지 ORM(JPA)으로 Table -> Entity로 옮겨지면서 필요에 의해 생겨난 개념이다

이러한 이유로 연관관계를 사용하지 않는 해당 서비스에서는 만들지 않으려고 했으나,
다음의 이유로 어쩔 수 없이 추가하였다

  • ❗️ 불필요한 조회 작업
    예를 들어 하나의 포스트가 관리하는 파일들에 대한 조회 및 삭제 작업을 한다고 하자
    우선 첫번째로 포스트가 가진 파일 ID를 조회해야 한다
    다른 테이블에 있든 포스트 테이블 컬럼에 있든 찾아줘야 한다

  • ❗️ 늘어나는 HTTP 사이즈
    다음으로 찾아낸 File ID들을 HTTP에 담아 전송해야 한다
    한두개라면 괜찮지만 파일이 여러개라면 요청 HTTP 크기가 매우 커질 것이다
    이는 매우 좋지 않은 방식이다

하지만 mappedBy 컬럼이 생기는 순간 위의 2가지 문제는 모두 해결된다
불필요한 File ID 조회 작업없이 Post ID 하나로 파일 데이터들을 손쉽게 다룰 수 있다


💡 PostImageEntity에 중복된 컬럼이 있는데?

그렇다. 사실 id 컬럼과 File ID를 의미하는 uuid 컬럼만 존재하면 된다
굳이 File 테이블의 name과 path까지 넣은 이유는 API 요청을 최소화하기 위함이다

  • ❗️ 불필요한 API 요청!
    원래대로라면 uuid를 통해 File 서비스에서 필요한 데이터들을 가져오면 된다
    하지만 포스트 조회는 굉장히 자주 일어난다
    이 때마다 추가로 API 요청을 날리는 것은 매우 부하가 걸리는 작업이다

이를 위해 ImageEntity에 미리 필요한 컬럼을 추가해놓는다면, 별도의 API 요청없이 자체 서비스 내에서 해결할 수 있게된다
물론 File RUD 마다 동일한 작업을 Image 테이블에도 해줘야 하지만, 적어도 매번 API 요청을 날리는 것보단 비용이 훨씬 덜하다


🔎 후기..?

막상 회고를 하며 적어놓고보니 큰 고민이 아닌 것처럼 느껴진다
하지만

파일 업로드는 곧 포스트 등록!

이런 당연시하던 연결 고리를 떼어놓고 생각하자니 생각의 전환이 어려웠던 것 같다
무엇보다 어려웠던 것은 하나로 흘러가던 서비스들의 흐름을 독립적으로 분리하여 생각해보자는 것이 가장 힘들었다
이에 관련해서는 다음 글에서 설명하도록 하겠다

profile
개발을 이야기하는 개발자입니다

0개의 댓글