[개인 프로젝트] DB 스키마 작성

양찌·2021년 12월 17일
2

ProjectDiary

목록 보기
1/5
post-thumbnail

DB 스키마 작성하는데 3일이 소요되었다. 처음에 한 3시간 정도면 되겠지라고 생각하였던게 큰 오산이였다.

처음에 필요한 테이블을 생각하였다. 그 다음에 각 테이블마다 어떤 필드가 필요할지 작성했다. 그런데!!!😱 그렇게 하니 이 테이블에 이 값이 들어가는 것이 맞는지? 아니면 또 다른 테이블을 만들어야 하는지?에 대해서 문제를 봉착하였다.🥺

필자의 경우, 클래스의 콘텐츠는 클래스 소개, 커리큘럼, 강사 소개 이렇게 3개의 값으로 나뉜다. 그런데 이 3개의 값 역시 또 다른 하위 값을 갖는다. 특히 클래스 소개 같은 경우 여러개의 이미지가 들어가고 그에 맞는 글이 들어가야하는 상황이다. 여기에서 가장 고민을 했던 부분은 강사 사용자가 글을 작성하고 이미지를 삽입하는 순서와 동일한 순서로 데이터가 심어져야한다...였다..

✋ 문제

  • 여러 개의 이미지를 한 테이블에 넣어야 하나? 이미지1, 이미지2 이런식으로?? 아니면 값을 배열로 넣나??
  • 여러 개의 이미지에 대응하는 글 들은 어떻게 저장하나?
  • 그 이미지와 글들을 어떻게 순서대로 렌더링 시킬 것인가?

꼬리의 꼬리를 무는 질문들이 내 머리속에 가득찼다.

그래서 우선 가장 기본적인 것, DB 모델링을 어떻게 하는지 부터 유투버에서 찾아보았다.

참고 영상 링크
MySQL - 데이터 모델 설계, 실무에서는 이렇게 프로젝트 시작과 설계를 한다!




위 영상을 토대로 DB모델링에 대해 정리하자면 이와 같았다.

✍ DB 모델링 과정

  • 1단계: 개념적(conceptual, contextual) 모델링 -> Entiti 도출
  • 2단계: 논리적(Logical) 모델링
    -> Data 구조 및 속성 정의
    -> 무결성 정의 및 정규화(데이터의 중복을 최소화하는 것)
  • 3단계: 물리적(Physical) 모델링
    -> 실제로 코드화 하는 것



1. 정규화 (Normal Form, NF)

정규화의 목적, 목표

"중복 데이터를 없애고 관계를 단순하게 가져 간다!"

  • 원자성

    모든 속성은 하나의 값만 갖는다.
    예) '특정 클래스'에 강사 '김코딩, 박해커' (X)

  • 부분 종속 제거

    모든 속성은 기본키에 종속되어야 한다.

    예) '클래스'에 강사 연락처
    -> 강사 연락처는 강사에 종속이다. (클래스의 종속 X)

  • 이행 종속 제거

    기본키가 아닌 모든 속성 간에는 서로 종속될 수 없다.
    예) 우편번호와 기본 주소

  • BCNF

    모든 결정자는 후보키에 속해야 한다.
    (후보키: 각 행을 유일하게 식별할 수 있는 최소한의 속성들의 집합. 유일성과 최소성을 동시에 만족)



2. 모델링 기법 팁

  1. PK(기본키_유일값을 갖는 기본키 필수)가 중요하다.
  2. 적절한 정규화 하자!
    원자성을 준수하고 최대한 중복 데이케가 없도록 한다.
    계산 결과 컬럼을 최대한 자제
    Nullable 할 필요가 없다면 Not Null로 하자!
  3. 참조 무결성을 위해 FK를 정의한다
    예) '클래스'테이블과 '강사'테이블
    강사가 없어졌는데 물건이 없어지면 안 됨
    (데이터 무결성 data integrity: 데이터의 정확성과 일관성을 유지하고 보증하는 것)
  4. 서로 다른 성격의 컬럼들은 테이블 분리!
    클래스 소개 콘텐츠는 클래스 소개글, 커리큘럼, 강사소개로 나뉨으로 분리한다







위의 단계로 필자의 프로젝트 DB 모델링을 해보았다.

✍ DB 모델링 구현


1. Entities(Object) 도출

Entities

  • 일반사용자, 강사
  • 클래스
  • 동영상
  • 커리큘럼
  • 관심 클래스
  • 구매한 클래스
  • 개설 클래스
  • 리뷰
  • 리뷰 이미지
  • QnA

Behavior

  • 일반 사용자, 강사 관리자 로그인 / 회원가입 / 개인정보수정
  • 클래스 개설 신청
  • 클래스 동영상 업로드
  • 클래스 구매
  • 클래스 찜
  • 클래스 리뷰
  • 클래스 QnA
  • 강사 지원



2. 관계설정

조인테이블을 만들거나 외래키(Foreign Key)를 만들기 위해서 관계를 설정해야한다.
그런데 1:N, N:M 관계 설정이 생각보다 많이 햇갈렸다.
나는 한 필드에서 한 필드로 참조하는 방향에 따라 여러 번 쓰일 수 있는지에 대한 여부에 따라 관계를 구별하였다.


