RECORD

[Firebase] RDB를 Firestore로 옮기기 / 관계형 데이터베이스 vs 비관계형 데이터베이스, NoSQL, Firebase

ez1n 2023. 12. 6. 16:47

 

[Firebase_RDB vs NoSQL]

 


 

 

기존 RDB의 데이터를 Firestore로 이관할 때 어떤 구조로 설계해야할까?

관계형 데이터베이스의 데이터를 비관계형 데이터베이스(Firestore)로 옮길 수 있는 방법에 대해 고민하게 되었다.

 

이번 포스팅에서는 관계형 데이터베이스와 비관계형 데이터베이스에 대해 간단히 정리하고,

RDB 기반의 데이터를 NoSQL 기반의 클라우드 데이터베이스인 Firestore로 옮겼던 경험을 소개하려고 한다.

 


 

<STUDY>

 

1. 관계형 데이터베이스 vs 비관계형 데이터베이스 

1️⃣ 관계형 데이터베이스

관계형 모델을 기반으로 데이터를 행과 열로 구성된 테이블로 구조화하고, 각 테이블 사이의 관계를 표현하는 데이터베이스 구조

 

📌 관계형 모델

데이터를 행(rows)과 열(columns)을 이루는 하나 이상의 테이블(관계)로 정리하는 모델로,
고유키(Primary Key)가 각 행(row)을 식별한다.

 

특징

  • 외래키(Foreign Key)를 통해 테이블 조인(JOIN)을 통해 관계를 나타내고, 의미있는 정보를 생성한다.
  • SQL을 사용한다.
  • RDB : MySQL, Oracle Database, Microsoft SQL Server 등
  • 클라우드 기반 RDB : Cloud SQL, Cloud Spanner, Alloy DB 등

 

장점

  • 전체 데이터베이스 구조에 영향을 주지 않고 테이블, 관계를 추가 및 삭제하고 데이터를 변경하는 것이 간편하다.
  • 데이터베이스 정규화를 통해 중복성을 최소화한다.
  • SQL을 사용하여 복잡한 쿼리도 쉽게 사용 가능하다.

 

 

2️⃣ 비관계형 데이터베이스

특정 데이터 모델에 대해 목적에 맞춰 구축되는 데이터베이스

 

특징

  • 고정된 스키마가 존재하지 않는다. (스키마, 관계 정의 X)
  • key-value 형식을 지원한다.
  • 데이터를 복제한다. (수평적 확장 : 모든 데이터를 일괄적으로 수정해야함)
  • 유형 : key-value, JSON 문서 형태, 그래프 형태 등
  • 예시 : MongoDB, CouchDB 등

 

장점

  • 개발이 용이하다.
  • 복잡한 구조 표현이 가능하다.
  • 기능성 및 확장성이 뛰어나다.
  • 쓰기 작업 속도가 빠르다.

 


 

2. Firestore로 데이터 이관하기 & 느낀 점

Firebase는 개인 프로젝트를 진행하면서 많이 사용했던 서비스이다.

realtime database를 주로 사용했었는데 회사에 들어오면서 firestore를 경험하게 되었다.

 

firestore가 realtime database와 달랐던 점은 데이터를 JSON 형태가 아닌 collection-document (컬렉션-문서) 형식으로 저장한다는 점이었다.

 

NoSQL의 특성상 정해진 스키마가 없어 데이터 구조를 자유롭게 표현할 수 있다는 점과,

개발을 진행하면서 다양한 구조를 쉽게 적용할 수 있다는 점이 가장 큰 장점으로 다가왔다.

 

하지만 관계형 데이터베이스처럼 JOIN을 통해 데이터들의 관계를 나타내고 재사용할 수 없다는 점은 단점으로 느껴졌다.

 

 

RDB를 Firestore로 옮기면서 가장 힘들고 어렵게 다가왔던 것은 "기존 관계들을 어떻게 정의해야 하는가" 였다.

 

- firestore의 참조 타입을 사용하여 데이터를 재사용하거나,

- 하위 컬렉션으로 저장한 뒤 특정 데이터만 불러오는 방법,

- document id를 필드값으로 넣고 필터를 걸어 사용하는 등

 

여러 고민과 시도 끝에, 각 방법의 장단점과 느낀 점이 몇 가지 있었다.

 

 

 1️⃣ 하위 컬렉션

 

