기업협업 1주차 - NoSQL과 트리구조 이해하기

더미벨·2022년 7월 25일
2

기업협업 1주차의 과제는

  • noSQL과 firebase에 대한 이해
  • 운영중인 웹사이트의 DB구조를 nosql 형식으로 파악하고 모델링해보기
  • 우리 웹사이트의 DB구조와 유사한 웹사이트를 찾아보고 DB구조 파악하기
  • 열람구조 생각하며 DB 짜기. Firestore에 직접 값을 넣고 뽑아보며 어떤 게 가장 효율적인 DB구조인지 고민해보기.

였다.

나는 우선 DB에 대한 지식 자체가 아예 없었기 때문에(^^) sql과 nosql의 차이점에 대해서 이해하는 것부터 시작했다.


1. NoSQL과 Firebase에 대한 이해


📍 기존 RDBMS(관계형 데이터베이스)의 문제점

  • 관계형 데이터 관리에는 적합하지만 비용이 따르고, 확장이 어렵다.
  • 관계 유지를 위해 많은 메모리와 컴퓨터 성능을 필요로 함. 한동안은 DB 서버를 계속 업그레이드 할 수 있지만, 어느 시점에서부터는 로드를 처리할 수 없게 된다.
  • 관계형 데이터베이스는 수직으로는 확장이 가능하지만, 수평으로는 확장이 불가하다.

📍 NoSQL

  • Not only SQL / Non-relational
  • NoSQL은 특별한 경우, 특별한 이슈에 대응하기 좋은 DB들이다.
  • key에 대한 put/get만 지원.
  • 기존의 관계형 데이터베이스보다 확장성이 뛰어나다. 수직적/수평적 확장이 모두 가능하다.
  • 가장 대표적인 것이 mongDB이며 이번에 사용할 Firestore도 nosql의 형식으로 데이터베이스를 사용한다.
  • 고정된 스키마가 없기 때문에 데이터베이스의 항목이 동일한 구조를 가질 필요가 없다.
{
	name: 'MacBook Pro 13',
	price: $1032.21,
	description: 'laptop'}

{
	name: 'Hand Sanitizer',
	price: $9.99,
	discount: 10%,
	category: 'survival'
}

2. 늘펫플러스 데이터모델링

늘펫플러스는 수의사들이 고객관리를 조금 더 쉽게 할 수 있게 하기 위한 서비스를 제공하는 챗봇 기반의 플랫폼이다.

NoSQL의 형식으로 데이터 구조를 파악해보라고 말씀하셨지만, 도저히 감이 오지 않아..^^ 일단은 내게 익숙한 테이블 형태로 모델링을 해보았다.

  • 처음에 보호자 등록할 때 핸드폰번호로 조회를 하기 때문에 핸드폰번호가 Key값이라고 생각함
  • 예약메시지와 팔로업메시지는 결국 예약날짜를 기준으로 발송되는 것이기 때문에 같은 테이블에 담았고, enum type을 통해 예약메시지는 reserve_date -1 , 팔로업메시지는 reserve_date +2 일 때, 각각 reserve_content / follow_content의 메시지 내용이 발송되는 형식.
  • 아이 상태 확인을 눌렀을 때 보호자가 선택하는 증상(symtom)과 연결되는 콘텐츠의 관계: 1대다로 연결. 하지만 기타를 선택했을 때는 아무런 메시지도 발송되지 않음.

하지만 보여주신 DB 구조는 완전히 달랐고... 이를 바탕으로 다음 과제로 넘어갔다!



3. 유사 구조 웹사이트 리서치 및 DB 모델링

보여주신 웹사이트가 hospital이라는 하나의 collection 아래 하위 collection들로 이루어져 있는 트리구조로 이루어져 있었기 때문에 tree data structure로 이루어진 웹사이트를 계속 서치했다.
그런데 아무리 구글링을 해도 안나와서 핸드폰에 있는 어플들을 전부 뒤져보던 와중 당근마켓을 발견했다!

당근마켓도 결국 위치기반의 서비스이기 때문에 location이라는 상위 collection 안에 users와 products에 대한 정보들이 하위 collection으로 들어가 있을 것이라 생각하고 DB를 짜기 시작했다.

⬇️ 당근마켓 DB 초기 모델링

