기타/42서울

[42서울-Checkin] 실제 서비스에서 데이터베이스 erd 설계해볼래?

레에몽 2022. 2. 1. 12:39

 코로나 시국에는 42서울 체크인 서비스로 출석명부를 관리했던 때가 있었습니다. 기존에 있던 체크인 사이트 코드를 분석해보면서, 혼자 새로운 데이터베이스를 설계할 때 제가 생각했던 것을 글로 남겨보고자 작성합니다.

 

ERD가 뭔데 그래요?

Entity Relationship Diagram의 약자로서 시스템의 엔티티들이 무엇이 있는지, 어떤 관계가 있는지를 나타내는 다이어그램입니다.

 

 쉽게 설명하자면 하나의 클래스를 만든다고 생각하면 됩니다. 예를 들면 운동하는 공을 정의하기 위해서는 Ball이라는 클래스를 만들고 speed, location 등을 통해서 공의 위치와 속도를 나타낼 수 있는 것처럼 하나의 객체를 정의하고 어떤 속성을 가지고 있는지를 정의하면 되는 것입니다.

 

Ball말고 ! 서비스에서는 어떻게 만드는거에요?

 서비스가 어떤 목적을 갖고 있는지, 비즈니스를 파악해야 합니다. 제공할 서비스에서 어떤 객체가 있을 것이고 어떤 행동을 할 것인지 생각을 해 봅시다.

 

 '42서울 체크인 사이트'의 목적을 생각해 봅시다. 제가 생각했을 때에는 코로나 상황에서의 출입명부 간편화 서비스라고 생각합니다. 조금 더 구체적으로 말하면 다음과 같습니다.

 

 클러스터에 참석한 카뎃이 코로나가 확진되었을 때 해당 시간에, 해당 클러스터에 방문했던 사람은 누구인지?가 제일 중요한 부분이라고 생각했습니다.

 

 그렇다면 우리는 다음과 같은 정보가 필요합니다.

  • 해당 클러스터에는 어떤 유저가 있었는지
  • 유저가 언제 클러스터에 방문했었는지

 

 그렇다면 여기서 나올 수 있는 객체는 누가 될까요? 특정해서 보았을 때에는 클러스터, 유저가 바로 눈에 보입니다. 그러면 그 객체끼리 어떤 행동을 하는지 정의를 해 봅시다.

42서울 체크인사이트에서의 클라이언트의 행동은 다음과 같습니다.

  • 유저가 42OAuth와 cardNumber를 통해서 로그인을 합니다.
  • 유저는 건강상태를 체크하고, 체크인을 합니다.
    • 이때 클러스터는 제한된 인원을 넘어가지 못합니다.
  • 유저는 자신의 출입 LOG기록을 가지고 있어 볼 수 있습니다.
  • 유저는 클러스터를 나갈 때 체크아웃을 합니다.

 

 그러면서 유저가 가져야 할 정보를 생각해 봅시다. 여기서 로그인은 api를 통해서 OAuth로그인을 하기 때문에 회원가입과 로그인 보안적인 문제는 크게 생각안해도 될 것 같습니다. 

 

유저를 만들어보자 😎

  • 출입기록은 유저의 체크인 시간과 체크아웃 시간을 가지고 있어야 LOG기록을 사용할 수 있습니다.
  • 유저는 카드 번호를 통해 체크인을 할 수 있습니다.
  • 관리자 페이지를 위해 역할이라는 개념이 필요합니다.
    • 역할은 ADMIN, STAFF, NONE와 같이 나눌 수 있습니다.
  • 42서울 API를 통해 유저의 닉네임과 사진을 받아옵니다.
    • 이때, 데이터베이스 상으로도 누구인지 확인할 수 있으려면 닉네임을 저장하는게 좋다고 생각합니다.
  • 데이터베이스에 유저 정보를 기록하기 때문에 유저의 회원가입 시점과, 생성 시점을 알면 좋다고 생각합니다.

 

클러스터를 만들어 보자 😎

  • 개포클러스터에서 몇 명이 사용중인지 알아야 합니다.
  • 서초클러스터에서 몇 명이 사용중인지 알아야 합니다.

 

해당 ERD를 정의하면 다음과 같아집니다.

1차 ERD

 처음에는 이렇게 작성했을 때 괜찮지 않을까..? 라는 내심 기대를 했습니다. 그러나 생각하면 생각할수록 이상하다는 느낌이 들기 시작했습니다.

 

 유저가 어디서 출석을 한 지에 대한 정보가 없다는 점과, 클러스터 객체 컬럼에서 서초와 개포는 같은 레벨이지만, 아이디와 서초/개포 는 같은 레벨이 아닙니다. 그래서 데이터베이스 스키마 관계가 어색하다고 생각했습니다.

 

추가로, 만약 새로운 클러스터가 생기거나 기존 클러스터가문을 닫는다면은 데이터베이스를 수정해야 된다는 번거로움이 있어보입니다.

 

그래서 확장성과 스키마의 레벨을 고려해서 다음과 같이 만들었습니다.

2차 ERD

이 방법도 나쁘지 않다고 생각합니다.

 

 그러나 묘하게 아쉽다라는 생각이 계속 들었습니다. 그 이유는 클러스터의 역할이 크게 없다라고 느껴지기 때문입니다. 그래서 다음과 같이 생각했습니다.

 

유저랑 클러스터를 합칠 수는 없을까?

 

 42서울 체크인 사이트가 코로나 19에 의한 출입기록이 목적이 맞다면 따로 정의하지 않고 출입기록 테이블을 만들면 되지 않을까라고 생각을 했습니다.

 

 출입기록과 클러스터를 외래키를 통해서 관리를 할 수 있다고 생각했지만, 그것보다 출입기록 테이블 한 개만 쓰는게 더 관리하기 편해보였습니다.

 

해당 형태로 만들면, 클러스터에 있던 사람들을 쉽게 파악할 수 있을 것이라고 생각했습니다.

 

3차 ERD

이렇게 ERD 정의를 마무리했습니다.

 

기존 42서울 체크인 사이트 ERD

 

해당 ERD를 공부할 때에는 다음과 같은 생각을 했었습니다.

  • config에서 begin_at / end_at이 있는 이유는 프랑스에서 온 것 때문이지 않을까?
    • 클러스터 열고 닫는 시간은 정해져있는데 왜 필요할까요!?
    • 42서울 체크인 사이트는 프랑스에서 모티브 한 것으로 알고있는데, 프랑스는 국가 내에서 다양한 시간을 쓰기 때문에 시차가 다를 수 있어서 정의하려고 했던 것 같습니다.
  • user에서 card_no는 왜 필요할까요?
    • 카드 번호 중복검사를 해야 할까요?
    • 카드를 분실했을 때 마지막으로 누가 썻는지 알기 위해서 필요했다고 생각했습니다.

 

기존 42서울 체크인 사이트 깃헙 주소 : https://github.com/innovationacademy-kr/42checkin-backend