컬렉션 하위에 새로운 컬렉션을 생성하는 방법이다.

collectionGroup을 통해 특정 문서 하위 컬렉션을 불러오거나 동일한 컬렉션 이름의 문서들을 모두 불러올 수 있다.

 

장점

  • 카테고리 하위 제품을 바로 불러올 수 있다. (여성 카테고리 > 티셔츠 or 남성 카테고리 > 티셔츠)
  • 같은 컬렉션 이름을 가진 하위 문서를 한번에 불러올 수 있다. (collectionGroup)

 

단점

  • firebase에서 데이터를 바로 찾는 것이 어렵다. (상위 문서의 id가 있어야함)

 

 

특정 카테고리에 소속되어 있는 데이터의 경우 하위 컬렉션을 활용하면 쉽게 구현이 가능하다.

때문에 쇼핑몰같이 그룹화가 많은 구조에서 사용하면 유용할 것 같다는 생각이 들었다.

 

 

2️⃣ reference type (참조 타입)

 

처음에는 firestore에서 관계를 가장 쉽게 표현할 수 있는 방법이 바로 참조 타입이라는 생각이 들었다.

참조 타입이 있다는 사실을 이번에 처음 알게 되었는데,

말 그대로 이미 저장된 데이터의 path를 document의 하위 필드 값으로 저장하는 방식이다.

 

장점

  • path(참조 경로)를 통해 데이터를 바로 불러올 수 있다. (doc id를 통한 document 정의 과정 필요 X)
  • 원본 데이터가 변경되면 참조 데이터가 함께 변경된다. (모든 데이터를 전부 변경할 필요가 없음!)

 

단점

  • 참조 데이터가 많아질수록 요청되는 read 횟수 또한 늘어난다. (비용 증가)

 

 

실제로 배열 안에 들어있는 참조 값들을 전부 읽어오면서 몇 백 건의 read 요청으로 인해 성능에 문제가 발생하는 일이 있었다.

때문에 이 방법은 간편하지만 비용적인 면이나 성능에 영향을 미칠 수 있다는 점에서 적절하지 않다고 판단했다.

 

 

3️⃣ document id 기반의 관계 표현 (front 처리)

 

참조 타입의 read 요청 증가에 따른 문제점을 보완하기 위해 생각한 방법이다.

소속된 (상위) 문서의 id를 저장하고 저장된 id를 기반으로 firestore에서 데이터를 읽어오는 방식이다.

이 방법은 컬렉션의 모든 문서를 불러온 후 id 값에 따라 front에서 필터 처리를 한 후 보여주는 방식으로 사용할 수 있다.

 

장점

  • read 요청을 한 번만 하면 되기 때문에 비용이 절약된다.
  • 데이터가 많지 않은 경우 front에서 처리하기 때문에 속도 및 성능 개선에 도움이 된다.

 

단점

  • 참조 데이터가 많은(대용량) 경우 성능에 문제가 생길 수 있다.
  • 중복되는 데이터 또는 삭제된 데이터가 존재할 수있다.

 

 

개인적으로 엄청난 대용량 데이터가 아니라면 이 방법이 가장 적합하다는 생각이 들었다.

물론 front에서 필터 처리를 해야한다는 단점이 있지만,

데이터가 대용량 급으로 많은 것이 아니었기 때문에 사용자에게 정보를 빠르게 보여줄 수 있다는 점이 좋았다.

 

 

그렇지만, 여전히 여러 문제들이 남아있었고 더 많은 공부가 필요하다는 생각이 든다.

 


 

 

 

개인 프로젝트를 진행하면서 비관계형 데이터베이스에 대한 비슷한 고민을 했던 경험이 떠올랐다.

 

이런 저런 관계들이 꼬여 있어서 진짜 머리가 터질뻔 했다(?) ㅎ

 

시간이 충분하지 않아 더 깊게 고민하고 더 많은 방법을 시도해보지는 못했지만,

그래도 이번 작업를 통해 데이터 구조에 대해 관심을 갖고 공부할 수 있는 계기가 되었다고 생각한다.

 

이번 경험을 기반으로 다음에 firebase를 이용할 때에는 더 나은 방법이 있는지 생각하고 데이터 구조를 정의할 수 있도록 공부해야겠다.

 

공부할게 엄청 많다...! 화이팅!