users collection 내에 유저아이디와 매너온도 등의 유저 정보가 들어가 있고, 또 하나의 하위 collection으로 products가 들어가 있는 형태로 DB를 짰다.

하지만 CTO님께서 "꼭 products가 users의 하위에 있어야 할까? 두 개를 분리할 수는 없을까?" 라는 질문을 던지셨다.

지금까지는 "열람"에 대해 생각하지 않고 데이터베이스를 짰는데 이제부터는 열람에 대한 생각도 함께 가지며 DB 구조를 고민해봐야 한다고 말씀해주셨다. 어떤 정보를 어떻게 최대한 빨리 가져올 수 있을지에 대한 고민 말이다.

예를 들어, product에 대한 정보를 모두 불러올 때 위와 같은 형태로 DB가 구성되어 있으면 결국 users에 대한 정보까지 다 불러오게 된다. 이 때 users 정보도 같이 필요할까에 대한 고민을 해보고, 만약 필요가 없다면 위와 같은 DB구조는 굉장히 비효율적인 것이 된다.
대신, 두 개를 분리하고 products 혹은 users의 하위로 필요한 정보들만 중복해서 넣는 방법도 있다.

나는 지금까지 그나마 익숙한 구조가 sql이라고 sql의 형태로만 생각을 했던 것 같다. sql형태로 DB를 짤 때에는 중복을 최대한 피해야했기 때문에 위 사진과 같은 형태로만 생각을 했던 것 같다.
하지만 NoSQL은 read를 최대한 빠르게 하고 업데이트를 최소화하기 위해 등장한 개념이기 때문에 중복을 최대한 활용하는 방식이 어쩌면 효율적으로 데이터베이스를 사용하는 방법이 될 수도 있다!


4. 열람구조 생각하며 DB 짜기

세번 이상 데이터베이스를 구성해보며 각 리드수를 비교하고 어떤 방식으로 DB를 짰을 때 가장 빠르고 효율적으로 데이터를 읽어올 수 있을지에 대해 고민해보라고 하셨다.

⬇️ 1차 모델링

지역을 검색했을 때 해당되는 판매상품이 나열되는 리스트페이지와 제품을 클릭했을 때 넘어가는 상세페이지를 나누어 생각했다. 리스트페이지에서는 유저정보가 보이지 않기 때문에 상품정보와 유저정보에 대한 collection을 분리했다.

⬇️ 2차 모델링

1차 모델링을 하고 데이터를 가져오는 과정에서 location의 위치가 애매해졌다. 리스트페이지에도, 상세페이지에도 location 정보가 필요한데 만약 상위 collection에서 정보를 가져오게 된다면 product와 users에 대한 정보를 반복문을 돌릴 때 어떻게 끼워넣어야 하는지를 잘 모르겠다.
그래서 일단 products의 field값으로 location을 한번 더 넣어주었다.

또한 상세페이지에서는 해당 상품을 판매하는 유저가 판매 중인 또 다른 상품들의 목록이 뜨는데, 해당 화면에서는 상품 이름, 가격, 사진만 뜨기 때문에 세가지 항목만 users 하위로 중복해서 연결시켜주었다.

⬇️ 3차 모델링

두번째 데이터까지 짜고 페이지를 구성하다 보니 리스트페이지에서는 상품 제목, 이미지, 가격, 좋아요 수, 지역까지만 보이는데 상품에 대한 정보를 전부 불러올 필요가 없다고 느꼈다.

그래서 product collection에 대한 field를 수정하고 users의 하위 collection인 products에 모든 정보를 담았다.

이렇게 하면 리스트페이지에서는 데이터를 5개만 읽어오면 되고, 상세페이지에서는 하위에 있는 데이터를 모두 읽어오면 된다!

하지만 여전히 드는 고민은 location값이 상위 collection으로 들어가는 게 맞는건지 아니면 유저/상품에 대한 field값으로 들어가서 그거에 해당하는 데이터를 싹 다 긁어오는 게 맞는건지...?

데이터베이스 너무 어렵다 휴🥲

profile
프론트엔드 개발자👩‍💻

1개의 댓글

comment-user-thumbnail
2022년 7월 30일

lolololol :) thanks 😃😃

답글 달기