본문 바로가기
프로젝트/DailycluB

DB Schema 설계

by 넬준 2022. 11. 3.

 

 

 

 이번 Dailyclub에서 DB Schema 설계를 처음에 어떤 식으로 했는지, 그리고 개발이 진행되면서 어떤 식으로 변경했는지 정리하고자 한다.

 

Version1

 일단 사용자 요구사항과 화면 설계를 바탕으로 필요한 엔티티를 정했다.

User
Program
Notice
Bookmark
Notification
Message
Location

 여기서 ``User`/`와 ``Program`/`이 메인 엔티티가 된다.

 

그리고 기본적으로 모든 엔티티 테이블에 식별자인 ``id`/`컬럼과 ``created_date`/`, ``modified_date`/`컬럼을 넣었다.

(``Location`/`테이블은 대한민국에 존재하는 지역을 테이블이라 어플리케이션이 켜질 때 초기값 세팅하고나면 운영 중에는 추가되거나 변경될 일이 없어서 ``created_date`/`, ``modified_date`/`컬럼을 넣지 않았다.)

테이블 소개

1. USERS

컬럼명 컬럼ID 타입 및 길이 Not Null PK FK AUTO_INCREMENT SET_DEFAULT UNIQUE
ID id INT Y Y   Y    
로그인ID login_id VARCHAR(50) Y         Y
닉네임 nickname VARCHAR(50) Y         Y
이메일 email VARCHAR(50) Y         Y
비밀번호 password VARCHAR(50) Y          
회원 사진 picture BLOB         Y  
자기소개 introduction TEXT            
친절 퍼센트 kind INT Y          
권한 role VARCHAR(50) Y          
생성일자 created_date TIMESTAMP Y          
수정일자 modified_date TIMESTAMP            
  • 처음 개발 환경에선 h2 데이터베이스를 사용했는데 ``User`/`가 h2에서 예약어라 테이블명을 ``Users`/`로 지정했다. 
  • 회원당 사진을 하나만 설정할 수 있게 할거라서 ``Users`/`테이블에  BLOB 자료형의 ``picture`/`컬럼을 추가했다.
    그리고 회원이 사진을 설정하지 않으면 기본 이미지를 사용할 예정이라 DEFAULT 값을 설정하기로 했다.
  • 회원 사진, 자기소개는 처음 회원가입 시 작성하지 않고, 회원가입 후 마이페이지에서 회원정보수정으로 추가하는 값이라서 Not Null 조건을 넣지 않았다.
  • 권한은 Spring Security를 적용할 걸 고려해서 ``ROLE_USER`/`, ``ROLE_ADMIN`/`형태로 값을 저장한다.
  • 로그인ID, 닉네임, 이메일은 중복값을 허용하지 않아 UNIQUE 조건을 추가했다.

 

2. Program

컬럼명 컬럼ID 타입 및 길이 Not Null PK FK AUTO_INCREMENT SET_DEFAULT UNIQUE
ID id INT Y Y   Y    
회원번호 user_id INT Y   Y      
제목 title VARCHAR(100) Y          
본문 text TEXT Y          
모집 인원 num_apply INT Y          
모임 사진 picture BLOB         Y  
지역 location_id INT Y   Y      
모임 날짜 program_date TIMESTAMP Y          
최소 친절 퍼센트 min_kind INT Y          
인원 상태 num_status VARCHAR(20) Y       Y  
생성일자 created_date TIMESTAMP Y          
수정일자 modified_date TIMESTAMP            
  • 모임 사진도 회원 사진과 마찬가지로 하나만 설정할 수 있기 때문에 ``Program`/`테이블에  BLOB 자료형의 ``picture`/`컬럼을 추가했다.
    그리고 모임 등록 시 이미지를 업로드하지 않으면 기본 이미지를 사용할 예정이라 DEFAULT 값을 설정하기로 했다.
  • 사용자에게 제공해야 하는 모임 상태 정보가 "얼만큼 모집인원이 남았는지""모임 날짜까지 남은 기간"이다.
    이를 현재 모집 인원이 몇 명인지, 남은 모집 인원에 따라 ``모집중`/` ``마감임박`/` ``마감`/`이라고 인원 상태를 따로 알려주고, 날짜에 대해서는 모임 날짜까지 며칠이 남았는지 보여주는 것으로 UI를 정했다.
    그리고 나서, 모집 인원과 신청 인원을 비교해 인원 상태를 계산하는 로직을 백엔드에서 둘지, 프론트엔드에 둘지 고민했다. 회원이 모임을 신청/취소할 때마다 백엔드에서 로직을 실행해 컬럼에 미리 저장하거나, 아니면 백엔드는 신청 인원을 응답 API에 담아 넘겨만 주고, 프론트엔드 쪽에서 로직을 실행하는 것이다. 결론은 백엔드에 두기로 했다. 인원상태에 대한 필터링 기능을 넣을 생각이라 컬럼에 인원 상태 값을 저장하고 있으면 DB 조회 때 WHERE절의 검색 조건으로 추가하기가 용이할 것이라 판단했다.
  • 인원 상태에 대해 모임이 처음 생성되면 ``모집중`/`을 기본값으로 설정했다.

모임 상태 정보를 보여주는 UI

 

연관관계

1:N 관계

  • USERS - PROGRAM, NOTIFICATION, BOOKMARK, MESSAGE, NOTICE
  • PROGRAM - NOTIFICATION, BOOKMARK
  • LOCATION - PROGRAM

N:M 관계

  • USERS - PROGRAM

 작성자와 모임은 1:N 관계이고, 신청자와 모임은 N:M 관계이다. 따라서 ``APPLY_USER`/` 조인 테이블을 두어 두 개의 1:N 관계로 만들었다.

 

version1

 

Version2 - Location 테이블 삭제

변경 사항

  • ``Location`/`테이블을 삭제하고 Program 클래스 내의 Enum으로 선언했다.
    자세한 내용은 이 글을 참고!
 

지역 정보를 Enum으로 할까 테이블로 할까? (@Converter)

프로그램 진행 장소에 대한 지역 정보를 어떤 식으로 저장할까 고민이 있었다. 별도의 테이블을 두어 foreign key로 연결 처음에는 프로그램 테이블과 별도로 지역 테이블을 두어 프로그램 테이블

nelljundev.tistory.com

 

 

Version3 - Image 컬럼을 테이블로 분리, Refresh Token 테이블 추가

변경 사항

  • DB에 이미지 Binary data뿐만 아니라 파일 이름, 사이즈, 타입 등도 같이 저장하고, 이후 하나의 모임(회원)에 여러 이미지를 업로드하는 방식으로 확장할 것을 대비해 Image 테이블을 따로 분리했다.
    자세한 내용은 이 글을 참고!
 

프로그램/유저 이미지 업로드

이미지를 프론트 쪽에서 받는 방식은 다음과 같다. 1. Multipart/form-data 형식으로 모든 정보를 한 번에 보낸다. 2. 사진만 별도로 Mutlipart로 먼저 요청 보내서 서버에 사진 저장 후 응답받은 사진 정

nelljundev.tistory.com

  • 로그인 처리를 위해 발급하는 Refresh_Token 테이블 추가

 

version3

 

댓글