예를 들면 다음과 같다.

1 : N = 유저 : 휴대폰 번호
(유저 → 휴대폰 번호) 특정 유저는 여러 개의 휴대폰 번호를 가질수 있다.
(휴대폰 번호 → 유저) 특정 휴대폰 번호는 오직 특정 유저에게만 귀속된다.

결론: 유저는 한 명이고, 휴대폰 번호는 여러 개가 올 수 있음.

N : M = 유저 : 여행상품
(유저 → 여행상품) 특정 유저는 여러 개의 여행상품을 구매할 수 있다.
(여행상품 → 유저) 특정 여행상품은 여러 유저에 귀속될 수 있다.


나의 프로젝트는 다음과 같은 관계를 갖는다.

teacher : class = 1 : N

(선생님 → 클래스) 특정 선생님은 여러 클래스를 오픈 할 수 있다.
(클래스 → 선생님) 특정 클래스는 한 선생님에 의해서 오픈된다.

region : class = 1 : N

(지역 → 클래스) 특정 지역은 여러 클래스에 들어갈 수 있다.
(클래스 → 지역) 특정 클래스는 한 지역만 갖는다.

class : class_course = 1 : N

(클래스 → 클래스 코스) 특정 클래스는 여러 코스를 가질 수 있다.
(클래스코스 → 클래스) 특정 코스는 한 클래스에만 귀속된다.

user : class_review = 1 : N

(유저 → 클래스 리뷰) 특정 유저는 여러 리뷰를 작성할 수 있다.
(클래스 리뷰 → 유저) 특정 클래스 리뷰는 특정 유저에 귀속된다.

teacher : class = 1 : N

(강사 → 클래스) 특정 강사는 여러 클래스를 개설할 수 있다.
(클래스 → 강사) 특정 클래스는 한 강사에 의해서만 개설될 수 있다.

user : class = N : M

다대다 관계로 인해 생성된 조인 테이블 :

  • 유저가 찜한 클래스
    (유저 → 클래스) 특정 유저는 여러 클래스를 찜 할 수 있다.
    (클래스 → 유저) 특정 클래스는 여러 유저에 의해 찜 당할 수 있다.
  • 유저가 구매한 클래스
    (유저 → 클래스) 특정 유저는 여러 클래스를 구매할 수 있다.
    (클래스 → 유저) 특정 클래스는 여러 유저에 의해 구매될 수 있다.



3. 생성 테이블 및 컬럼

  • 사용자 : 로그인 아이디, 패스워드, 닉네임, 이름, 생년월일, 성별, 프로필이미지url, 관리자 여부
  • 클래스 : 클래스명, 강사 아이디, 가격, 온/오프라인, 지역 아이디, 평점, 할인율, 생성일자, 배너이미지 url, 콘텐츠(클래스 소개)
    - 동영상 : 클래스아이디, 커리큘럼아이디, 강의 순서 ==> 커리큘럼과 1:1관계이므로 따로 테이블을 생성하지 않기로 한다
  • 커리큘럼 : 커리큘럼명, 클래스아이디, 커리큘럼아이디, 강의 순서, 동영상url
  • 관심 클래스: 유저 아이디, 클래스 아이디
  • 구매한 클래스 : 유저 아이디, 클래스 아이디
  • 개설한 클래스 : 선생님 아이디, 클래스 아이디, 개설일
  • 리뷰 : 유저 아이디, 클래스 아이디, contents, 평점, 작성일
  • 리뷰 이미지 : 리뷰 아이디, 클래스 아이디, 이미지url, 생성일
  • QnA : 클래스 아이디, q contents, q 아이디, q 작성일, a contents, a 아이디, a 작성일
  • 지역: 지역명





🙌 해결책

  1. 클래스 > 클래스 콘텐츠 > 클래스 소개는 Ckeditor를 사용하여 강사가 작성하는 글과 이미지가 순서대로 통째로 저장될 수 있도록 할 것이다.?
    (ckeditor 사용법을 잘 몰라서 추후 변동 사항이 있을 것으로 예상이 됨)
  2. 강사 테이블을 따로 만들지 않고, 일반 사용자 테이블에 강사인지 아닌지 구별하는 필드 생성할 예정
  3. 동영상 업로드 순서: 강의 개설 신청 -> 관리자로부터 승인 -> 동영상 업로드 버튼이 활성화
  4. 이미지 테이블은 리뷰 이미지만 따로 만들고, 생성일 필드를 만들어 등록된 순서대로 게시될 수 있도록 함
  5. 질의 응답은 질문과 응답을 따로 분리하지 않고 하나의 테이블로 만듦.

완성된 DB 모델링 이미지

profile
신입 개발자 입니다! 혹시 제 글에서 수정이 필요하거나, 개선될 부분이 있으면 자유롭게 댓글 달아주세요😊

1개의 댓글

comment-user-thumbnail
2023년 10월 15일

많은 도움이 되었습니다. 감사합니다~

답글 달기