[프로젝트] 2. ERD 그리기

공부하는 감자·2024년 1월 10일
0

F-Lab 프로젝트

목록 보기
2/11

ERD

프로젝트를 시작하기 앞서 ERD를 먼저 그려서 도메인 영역을 정의했다. 아래 항목들을 명심하며 그린다.

  • 도메인 설계하기 → 한 눈에 보이도록 영역 분리하여 구분
  • 컨벤션 지킬 것
  • 테이블 레벨의 PK와 FK가 아닌, 연관 관계를 맺어준다. (JPA의 연관 관계 생각)
    • 큼직하게 관계를 맺어주고 디테일 한 관계까지는 그리지 않는다.
    • 그룹으로 묶어주는 것이 목적이다.
    • 경계를 나누는 것!

ERD Tools

💡 https://dbdiagram.io/

여러 툴이 있었는데, 그 중 dbdiagram이라는 사이트에서 ERD를 그릴 수 있었다. 이 사이트를 고른 이유는 다음과 같다.

  • 코드로 작성할 수 있다.
  • 다른 사용자에게 공유가 가능하다.
  • MySQL, MS-SQL, SQL-Server 를 대상으로 export 할 수 있다.

Naming Conventions

💡 MySQL 스타일 가이드와 멘토님의 컨펌을 통해 정했습니다.
https://www.sqlstyle.guide/

공통

  • 예약된 키워드를 피하여, 고유한 이름을 부여한다.
  • 이름의 길이는 최대 30 바이트이다.
  • 이름에는 문자, 숫자, 밑줄만 사용하라.
    • 문자로 시작해야 하며, 밑줄로 끝날 수 없다.
  • 여러 개의 연속된 밑줄은 사용하지 마라.
  • 이름의 공백은 밑줄로 표시한다.
    • 예를 들어, “사용자 정보”는 “사용자_정보”로 작성
  • 약어는 피하되, 사용해야 한다면 일반적으로 이해할 수 있는지 확인하라.
  • PK는 auto_increment를 사용한다. 이를 사용하는 것이 페이징, 무한 스크롤, 조회 등에 편리하다.
  • 모든 테이블에는 생성일자(created_at)와 수정일자(updated_at)이 있어야 한다.
    • 통계를 내거나 정보를 확인할 때 요긴하게 쓰인다.

Uniform suffixes

다음은 SQL에서 보편적인 의미를 갖는 접미사들이다.

  • _id: 기본 키와 같은 고유 식별자
  • _key: PK 대신 외부에 유출할 키 값
  • _seq: 연속된 값 시퀀스
  • _status: 플래그 값 혹은 어떠한 타입의 상태
  • _code: 회원 상태처럼 어떠한 것을 나타내는 코드 값
  • _total: 값의 합계 또는 total
  • _num: 모든 종류의 숫자가 포함되어 있음
  • _name: 이름
  • _date: 어떤 항목의 날짜가 포함된 열
    • 나는 DateTime일 때 이 접미사를 사용했다.
  • _at: Timestamp 타입의 날짜
  • _tolly: 카운트
  • _size: 파일이나 사물의 크기
  • _addr: 기록의 주소, 물리적인 주소뿐만 아니라 논리적인 주소(IP 주소)를 말하기도 한다.

Uniform preffixes

열(column)에 적용되는 접두사이다. 일반적으로 접두사는 잘 사용하지 않는다.

  • {테이블명}_id: 식별자를 표시할 때는 테이블의 명을 앞에 붙인다.
  • is_: true/false 값을 표현하는 tinyint(1)

Tables

  • 집합적인 이름을 사용하거나 복수형으로 사용한다.
  • tbl과 같은 접두사(prefix)는 사용하지 마라.
  • 테이블의 열 중 하나와 동일한 이름은 지정하지 마라.
  • 가능한 관계 테이블의 이름은 두 테이블의 이름을 연결하여 사용하지 마라.
    • 이건 연관된 두 테이블을 서로 매핑 시켜주는 테이블일 경우, 두 테이블의 이름을 이어 붙이게 사용하기로 했다.
    • ERD를 봤을 때 이 테이블이 무슨 테이블인지 알 수 있어야 하기 때문이다.

Columns

  • 항상 단수형 이름을 사용하라.
  • 기본 식별자로 단순히 “id”라고 적는 것은 피하라.
  • 테이블과 이름이 같은 열을 추가하지 마라.
  • 고유 명사와 같이 의미가 없는 경우를 제외하고는 항상 소문자를 사용하라.
  • 다른 테이블에서 가져오는 값(FK로 설정하지 않더라도)은 원래의 열 이름을 그대로 사용한다.

전체 ERD

영역을 확실히 구분하기 위해 테이블 간의 거리를 떨어뜨렸다.

