Firebase_NoSQL_데이터_구조 - boostcampwm-2024/and04-Nature-Album GitHub Wiki

✅ Firebase NoSQL 구조

1. 통합하여 관리

NoSQL

[라벨]

Collection - Label

Document - 고양이

Data

  • BackgroundColor (유저마다 다름) ⭐
  • userID

[Album]

Album은 결국 유저 별로 관리 해야 함 (대표이미지가 서로 다르기 때문)

Collection - Album

유저마다 라벨 별 대표이미지 및 라벨 색상 등 개개인의 차이가 심하기 때문에 통합하여 관리하는 것은 불가능하다고 판단

2. 각각의 유저 Collection에서 도감을 관리

첫 번째 구조

image

두 번째 구조

Photos를 Label 아래로 이동

  • 사진 전체에 대한 요청 (지도에서 클러스트링을 위해)을 하는 경우 각 라벨들을 순회하며 사진들에 대한 정보를 얻을 수 있다.
  • 각 라벨에 대한 도감을 보여줄 때 전체를 받아와 라벨로 필터링을 하는 것보다 오버헤드가 적을 것 같다.
  • 현재 우리 앱은 라벨을 기준으로 사진을 불러오는 경우가 많음 (사진 전체를 불러올 일은 없음)

두 구조에 대한 의견

1: USER 컬렉션 안에 LABEL 및 Photos 컬렉션을 포함하는 구조

  • 장점:
    • 각 유저의 도감을 독립적으로 관리하여 개인화된 데이터 구조를 유지할 수 있음.
    • PhotosLABEL 아래로 이동하면, 특정 라벨의 사진을 효율적으로 클러스터링 및 필터링 가능.
    • 유저 개별 앨범 관리가 용이하며, 사진 조회 시 라벨 단위로 데이터 접근이 가능해 오버헤드가 줄어듦.
  • 단점:
    • 유저 데이터가 늘어날수록 중복된 정보가 많아질 가능성이 있음. 예를 들어, 공통적인 라벨이 많을 경우 같은 라벨이 여러 유저 문서에 중복 저장될 수 있음.
    • 유저 개별 데이터 외 공통 데이터의 업데이트나 조회가 불편할 수 있음.

2: LABEL 컬렉션과 ALBUM 컬렉션을 통합 관리

  • 장점:
    • 공통적인 라벨 데이터를 하나의 Label 컬렉션에 저장하면 모든 유저가 접근 가능하므로, 중복을 줄일 수 있음.
    • Album은 유저 별로 관리하여 각 유저의 대표 이미지나 개별 설정을 분리할 수 있음.
  • 단점:
    • 유저마다 다르게 설정될 수 있는 BackgroundColor 같은 속성을 공통 라벨 컬렉션에서 관리하기 어려움.
    • 유저별로 다양한 라벨 설정이 필요한 경우 데이터가 비효율적으로 저장될 수 있음.

결론

⇒ 각각의 유저 Collection에서 도감을 관리하는 것이 나아 보임

  • 사용자별 라벨 색상 관리

    각 유저는 동일한 라벨 이름을 사용하더라도 색상이나 스타일을 개인 취향에 맞게 설정할 수 있다.

    유저마다 라벨의 배경색이 다를 수 있기 때문에, 공통 컬렉션에서 이를 관리하는 것보다 개별 유저 컬렉션에서 라벨과 관련 설정을 독립적으로 관리하는 것이 더욱 유연하다.

  • 사용자별 대표 이미지 관리

    동일한 라벨이라도 유저마다 다른 대표 이미지를 설정할 수 있다.

    예를 들어, ‘고양이’라는 라벨에 대해 어떤 유저는 특정 사진을 대표 이미지로 선택하고, 다른 유저는 다른 이미지를 선택할 수 있다.

    이러한 설정을 지원하기 위해 사용자 컬렉션별로 도감을 관리하는 것이 더욱 적합하다.

첫 번째 구조로 결정

image


24.11.14 변동 사항

이미지 Uri로 Document ID를 지정하려고 했더니 문제가 생겼다.

  1. 너무 길다. 사실 이건 큰 문제가 되지 않는다.
  2. uri에 // 가 들어가는데 Document ID에는 // 가 들어갈 수 없다.

따라서 Document ID에는 이미지 파일명으로 구분 후 필드에 uri를 넣어주는 방법 생각

image

다음과 같이 바꿔주면 Room DB 또한 변경이 필요하다.

2024.11.14 변동 사항

  • 친구 기능이 도입됨에 따라 다음과 같이 업데이트 되었다.
Firestore
├── USERS (Collection)
│   ├── {uid} (Document)
│   │   ├── displayName: String
│   │   ├── email: String
│   │   ├── photoUrl: String
│   │   ├── FRIENDS (Sub-collection)
│   │   │   ├── {friendUid} (Document)
│   │   │   │   ├── user: FirestoreUser (Embedded object)
│   │   │   │   │   ├── uid: String
│   │   │   │   │   ├── displayName: String
│   │   │   │   │   ├── email: String
│   │   │   │   │   ├── photoUrl: String
│   │   │   │   ├── addedAt: String (Timestamp)
│   │   │
│   │   ├── FRIEND_REQUESTS (Sub-collection)
│   │   │   ├── {requestUid} (Document)
│   │   │   │   ├── user: FirestoreUser (Embedded object)
│   │   │   │   │   ├── uid: String
│   │   │   │   │   ├── displayName: String
│   │   │   │   │   ├── email: String
│   │   │   │   │   ├── photoUrl: String
│   │   │   │   ├── requestedAt: String (Timestamp)
│   │   │   │   ├── status: String ("sent" or "received")
│   │   │
│   │   ├── LABEL (Sub-collection)
│   │   │   ├── {labelName} (Document)
│   │   │   │   ├── backgroundColor: String
│   │   │   │   ├── thumbnailUri: String
│   │   │
│   │   ├── PHOTOS (Sub-collection)
│   │   │   ├── {photoId} (Document)
│   │   │   │   ├── uri: String
│   │   │   │   ├── label: String
│   │   │   │   ├── latitude: Double
│   │   │   │   ├── longitude: Double
│   │   │   │   ├── description: String
│   │   │   │   ├── datetime: String (ISO-8601)