서비스의 전체적인 DB 구조는 다음과 같습니다.
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을 두어 언제든지 태그 분류를 쉽게 확장할 수 있게 하였다.
해당 테이블들은 좋아요 기능 및 스크랩 기능을 구현하기 위해 설계된 테이블입니다. 모두 중간 테이블의 역할로 다 대 다 관계를 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;
}
}
}