이번 프로젝트에서는 사용자들이 방(채널)을 생성하고 그 안에 다수의 게스트를 초대하여 특정 위치와 경로 정보를 공유할 수 있는 기능을 구현 중입니다. 사용자는 방을 만들어 자신이 호스트가 되고, 방 안에 여러 게스트가 위치 및 경로 정보를 공유하며 참여할 수 있습니다.
이때 PostgreSQL을 사용해 방과 게스트 데이터를 효율적으로 저장하고 관리하고자 channel
테이블과 guest
테이블을 설계했으며, 두 테이블이 서로 연결된 구조로 설계되어야 했습니다.
처음 설계한 erd는 아래와 같았습니다. (channel 테이블에 게스트 객체 배열
이 존재합니다)
처음에는 방과 게스트 정보 모두를 channel
테이블에 JSONB 타입으로 넣어 guests
라는 컬럼으로 관리하고자 했습니다. 이렇게 하면 한 번의 쿼리로 channel
테이블에서 방 정보와 게스트 정보를 모두 조회할 수 있어 단순하게 보였습니다. 그러나 이렇게 guests
정보를 포함하는 방식에는 몇 가지 문제점이 발견되었습니다:
channel
테이블에 넣으면, 게스트 정보에 수정 사항이 생길 때마다 channel
테이블에 있는 JSON 데이터를 업데이트해야 합니다. 이는 데이터 중복 및 불필요한 수정 작업이 필요하다는 문제점이 있습니다.channel
테이블 안에 JSON으로 들어가면, 테이블 구조가 고정되지 않아 확장하기 어렵습니다. 예를 들어 게스트 정보에 새로운 속성이 추가된다면, channel
테이블 안의 JSON 구조를 모두 수정해야 하는 부담이 생깁니다.channel
테이블의 데이터를 조회할 때마다 불필요하게 큰 JSON 데이터를 가져오게 되어 성능이 저하될 수 있습니다.channel
테이블에 데이터를 저장하면 아래와 같이 guests
가 저장되었는데, 너무 비효율적이라는 생각이 들었습니다.
이러한 이유로 고민 끝에 channel
테이블에서 guests
컬럼을 제거하고, guest
테이블을 독립적으로 구성하기로 결정했습니다.
각 게스트는 guest
테이블에 저장되며, channel_id
로 해당 방을 참조하는 관계를 가지게 됩니다.
channel
테이블: 채널의 고유 ID, 이름, 호스트 ID(host_id
), 생성 날짜(generated_at
) 등의 채널 자체 정보만 포함합니다.guest
테이블: 채널과 연결된 각 게스트의 정보를 관리합니다. guest
테이블에는 channel_id
외에도 start_location
, end_location
, path
, marker_style
, host_id
등의 필드가 JSONB 형태로 저장되어 각 게스트의 구체적인 정보를 유연하게 관리할 수 있습니다.이렇게 테이블을 분리하면서 가장 크게 유지보수
를 하는 데에 훨씬 편리해진다는 장점을 가질 수 있었습니다. 얻게된 이점에 대해 간략히 정리해보면 아래 3가지 정도로 정리됩니다.
guest
테이블만 수정하면 되므로 channel
테이블은 영향을 받지 않게 됩니다.guest
테이블만 수정하면 되므로, 유지보수가 쉬워졌습니다.channel
테이블을 조회할 때는 방에 대한 기본 정보만 가져오고, 게스트 정보가 필요할 때만 guest
테이블을 조인하여 조회할 수 있습니다.초기 설계 때는 channel
테이블에 게스트 정보를 JSON으로 포함하는 것이 간단해 보였지만, 실질적으로는 유지보수와 성능에 문제가 생길 수 있다는 것을 깨달았습니다. 최종적으로 guest
테이블을 독립적으로 관리하는 방식으로 전환하면서 설계의 유연성과 확장성을 확보할 수 있었습니다.
이와 같은 데이터베이스 설계 결정은 프로젝트의 향후 확장성에 큰 영향을 주기 때문에 신중히 고려할 필요가 있었습니다. 조금 더 깊게 고려해볼 필요가 있다는 생각을 한번 더 하게 된 계기가 되었습니다. (물론 나름 처음 설계할 때도 엄청 고민한 거였는데..... 하하.....ㅜㅜ)