이번 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 | ||||
이메일 | 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절의 검색 조건으로 추가하기가 용이할 것이라 판단했다. - 인원 상태에 대해 모임이 처음 생성되면 ``모집중`/`을 기본값으로 설정했다.
연관관계
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 관계로 만들었다.
Version2 - Location 테이블 삭제
변경 사항
- ``Location`/`테이블을 삭제하고 Program 클래스 내의 Enum으로 선언했다.
자세한 내용은 이 글을 참고!
Version3 - Image 컬럼을 테이블로 분리, Refresh Token 테이블 추가
변경 사항
- DB에 이미지 Binary data뿐만 아니라 파일 이름, 사이즈, 타입 등도 같이 저장하고, 이후 하나의 모임(회원)에 여러 이미지를 업로드하는 방식으로 확장할 것을 대비해 Image 테이블을 따로 분리했다.
자세한 내용은 이 글을 참고!
- 로그인 처리를 위해 발급하는 Refresh_Token 테이블 추가
'프로젝트 > DailycluB' 카테고리의 다른 글
검색/필터링 기능 (Querydsl) (0) | 2022.10.02 |
---|---|
프로그램 상세 페이지에서의 API 스펙 고민 (0) | 2022.09.22 |
Entity와 DTO의 사용 범위는 어떻게 해야 할까? (0) | 2022.09.22 |
지역 정보를 Enum으로 할까 테이블로 할까? (@Converter) (0) | 2022.09.19 |
날짜/시간 정보 API로 주고 받기 (0) | 2022.09.18 |
댓글