ASKu 입실렌티 사이드 프로젝트 때 DB 스키마를 짜는 역할을 맡았다. 데이터베이스 수업을 들으면서 과제로 DB 스키마를 짜본 경험은 있지만... 문제는 그땐 그냥 손으로 그려서 했다는 것이다! 그래서 나 혼자 스키마를 짜도 다른 팀원들에게 명확하게 설명하기 힘든 상황이라 스키마를 깔끔하게 보여지도록 하기 위해 여러 방법을 찾았다.
우선은 내가 프로젝트에서 스키마를 짠 순서를 소개하고, 그 과정에 사용한 몇가지 추천 툴들을 추천하려고 한다.
1. DB 스키마 짜는 순서
0) ★기획상의 기능정의와 요구사항을 명확히 이해하기★
정말 제일 중요하다!!! 현재 프로젝트에서 기획하고 있는 제품이 뭔지, 무엇을 해야 하는지 명확히 이해해야 하고 부정확하거나 잘 이해되지 않는 부분이 있다면 기획 쪽에 반드시 다시 한 번 확인해야 한다. 안 그러면 스키마가 완성됐을 때 요구사항과 맞지 않아 뒤엎어야 하는 불상사가 생길 수 있다...
데이터베이스 수업 시간에 배운 걸로는 클라이언트 측에서 기능정의서를 제시하면 그 기능정의서에 나온 문장의 주어 목적어 술어 하나하나를 다 뜯어보면서 스키마를 짠다는데, asku 때는 시간이 촉박했던지라... 기획 쪽과 실시간으로 소통하면서 기능과 요구사항을 확인했다.
필요한 기능들을 체크하다 보면 이걸 DB상의 Table로 구현할지, 아니면 백엔드 내부 로직으로 구현할지 고민이 되는데, 이 때는 백엔드가 어느정도까지 감당 가능한지 확인하고 두 가지 선택지의 장단점을 잘 비교해가면서 구현하면 된다.
각자의 프로젝트에 따라 다르겠지만, 장단점을 정리해보자면 이렇다.
(1) DB table로 구현하기
[장점] 정합성을 지킬 수 있을 확률이 늘어남: 엄밀한 FK 정의 등으로 혹시라도 백엔드 개발자가 로직 구현 중 필요한 값을 빼먹었다면 DB 측에서 오류를 잡아줄 수 있다.
[단점] DB 내의 관계가 복잡해진다. 이후 기능 수정이 필요할 경우 DB를 건드려야 하기 때문에 비용이 커지거나 사용하지 않는 column이 생기거나 부가적인 문제가 발생할 수 있다. table이 많아져서 보기가 안 좋다(개인 취향)
(2) 백엔드 내부 로직으로 구현하기
[장점] DB 자체는 간단해져서 이해하기 쉽다. 이후 기능 수정이 필요할 경우 백엔드 코드만 좀 수정해주면 된다.
[단점] 정합성 문제: 테이블과 테이블 간의 관계로 엄밀하게 연결되지 않아 백엔드 쪽에서 정합성을 일일히 체크해주지 않으면 문제가 생길 수 있다.
물론 DBA가 구분된 회사에서는 이렇게 하지는 않을 것 같지만.. 나는 프로젝트에서 백엔드 담당이면서 DB를 주로 담당했었기 때문에 이런 장단점을 다른 백 팀원들과 의논하면서 조율해나갈 수 있었다.
1) 필요한 table을 정의하자
기능상에서 필요한 table을 정의하자. 이를테면 '회원', '연예인 목록', '위키 문서 목록', '위키 수정 히스토리' 같은 것들이다. 일단은 필요할 것 같은 table은 최대한 만들어놓는 게 좋다. 기능 정의 읽다가 놓쳐서 까먹는 것보다는..(나도 아직 기능 몇 개씩 까먹는다;-; 학창 시절 필기하는 것처럼 꼼꼼히 보자!)
2) 중복되는 table은 제거하자
1)에서 최대한 table을 만들어냈다면 분명히 중복되는 table이나 기획 상에서 요구하지 않은 table이 있을 것이다. 다시 한 번 기획서와 기능정의서를 읽어보고, 필요없는 table은 제거하자.
3) 각 table의 column을 정의하자
각 table에 필요한 column을 정의하자. 이를테면 'User' 테이블의 'ID', '비밀번호', '전화번호'가 있겠다. 이 또한 요구사항을 확인하면서 해야 한다.
4) 각 table의 PK (primary key)를 표시하자
테이블의 각 row의 구분 기준이 되는 PK를 설정한다. 나는 대개 (개체) id 라는 column을 항상 만들어서 (예: history_id, comment_id...) 그 column을 PK로 설정했고, 기획적으로 다른 PK가 필요한 경우에만 다른 column에 PK 설정을 하였다.
ASKu 프로젝트에서는 1)~4)를 같은 프로세스로 묶어서 진행했다. 아무래도 table을 정하면 column도 얼른 적어놓고 PK도 정해두고 싶은 게 사람 마음인지라... 그리고 다음 단계에서 조금이라도 편하기 위해 FK 관계가 설정될 것 같은 table이 붙어있도록 잘 배치해둬야 한다! 나는 아예 미리 FK가 필요할 것 같은 테이블 사이에 선을 그어놨다. 여기까지 하면 대략 이런 모양이다.
5) 관계를 설정한다.
대망의 FK 설정이다. 연결해둔 선을 기준으로 Cardinality와 기타 필요한 옵션을 명시해준다. 일대일, 일대다, 다대다 이런 관계를 팀이 사용하는 ERD 표현법에 맞게 짜주면 된다. 여기서 상당히 머리가 아프긴 한데... 나는 항상 두 테이블을 주어/목적어로 두면서 다음과 같은 문장을 되내이면서 관계를 작성해주었다.
"회원은 댓글을 여러 개 쓸 수 있지만(일대다), 댓글은 반드시 작성자인 회원 한 명하고만 연결된다. (일대일)"
"댓글은 여러 개의 좋아요를 가질 수 있지만(일대다), 댓글 좋아요 히스토리는 항상 하나의 댓글하고 연결된다. (일대일)"
"포인트 획득 사유는 여러 획득 내역과 연결될 수 있지만(일대다), 포인트 획득 내역은 반드시 하나의 획득 사유와 연결된다. (일대일)"
이런 사고를 거친 후에는 꼭 다른 팀원에게 물어봐서 관계가 맞는지 교차확인하자!! 가끔 머릿속에서 과부하가 걸려서 잘못 생각하는 경우가 있는데 이건 정말 혼자서는 한참을 봐도 안 보였다...
아무튼 관계를 다 설정하면 이런 식의 기초적인 ERD가 나온다! 아직 type이나 여러 제약 조건을 설정해놓지 않았지만, 여기까지 왔으면 일단 한 숨 돌리고 물을 한 잔 마시자:)
2. DB 스키마 짜는 도구
1번 과정을 모두 거쳤다면 손으로 대강 그려낸 ERD가 있을 것이다! 하지만 그걸 그대로 sql문으로 옮긴다면 좀 끔찍할 것이다... 이제 해야 할 것은 다음과 같다.
1) ERD를 협업에 용이하도록 공유 플랫폼에 올리기
2) 각 column의 type 결정하기 (INT, VARCHAR, TIMESTAMP 등등...)
3) AUTO_INCREMENT, DEFAULT 등 옵션 추가하기
이때 1)을 위해서는 다음 2가지 툴을 추천한다.
1) Lucidchart
ERD뿐만 아니라 여러 diagram을 편리하게 그릴 수 있는 사이트이다! 여러 Templates에서 자신이 원하는 ERD 스타일을 선택하여 ERD를 그릴 수 있다. 필요한 옵션들도 다 적어둘 수 있다! 또한 팀원들과 동시에 작업할 수 있다.
다만 무료 버전은 3개까지만 diagram 파일을 만들 수 있다는 불편함이 있다. 또한 ERD를 만들어도 SQL문으로 바꿀 수는 없기 때문에 ERD를 다 그리고 직접(...) SQL문을 짜야 한다... 이 부분은 DB 규모가 커질 수록 불편이 커질 것이니 자신이 하려는 프로젝트의 규모를 보고 사용하는 게 좋겠다.
2) ERD Cloud
ERD 사이트라고 하면 가장 널리 알려진 ERD Cloud이다. 관계 설정을 버튼 몇 번 누르는 걸로 간단하게 할 수 있고, 가장 큰 장점은 만들어낸 ERD를 바로 SQL문으로 export할 수 있다는 점이다!! 완전 무료이고 팀원들과 동시 작업도 가능하다.
다만 이 시스템 자체가 여러 DBMS와 공유하는 것이다보니, 특정 DBMS에만 있는 옵션은 따로 설정할 수 없는 경우도 있어 수작업이 좀 필요했다. 나 같은 경우에는 MySQL을 사용해서 모든 table id를 AUTO_INCREMENT 설정으로 했어야 했는데, 이 사이트에서는 이걸 설정할 수도 없고 export한 sql문에도 나오지 않기 때문에 이후 하나하나 수작업을 해줘야 했다... 메인 프로젝트에서는 워낙 규모가 커지니 빼먹는 부분도 생겨 서버에 DB를 올렸다가 지우고 다시 올리고 하는 과정을 반복하게 되어 많이 힘들었다. 또한 사이트가 미묘하게 불안정적인 것인지... 가끔 로그인이 풀려서 작업 중에 다시 로그인을 하는 상황도 있었다.
결론적으로 나는 사이드 프로젝트는 table이 9-10개 정도로 작았고, 관계도 비교적 간단했기 때문에 Lucidchart를 사용했지만, 규모가 커진 현재 진행 중인 메인 프로젝트에서는 ERD Cloud를 사용하고 있다.
3. 결론
DB 스키마 짜기는 상당히 번거롭고 그 과정에는 머리가 참 아프지만...^^ 모든 과정이 끝나고 잘 돌아가는 DB를 보고 있으면 뿌듯해지곤 한다. DBA나 DB가 주력인 백엔드 개발자가 되고 싶은지라 프로젝트에서도 DB 쪽을 도맡아했는데, 물론 힘든 점도 있었지만 내가 짠 스키마를 기반으로 한 DB가 서비스의 큰 기둥이 되어주는 게 DB의 매력인 것 같다.
다들 팀프로젝트든 개인 프로젝트든 이 글을 보고 조금이라도 도움을 얻어서 스키마를 좀 더 편리하게 짤 수 있었으면 좋겠다!
'웹 > BackEnd' 카테고리의 다른 글
[Redis] connect-redis TypeError: require(...) is not a function 해결 (0) | 2023.08.10 |
---|