프로젝트 - 빙터뷰 [DB 설계]

Chan Young Jeong·2023년 6월 29일
0

프로젝트 빙터뷰

목록 보기
3/9
post-thumbnail

DB 설계

서비스의 전체적인 DB 구조는 다음과 같습니다.

  • member : 사용자의 기본적인 인적 사항을 저장하기 위한 테이블입니다. id와 password를 속성으로 가지고 있지만, 추후에 구글 로그인을 사용하게 되면서 삭제되었습니다. 그리고 password와 id같은 개인정보는 다른 테이블에 저장하여 보안을 강화하는 방법이 나을 것입니다.
  • question : 면접 질문을 저장하는 테이블입니다. 사용자가 질문을 등록하고 누가 등록했는지 알아야 하기 때문에 member_id를 외래키로 참조하고 있습니다.
  • comment : 게시글에 달린 댓글을 저장하는 테이블입니다. board_id 와 member_id를 외래키로 참조하고 있습니다.
  • board : 게시글을 저장하는 테이블입니다. 어떤 면접 질문에 관련된 게시글인지 그리고 누가 작성했는지를 알아야 하기 때문에 member_id와 question_id를 외래키로 참조하고 있습니다. 그리고 video_url s3에 저장된 비디오 url입니다. 자신이 올린 면접 영상이 서버에서 딥페이크가 적용된 영상으로 바뀌고 해당 url을 저장합니다.
  • tag : 질문과 연관된 태그를 저장하기 위한 테이블입니다. tag는 대분류, 중분류, 소분류 태그로 나뉩니다. 따라서 tag_id는 기본키이고 parent_id는 자신의 부모 태그를 가리키며 tag 테이블 자기 자신을 가리키는 외래키입니다.
  • tag_member : 사용자가 관심있는 tag를 저장하는 테이블입니다. tag 와 member의 관계는 다대다로 이를 중간 테이블을 두어 1 대 다 방식으로 풀어 설계하였습니다.

tag 테이블 설계

tag 테이블을 설계하는 과정에서는 두가지 방식이 제안되었습니다. 첫 번째는 위 방식처럼 tag 테이블을 한 개만 두고 부모 tag의 id를 함께 저장하는 방식. 그리고 두 번째는 대분류 tag 테이블, 중분류 tag 테이블, 소분류 tag 테이블 이런식으로 3개의 tag 테이블 만드는 방식이었다. 하지만 두 번째 방식을 채택하지 않은 이유는 일단 확장성이 부족했다. 태그가 3가지로 분류가 항상 될지도 모르고 또 tag 분류가 더 세분화 될 수도 있었기 때문이다. 그리고 태그를 조회할 때 3개의 table을 조회해야했기 때문에 굳이 많은 테이블을 조회해야 할까라는 의문이 들었다. 그리고 마지막으로 어차피 부모 tag에 대한 id를 가지고 있어야 했기 때문에 첫 번째 방식으로 tag 테이블을 설계하게 되었다.

@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Tag {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "tag_id")
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "parent_id")
    private Tag parent;
    private String name;

    @Enumerated(EnumType.STRING)
    private TagType category;

    @Builder
    public Tag(Tag parent, String name, TagType category) {
        this.parent = parent;
        this.name = name;
        this.category = category;
    }
}

public enum TagType {
    TOPLEVEL,MIDLEVEL,SUB
}

그리고 TagType을 두어 언제든지 태그 분류를 쉽게 확장할 수 있게 하였다.

board_member_like, comment_member_like, member_question_scrap 테이블 설계

해당 테이블들은 좋아요 기능 및 스크랩 기능을 구현하기 위해 설계된 테이블입니다. 모두 중간 테이블의 역할로 다 대 다 관계를 1 대 다 관계로 바꾸기 위해 설계되었습니다.

BoardMemberLike 테이블의 구현 코드는 다음과 같습니다.

@Entity
@Getter
@NoArgsConstructor
public class BoardMemberLike {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "board_member_id")
    private Long id;

    @Enumerated(EnumType.STRING)
    private LikeType likeStatus;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "board_id")
    private Board board;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "member_id")
    private Member member;

    @Builder
    public BoardMemberLike(Board board, Member member) {
        this.board = board;
        this.member = member;
        this.likeStatus = LikeType.LIKE;
    }

    public void updateStatus() {
        if (this.likeStatus == LikeType.LIKE) {
            this.likeStatus = LikeType.UNLIKE;
        }else{
            this.likeStatus = LikeType.LIKE;
        }
    }
}

0개의 댓글

관련 채용 정보