크게 5가지 영역으로 구분되고, 위의 세 영역이 핵심 영역(도메인)이다.

회원 영역

회원 정보 테이블

  • 회원은 이메일과 비밀번호로 가입 및 로그인 가능하다.
  • 외부 계정 연동을 할 경우, 이메일만 저장한다.
    • 가입 이후 비밀번호를 따로 등록할 수 있다.
  • 회원 상태는 정상, 정지, 휴면, 탈퇴 상태가 있다.
  • auto_increments로 user_id를 만들었는데, 이 PK는 외부로 노출하지 않는다. 따라서 외부용 키(user_key)를 따로 저장한다.
    • 외부용 키는 Base64나 Hash 등을 이용해서 생성한다. 정책은 개발하면서 고민해봐야겠다.
    • 자세한 내용은 참고 사이트를 확인할 것.

회원 토큰 테이블

FCM 푸시를 이용해 사용자에게 일대일 문의(채팅)나 펀딩 상태에 따른 알림이 발송할 것이다.

푸시 발송에 필요한 핵심 정보는 다음 두 가지이다.

  • 안드로이드인지 아이폰인지 구분하는 타입 값
  • 디바이스의 토큰 정보 (APP에서 전달해줘야 한다)

문제는 이 토큰 값은 만료가 되었는지 체크해 따로 관리해줘야 한다.

실무에서 유효하지 않은 토큰은 주로 아래 두 경우가 있었다.

  • 앱 삭제 시 유효하지 않은 토큰 값이 된다.
  • 일정 기간(2개월 정도)이 지나면 토큰이 만료된다.

따라서, 주기적으로 확인 후 변경되는 테이블이기에 회원 정보 테이블에서 분리하여 토큰 테이블을 생성했다.

이 토큰 테이블은 추후 Redis를 연동하여 사용할 수 있다.

회원 배송지 테이블

  • 각 회원은 배송지를 여러 군데 등록할 수 있다.
  • 여러 배송지 중 하나를 대표로 설정할 수 있다.
  • 우편번호와 주소를 입력한다.
  • 받는 사람의 이름과 핸드폰 번호를 입력한다.

회원 결제수단 테이블

  • 각 회원은 결제수단을 여러 군데 등록할 수 있다.
  • 여러 결제 수단 중 하나를 대표로 설정할 수 있다.
  • 카드인지 은행인지 구분하여, 카드 번호나 은행 번호를 입력한다.

펀딩 테이블

펀딩 테이블

  • 각 항목은 주로 텀블벅을 참고하여 작성했다.
  • 요금제, 펀딩 분류, 목표 금액, 시작일과 종료일은 필수 값이다.
  • 펀딩 상태는 등록 → 심사 대기 → 심사 종료 → 오픈 예정 → 오픈 → 종료(성공/실패)가 있다.
  • 심사 중이거나 심사가 끝난 후에 오픈 예정으로 돌입한다면, 대부분의 정보는 수정할 수 없다.

창작자 정보 테이블

텀블벅과 와디즈는 프로젝트 별로 정보를 기입할 수 있게 되어 있다. 오히려 그래서 정책을 알기 제일 까다로웠다.

  • 각 프로젝트(펀딩)에 창작자 정보를 입력해야 한다. (1:1)
  • 창작자 정보는 본인인증을 해야 하며, 사업자일 경우 사업자 번호를 등록한다.
    • 원래는 제출해야할 서류나 다른 항목(입금 계좌 등)이 있지만, 고도화 영역으로 넘기고 간소하게 잡았다.
  • 펀딩 글에 보이는 창작자 정보이다.
  • 프로젝트의 창작자를 다른 사용자의 창작자 정보로 변경할 수 있다.
    • 이건 따로 관리자 페이지를 만들어 관리해야 한다.

펀딩 태그 테이블

  • 펀딩 글에는 검색에 용이하게 할 수 있도록 키워드를 입력할 수 있다.
  • 키워드는 15자 이내여야 한다.

펀딩 아이템 테이블

  • 펀딩에서 판매할 상품들의 정보가 담겨 있다.
  • 각 상품의 이름과 옵션이 있는지 구분한다.
  • 옵션 상태는 없음/주관식/객관식 총 3개이다.

예를 들어, 쥬얼리 펀딩 글이 있다고 하자. 그렇다면 펀딩 아이템은 각각 다음과 같이 있을 수 있다.

  • 은 귀걸이
  • 금 귀걸이
  • 보석 귀걸이

펀딩 아이템 옵션 테이블

  • 옵션이 있는 아이템이 있을 경우 등록한다.

위의 예시와 같을 때는, 다음과 같은 옵션이 있을 수 있다.

  • 은 귀걸이의 옵션
    • 3mm
    • 5mm
    • 7mm
    • 9mm

