[엉박사] DB 재구성

impala·2023년 4월 2일
0

[리팩토링] 엉박사

목록 보기
2/3
post-thumbnail

Before

After

변경사항

공통

  • 기존 데이터베이스는 회원 아이디, 책제목등의 값을 PK로 사용하였는데, 이를 각 테이블마다 “테이블명_id”의 대리키를 두어 PK로 사용하도록 변경하였다.

Member

기존 DB의 사용자정보를 보관하는 테이블은 아래와 같다.

  • PostgreSQL에서는 Array타입을 허용하고 Django에도 ArrayField()라는 함수로 이를 지원한다. 그러나 Spring과 MySQL에서는 Array타입이 없기 때문에 abillity와 genreScore를 별도의 테이블로 분리하고 Member테이블과 일대일 관계로 매핑하였다.
  • 기존에 단일 컬럼으로 사용하던 accessory필드를 세분화하여 머리, 얼굴, 몸통에 각각 악세사리를 하나씩 장착할 수 있도록 테이블을 분리하였다. 악세사리들은 Accessory테이블에서 AccessroyType으로 구분하여 저장하고, MemberAccessory 중간테이블을 두어 사용자가 장착한 악세사리를 관리한다.
  • 기존에 0~5사이의 정수값으로 표시하던 티어를 enum타입으로 변경(DB에는 String)하여 좀 더 명확하게 구분이 되도록 하였다.

위와 같은 이유로 회원정보를 담은 테이블을 아래와 같이 세분화하였다.

Report

독후감 정보를 담고있던 기존 테이블은 Report, Text, Activity 총 3개로 구성되어있었다.

  • 기존 Report테이블은 독후감의 정보만 저장하고 실제 사용자가 작성한 독후감과 피드백은 Text테이블에 저장되었는데, 좀 더 테이블의 이름과 역할을 일치시키기 위해 Report테이블에 사용자가 작성한 독후감의 내용을 추가하고, 이를 바탕으로 나오는 교정본과 피드백을 Feedback테이블에서 관리하고 Report테이블과 일대일로 매핑하였다.
  • Report에서 현재 읽고있는 챕터의 정보를 담은 current_chapter를 챕터의 번호를 저장하는 방식에서 실제 Chapter와 연결하는 방식으로 변경하여 current_chapter필드의 목적을 좀 더 분명하게 하였다.
  • 기존 Activity테이블의 question_set은 각 항목별로 미리 정해진 3~4가지의 질문들을 랜덤하게 섞어서 제공하는 방식이었는데, 이를 좀 더 체계적으로 관리하기 위해 Question에 질문항목과 질문 내용을 저장해두고 중간 테이블을 두어 Activity테이블과 연결하였다.
  • 기존 Activity 테이블의 chapter는 해당 활동이 속해있는 챕터의 번호만 저장했는데, 이를 실제 Chapter테이블과 연결하여 현재 활동이 어느 챕터에 속해있는지 의미를 분명하게 하였다.

위와 같은 이유로 재구성한 Report테이블은 아래와 같다.

Book

기존 데이터베이스에서 책과 퀴즈의 정보는 아래와 같은 구조로 관리하고 있었다.

  • Book과 Chapter에서 각각 전체 챕터 수와 전체 퀴즈 수를 저장하는 필드(chapters, quizzes)들은 쿼리문으로 알 수 있는 정보들이기 때문에 필요하지 않다고 판단하여 테이블에서 제거하였다.
  • Book테이블에 isbn 필드를 추가하였고, genre를 enum타입으로 변경하여 좀 더 명확히 구분할 수 있도록 하였다.
  • 기존 Quiz테이블은 선택지를 문자열 배열로 저장하고 답을 배열의 인덱스로 식별했는데, 데이터의 순서를 바탕으로 하는 방식은 데이터가 배열의 중간 데이터가 누락되거나 변경되었을 때 순서가 변할 수 있기 때문에 안전하지 않다고 판단하여 선택지만 저장하는 Choice테이블을 두고 Quiz와 다대일로 매핑하여 관리하는 동시에, 정답 선택지 또한 answer_id를 통해 Choice테이블과 일대일로 매핑하여 문제에 대한 정답을 식별할 수 있도록 하였다.
  • 힌트의 경우 기존 데이터베이스에서는 각 챕터의 내용을 문장으로 나누어 content_line에 저장하고 hint에 힌트로 사용될 문장의 시작 인덱스와 끝 인덱스를 저장하여 힌트를 제공하였는데, 불필요하게 책의 내용이 두번씩 저장되기 때문에 저장공간이 낭비된다고 판단하여 hint필드에 직접 힌트로 사용될 텍스트를 저장하도록 변경하였다.

위의 내용을 바탕으로 변경한 구조는 아래와 같다.

0개의 댓글