Skip to content

MySQL 데이터베이스 모델링 논의

Sangwoo Park edited this page Jul 20, 2021 · 3 revisions

MySQL 데이터베이스 모델링에서 테이블 생성과 관계 정의에 대해 논의한 내용을 정리합니다.

요구사항

  1. 각 회원에 대한 정보를 저장합니다.
  2. 스터디 그룹에 대한 정보를 저장합니다.
  3. 회원은 여러 그룹에 가입할 수 있습니다.
  4. 그룹에 속한 회원은 관리자와 구성원으로 나뉩니다.

논의내용

먼저 요구사항 1번과 2번에 해당하는 user 테이블과 study_group 테이블을 아래와 같이 생성했습니다. 그리고 하나의 사용자가 여러 스터디 그룹을 가입할 수 있어야 하므로 user 테이블과 study_group테이블은 1:N 관계로 정의했습니다.

img-01

사용자가 '진행 중인 스터디'와 '참여 중인 스터디'를 어떻게 구별할까?

그런데 문제는 "user테이블의 id 값을 통해 사용자가 가입한 study_group 정보를 어떻게 구별해서 가져올 수 있을까?"였습니다. 만약 '진행 중인 스터디'와 '참여 중인 스터디'를 구별하기 위해서 study_group 테이블에 lead_user_id, join_user_id와 같은 컬럼을 추가하고 ,로 구별한 문자열을 저장한다면, 결국 모든 study_group에서 해당 사용자의 id값을 탐색하게 됩니다. study_group이 많을수록 성능 저하가 예상되는 방식이었습니다.

이에 대한 해결책을 모색한 결과, user테이블과 study_group 테이블의 id를 참조하는 group_member 테이블을 생성했습니다. 여기에서 사용자의 ID의 따라 user_id 컬럼을 정렬하고 탐색하면, 해당하는 행의 study_group_id를 통해 사용자가 가입한 그룹을 빠르게 찾을 수 있습니다. 그 그룹의 관리자인지 구성원인지의 여부는 is_manager 값을 통해서 파악할 수 있게 됩니다.

img-02

어떤 스터디의 관리자가 누구인지 어떻게 찾을까?

그런데 여기에서 또 다른 문제는 어떤 study_group의 관리자가 누군지 찾아야 한다면, 해당 study_groupid와 동일하면서 is_managertrue인 행을 찾아 얻은 user_id 값으로 user 테이블의 nickname을 한 번 더 찾는 과정이 필요합니다. 이 과정을 단축하기 위해 study_groupuser 테이블을 참조하는 manager를 추가했습니다. 해당 스터디 그룹의 id만 안다면 바로 관리자를 알 수 있는 것입니다.

img-03

그룹에 속한 구성원들의 닉네임은 어떻게 가져올까?

예를 들어 스터디 관리 페이지에서 '진행 중인 그룹'의 구성원 닉네임을 가져오려면 사용자 ID로 study_groupmanager를 탐색하고, 해당 그룹의 멤버를 group_member 테이블에서 각각 찾아 user 테이블로 가는 단계를 거쳐야 합니다. 그룹의 멤버가 많아질수록 성능 저하가 예상되었습니다. 그래서 group_member 테이블에서 user 테이블의 unique key인 nickname을 참조하게 했습니다. 또한 user 테이블의 nickname이 변경되면 group_member 테이블의 'nickname'도 함께 변경되어야 하므로, group_member 테이블에 ON DELETE CASCADEON UPDATE CASCADE를 추가했습니다.

  CONSTRAINT `fk_group_member_user2`
    FOREIGN KEY (`nickname`)
    REFERENCES `wooggooms`.`user` (`nickname`)
    ON DELETE CASCADE
    ON UPDATE CASCADE