펀딩 리워드 테이블

  • 실제 사용자가 후원할 수 있는 항목이다.
  • 낱개로 등록된 아이템들을 조합하여 가격을 책정해 매긴다.
  • 각 리워드는 개인 구매 가능 수량 혹은 전체 수량을 설정할 수 있다.
  • 리워드는 온라인으로 전달될 수도 있고 실물로 배송될 수도 있다.

예를 들어 다음과 같은 리워드들이 있을 수 있다.

  • 리워드 A
    • 은 귀걸이 1개
  • 리워드 B
    • 금 귀걸이 1개
  • 리워드 C
    • 보석 귀걸이 1개
  • 리워드 ALL 1
    • 은 귀걸이 1개
    • 금 귀걸이 1개
    • 보석 귀걸이 1개
  • 리워드 ALL 2
    • 은 귀걸이 2개
    • 금 귀걸이 2개
    • 보석 귀걸이 2개

리워드-아이템 매핑 테이블

  • 흐름 상 아이템을 먼저 등록한 후에 리워드를 등록해야 한다.
  • 리워드는 여러 개의 아이템을 가지고 있을 수 있다.

따라서 매핑 테이블을 따로 만들었다.

후원 테이블

후원 (정보) 테이블

  • 사용자는 여러 펀딩을 후원할 수 있다.
  • 펀딩은 여러 후원 내역을 가질 수 있다.
  • 누가, 어떤 펀딩에서, 어떤 리워드를 선택했는지 정보를 가진다.
  • 후원번호를 사용자(창작자/후원자)에게 보여주기 위해, 외부에 보여줄 용도의 열을 만들었다.
    • support_key: 총 7글자로, 숫자나 영문을 섞어 만들 생각이다.
  • 후원 상태는 후원예약/후원성공/후원무산 총 3개가 있다.

후원 결제 테이블

  • 후원이 성공하면 펀딩 종료 후 다음날에 자동 결제된다.
  • 결제 실패하면 일정 일 뒤에 다시 시도한다.
  • 이때, 결제 수단은 사용자가 선택하여 등록해야 한다.
    • 여기서 선택한 결제 수단의 ‘회원 결제 수단 테이블’의 하나이다.
  • 결제 상태는 결제대기/결제성공/결제실패 총 3개가 있다.

후원 배송 테이블

  • 결제가 완료되면 지정된 일(펀딩 테이블의 발송일)
  • 예상 전달일(각 리워드 별로 지정)에 배송이 시작된다.
  • 배송은 창작자가 직접 업데이트 한다.
    • 배송 업체를 끼고 할 수도 있다.
    • 이건 좀 더 알아봐야 할 거 같다.
  • 배송 상태는 전달예정/배송시작/배송종료 총 3개가 있다.

1:1 채팅 테이블

후원자가 창작자에게 일대일로 문의를 넣을 수 있다. 채팅 형식으로 되어 있으며, 이를 위해 간략하게 구상해봤다.

FCM 푸시를 연동하면서 변경될 수 있다.

기타

파일 테이블

펀딩을 등록할 때 썸네일 이미지나, 본문에 이미지 혹은 영상 등을 넣을 수 있다. 이러한 파일 정보를 저장하기 위한 테이블이다.

  • 각 파일은 서버에 저장하고, 파일 정보를 테이블에 저장한다.
  • 파일 이름은 저장될 때 UUID로 변환하여 저장한다.
  • 파일의 원래 이름, 파일의 변환된 이름, 파일 경로는 필수로 존재해야 한다.
  • 파일은 그룹으로 크게 묶이고, 그룹 안에서 식별자를 주어 구분한다.
    • 그룹: 사용자 프로필 사진/펀딩 썸네일 이미지/펀딩 본문 이미지 등
    • 식별자: 사용자 회원번호/펀딩 번호/펀딩 번호

로그 테이블

원래는 증적 자료를 위해 로그를 쌓아야 한다. 통계에 사용하기도 하고, 배송 상태나 접속 로그 등 이곳 저곳에 사용된다.

그러나 처음부터 설계를 디테일하게 잡는 것보다는 핵심 기능(도메인)에 집중해서 개발하고 이후에 차례차례 덧붙여 나가는 게 좋을 거 같아서 지금은 제외했다.

Reference

SQL style guide by Simon Holywell

Table column(attribute) 네이밍

MySQL 데이터베이스명, 테이블명, 컬럼명은 어떻게 지어야 할까?

MySQL Naming Convention (번역)

profile
책을 읽거나 강의를 들으며 공부한 내용을 정리합니다. 가끔 개발하는데 있었던 이슈도 올립니다.

0개의 댓글

관련 채용 정보