프로젝트/크루트

Entity 설계하기

발전생 2022. 1. 21. 20:33

백엔드에 있어서 데이터베이스의 설계는 중요하다. 효율적으로 설계하기는 쉽지 않지만 김영한 님의 스프링 강의에서 봤던 엔터티 관계를 떠올리며 만들어봤다.

 

 

draw.io가 제약이 적은 무료 툴이라 사용했는데 left spacing이 작동하지 않는다. 그래서 엔티티의 필드를 볼 때 가독성이 떨어진다.

 

김영한 님의 spirng 강의에서 category가 트리 구조라 자신과 관계를 맺는 엔티티였다. 그걸 반영하니 대댓글의 엔티티 관계를 만들 수 있었다. Question에 parent와 child를 둬서 parent는 대댓글의 원 댓글을, child는 대댓글들을 값으로 가질 것이다.

 

Stack은 frontend, backend, design 3 분류 나눌 예정이기 때문에 상속 관계를 써야 한다고 생각했다. 굳이 데이터베이스에 테이블을 둘 필요가 없다고 생각해서 jpa의 Embedable 값 타입을 사용해야 하나 잠시 고민도 했었다. 그런데 embedable은 테이블을 따로 안 만들 뿐이지 그 엔티티의 속성들이 전부 embeded 애노테이션이 있는 테이블에 들어가게 된다. 값 타입의 리스트를 사용하면 jpa(하이버네이트)가 어떻게 테이블을 만들지 잘 모르겠다.

 

나중에 직접 코드를 짤 때 시도해보아야겠고 안 될 경우를 대비해 Stack을 따로 테이블로 두는 방식도 설계해놨다. 자식 엔티티들이 필드가 없는 게 깔끔해보이지는 않지만 나중에 한 분야의 엔티티만이 갖는 필드가 생길 경우에 변경이 쉬운 장점이 있겠다. 현재는 공통 필드만 필요하므로 단일 테이블 전략을 사용할 것이다. 그러면 frontend, backend, design의 각 테이블이 생기지 않고 Stack 테이블만 생기게 돼서 sql 쿼리를 적게 요청할 수 있고 join도 안 해도 된다. 

 

 

 


<1차 수정>

값 타입 컬렉션을 사용하는 방법을 기존에 배웠었다. 까먹고 있다가 강의 내용을 다시 훑다가 알게 되었다. @ElementCollection과 @CollectionTable을 사용하면 된다. 이 값 타입을 위한 새로운 테이블을 jpa가 만들어준다.

 

Stack을 엔티티로 할지, 값 타입으로 할지 고민이 꽤 됐었다. 하지만 잘 생각해보니 엔티티가 옳다고 느꼈다. 

엔티티이든 값 타입이든 sql문을 잘 작성하면 통계 쿼리, 조회 쿼리 모두 가능하다. 저장되는 데이터 양의 관점에서 봤을 때 엔티티에 한 표를 줬다. 가령 vue를 사용하는 유저가 1000명 있고 stack을 값 타입으로 해서 user에 저장하면 user마다 stack의 필드가 전부 column으로 들어가게 된다. 하지만 엔티티라면 Stack 테이블에 vue를 표현하는 정보들이 한번 들어가고 중간 테이블에서 FK만 1000번 들어가면 된다. 1000번 값 타입 데이터를 전부 db에 넣는 것보다는 FK 1000번 + 값 타입 데이터 1번이 용량 면에서 우위라고 본다.

 

그리고 김영한 강사님이 강조하신 대로 다대다 관계는 일대다, 다대일로 풀어쓰기로 했다. 추후에 중간테이블에 필드를 추가하고 싶을 수 있기 때문이다. 당장은 추가 필드가 필요 없다고 느껴서 @ManyToMany를 쓰면 편하겠지만 나중의 유지보수를 위해 말씀을 따르겠다.

 

변경된 엔티티, 테이블 그림이다.

 

설계한 엔티티를 보고 java code를 작성한 뒤 jpa가 의도한 대로 작동하는 지 h2를 통해 확인했다. h2에서 만들어진 각 테이블이 그려놨던 테이블과 일치하는 지 확인해봤고 잘 작동하는 걸 확인할 수 있었다.