Cloud Firestore 데이터 모델

Cloud Firestore는 NoSQL 문서 중심의 데이터베이스입니다. SQL 데이터베이스와 달리 테이블이나 행이 없으며, 컬렉션으로 정리되는 문서에 데이터를 저장합니다.

문서에는 키-값 쌍이 들어 있습니다. Cloud Firestore는 작은 문서가 많이 있는 컬렉션을 저장하는 데 최적화되어 있습니다.

모든 문서는 컬렉션에 저장되어야 합니다. 문서는 하위 컬렉션 및 중첩된 객체를 포함할 수 있으며, 둘 다 문자열 같은 기본 필드나 목록 같은 복합 객체를 포함할 수 있습니다.

컬렉션과 문서는 Cloud Firestore에서 암시적으로 생성됩니다. 사용자는 컬렉션 내 문서에 데이터를 할당하기만 하면 됩니다. 컬렉션이나 문서가 없으면 Cloud Firestore가 이를 자동으로 만듭니다.

문서

Cloud Firestore의 스토리지 단위는 문서입니다. 문서는 값에 매핑되는 필드를 포함하는 간단한 레코드입니다. 각 문서는 이름으로 식별됩니다.

사용자 alovelace를 나타내는 문서는 다음과 같이 구성될 수 있습니다.

  • alovelace

    first : "Ada"
    last : "Lovelace"
    born : 1815

문서의 복잡한 중첩된 객체를 맵이라고 합니다. 예를 들어 위의 예시에서 사용자 이름을 다음과 같이 맵으로 구조화할 수 있습니다.

  • alovelace

    name :
        first : "Ada"
        last : "Lovelace"
    born : 1815

문서가 JSON과 매우 비슷해졌는데, 사실 기본적으로는 JSON과 유사합니다. 문서가 추가적인 데이터 유형을 지원하고 크기가 1MB로 제한되는 등의 몇 가지 차이점이 있기는 하지만, 일반적으로는 문서를 간단한 JSON 레코드로 취급해도 무방합니다.

컬렉션

문서는 단순히 문서의 컨테이너인 컬렉션에 저장됩니다. 예를 들어 각각 문서로 표현되는 여러 사용자를 포함하는 users 컬렉션이 있을 수 있습니다.

  • 사용자

    • alovelace

      first : "Ada"
      last : "Lovelace"
      born : 1815

    • aturing

      first : "Alan"
      last : "Turing"
      born : 1912

Cloud Firestore는 스키마를 사용하지 않으므로 각 문서에 어떤 필드를 넣을지와 각 필드에 어떤 유형의 데이터를 저장할지는 완전히 사용자의 재량입니다. 같은 컬렉션에 포함된 여러 문서가 서로 다른 필드를 포함하거나 이러한 필드에 서로 다른 유형의 데이터를 저장할 수도 있습니다. 그러나 문서를 보다 쉽게 쿼리할 수 있도록 여러 문서에서 동일한 필드와 데이터 유형을 사용하는 것이 좋습니다.

컬렉션은 오로지 문서만 포함합니다. 값이 있는 원시 필드를 직접 포함하거나 다른 컬렉션을 포함할 수 없습니다. Cloud Firestore에서 보다 복잡한 데이터를 구조화하는 방법은 계층적 데이터를 참조하세요.

컬렉션 내의 문서 이름은 고유합니다. 사용자 ID와 같은 고유한 키를 제공하거나 Cloud Cloud Firestore에서 임의 ID를 자동으로 만들도록 할 수 있습니다.

컬렉션을 직접 '생성' 또는 '삭제'할 필요는 없습니다. 컬렉션에 첫 번째 문서를 만들면 컬렉션이 생성됩니다. 컬렉션의 모든 문서를 삭제하면 컬렉션도 삭제됩니다.

참조

Cloud Firestore의 모든 문서는 데이터베이스 내 위치에 따라 고유하게 식별됩니다. 앞의 예시에 나왔던 alovelace 문서는 users 컬렉션에 속했습니다. 코드에서 이 위치를 참조하려면 위치를 가리키는 참조를 만드세요.

Web

import { doc } from "firebase/firestore";

const alovelaceDocumentRef = doc(db, 'users', 'alovelace');

Web

var alovelaceDocumentRef = db.collection('users').doc('alovelace');
Swift
참고: 이 제품은 watchOS 및 앱 클립 대상에서 사용할 수 없습니다.
let alovelaceDocumentRef = db.collection("users").document("alovelace")
Objective-C
참고: 이 제품은 watchOS 및 앱 클립 대상에서 사용할 수 없습니다.
FIRDocumentReference *alovelaceDocumentRef =
    [[self.db collectionWithPath:@"users"] documentWithPath:@"alovelace"];

Kotlin

val alovelaceDocumentRef = db.collection("users").document("alovelace")

Java

DocumentReference alovelaceDocumentRef = db.collection("users").document("alovelace");

Dart

final alovelaceDocumentRef = db.collection("users").doc("alovelace");
자바
// Reference to a document with id "alovelace" in the collection "users"
DocumentReference document = db.collection("users").document("alovelace");
Python
a_lovelace_ref = db.collection("users").document("alovelace")

Python

a_lovelace_ref = db.collection("users").document("alovelace")
C++
DocumentReference alovelace_document_reference =
    db->Collection("users").Document("alovelace");
Node.js
const alovelaceDocumentRef = db.collection('users').doc('alovelace');
Go

import (
	"cloud.google.com/go/firestore"
)

func createDocReference(client *firestore.Client) {

	alovelaceRef := client.Collection("users").Doc("alovelace")

	_ = alovelaceRef
}
PHP

PHP

Cloud Firestore 클라이언트 설치 및 생성에 관한 자세한 내용은 Cloud Firestore 클라이언트 라이브러리를 참조하세요.

$document = $db->collection('samples/php/users')->document('alovelace');
Unity
DocumentReference documentRef = db.Collection("users").Document("alovelace");
C#

C#

Cloud Firestore 클라이언트 설치 및 생성에 관한 자세한 내용은 Cloud Firestore 클라이언트 라이브러리를 참조하세요.

DocumentReference documentRef = db.Collection("users").Document("alovelace");
Ruby
document_ref = firestore.col("users").doc("alovelace")

참조는 데이터베이스의 특정 위치를 가리키는 간단한 객체입니다. 해당 위치에 데이터가 있는지 여부에 관계없이 참조를 만들 수 있으며, 참조를 만들어도 네트워크 작업이 수행되지 않습니다.

컬렉션을 가리키는 참조를 만들 수도 있습니다.

Web

import { collection } from "firebase/firestore";

const usersCollectionRef = collection(db, 'users');

Web

var usersCollectionRef = db.collection('users');
Swift
참고: 이 제품은 watchOS 및 앱 클립 대상에서 사용할 수 없습니다.
let usersCollectionRef = db.collection("users")
Objective-C
참고: 이 제품은 watchOS 및 앱 클립 대상에서 사용할 수 없습니다.
FIRCollectionReference *usersCollectionRef = [self.db collectionWithPath:@"users"];

Kotlin

val usersCollectionRef = db.collection("users")

Java

CollectionReference usersCollectionRef = db.collection("users");

Dart

final usersCollectionRef = db.collection("users");
자바
// Reference to the collection "users"
CollectionReference collection = db.collection("users");
Python
users_ref = db.collection("users")

Python

users_ref = db.collection("users")
C++
CollectionReference users_collection_reference = db->Collection("users");
Node.js
const usersCollectionRef = db.collection('users');
Go

import (
	"cloud.google.com/go/firestore"
)

func createCollectionReference(client *firestore.Client) {
	usersRef := client.Collection("users")

	_ = usersRef
}
PHP

PHP

Cloud Firestore 클라이언트 설치 및 생성에 관한 자세한 내용은 Cloud Firestore 클라이언트 라이브러리를 참조하세요.

$collection = $db->collection('samples/php/users');
Unity
CollectionReference collectionRef = db.Collection("users");
C#

C#

Cloud Firestore 클라이언트 설치 및 생성에 관한 자세한 내용은 Cloud Firestore 클라이언트 라이브러리를 참조하세요.

CollectionReference collectionRef = db.Collection("users");
Ruby
collection_ref = firestore.col "users"

편의상 경로 구성요소를 포워드 슬래시(/)로 구분한 문자열로 문서 또는 컬렉션의 경로를 지정해 참조를 만들 수도 있습니다. 예를 들어 alovelace 문서에 대한 참조를 만드는 방법은 다음과 같습니다.

Web

import { doc } from "firebase/firestore"; 

const alovelaceDocumentRef = doc(db, 'users/alovelace');

Web

var alovelaceDocumentRef = db.doc('users/alovelace');
Swift
참고: 이 제품은 watchOS 및 앱 클립 대상에서 사용할 수 없습니다.
let aLovelaceDocumentReference = db.document("users/alovelace")
Objective-C
참고: 이 제품은 watchOS 및 앱 클립 대상에서 사용할 수 없습니다.
FIRDocumentReference *aLovelaceDocumentReference =
    [self.db documentWithPath:@"users/alovelace"];

Kotlin

val alovelaceDocumentRef = db.document("users/alovelace")

Java

DocumentReference alovelaceDocumentRef = db.document("users/alovelace");

Dart

final aLovelaceDocRef = db.doc("users/alovelace");
자바
// Reference to a document with id "alovelace" in the collection "users"
DocumentReference document = db.document("users/alovelace");
Python
a_lovelace_ref = db.document("users/alovelace")

Python

a_lovelace_ref = db.document("users/alovelace")
C++
DocumentReference alovelace_document = db->Document("users/alovelace");
Node.js
const alovelaceDocumentRef = db.doc('users/alovelace');
Go

import (
	"cloud.google.com/go/firestore"
)

func createDocReferenceFromString(client *firestore.Client) {
	// Reference to a document with id "alovelace" in the collection "users"
	alovelaceRef := client.Doc("users/alovelace")

	_ = alovelaceRef
}
PHP

PHP

Cloud Firestore 클라이언트 설치 및 생성에 관한 자세한 내용은 Cloud Firestore 클라이언트 라이브러리를 참조하세요.

$document = $db->document('users/alovelace');
Unity
DocumentReference documentRef = db.Document("users/alovelace");
C#

C#

Cloud Firestore 클라이언트 설치 및 생성에 관한 자세한 내용은 Cloud Firestore 클라이언트 라이브러리를 참조하세요.

DocumentReference documentRef = db.Document("users/alovelace");
Ruby
document_path_ref = firestore.doc "users/alovelace"

계층적 데이터

Cloud Firestore의 계층적 데이터 구조를 이해하기 위해, 메시지와 채팅방을 갖춘 채팅 앱 예시를 가정해 보겠습니다.

다음과 같이 여러 채팅방을 저장하는 rooms라는 컬렉션을 만들 수 있습니다.

  • rooms

    • roomA

      name : "my chat room"

    • roomB

      ...

이제 채팅방이 생겼으므로 메시지를 저장할 방법을 결정해야 합니다. 채팅방 문서에는 저장하지 않는 것이 좋습니다. Cloud Firestore의 문서는 가벼워야 하는데 채팅방에 매우 많은 메시지가 포함될 수 있기 때문입니다. 그러나 채팅방 문서 안에 하위 컬렉션을 추가로 만들 수는 있습니다.

하위 컬렉션

이 시나리오에서 메시지를 저장하는 가장 좋은 방법은 하위 컬렉션을 사용하는 것입니다. 하위 컬렉션은 특정 문서와 관련된 컬렉션입니다.

rooms 컬렉션의 모든 채팅방 문서에 messages라는 하위 컬렉션을 만들 수 있습니다.

  • rooms

    • roomA

      name : "my chat room"

      • messages

        • message1

          from : "alex"
          msg : "Hello World!"

        • message2

          ...

    • roomB

      ...

이 예시에서는 다음 코드를 사용하여 하위 컬렉션의 메시지에 대한 참조를 만들 수 있습니다.

Web

import { doc } from "firebase/firestore"; 

const messageRef = doc(db, "rooms", "roomA", "messages", "message1");

Web

var messageRef = db.collection('rooms').doc('roomA')
                .collection('messages').doc('message1');
Swift
참고: 이 제품은 watchOS 및 앱 클립 대상에서 사용할 수 없습니다.
let messageRef = db
  .collection("rooms").document("roomA")
  .collection("messages").document("message1")
Objective-C
참고: 이 제품은 watchOS 및 앱 클립 대상에서 사용할 수 없습니다.
FIRDocumentReference *messageRef =
    [[[[self.db collectionWithPath:@"rooms"] documentWithPath:@"roomA"]
    collectionWithPath:@"messages"] documentWithPath:@"message1"];

Kotlin

val messageRef = db
    .collection("rooms").document("roomA")
    .collection("messages").document("message1")

Java

DocumentReference messageRef = db
        .collection("rooms").document("roomA")
        .collection("messages").document("message1");

Dart

final messageRef = db
    .collection("rooms")
    .doc("roomA")
    .collection("messages")
    .doc("message1");
자바
// Reference to a document in subcollection "messages"
DocumentReference document =
    db.collection("rooms").document("roomA").collection("messages").document("message1");
Python
room_a_ref = db.collection("rooms").document("roomA")
message_ref = room_a_ref.collection("messages").document("message1")

Python

room_a_ref = db.collection("rooms").document("roomA")
message_ref = room_a_ref.collection("messages").document("message1")
C++
DocumentReference message_reference = db->Collection("rooms")
    .Document("roomA")
    .Collection("messages")
    .Document("message1");
Node.js
const messageRef = db.collection('rooms').doc('roomA')
  .collection('messages').doc('message1');
Go

import (
	"cloud.google.com/go/firestore"
)

func createSubcollectionReference(client *firestore.Client) {
	messageRef := client.Collection("rooms").Doc("roomA").
		Collection("messages").Doc("message1")

	_ = messageRef
}
PHP

PHP

Cloud Firestore 클라이언트 설치 및 생성에 관한 자세한 내용은 Cloud Firestore 클라이언트 라이브러리를 참조하세요.

$document = $db
    ->collection('rooms')
    ->document('roomA')
    ->collection('messages')
    ->document('message1');
Unity
DocumentReference documentRef = db
	.Collection("Rooms").Document("RoomA")
	.Collection("Messages").Document("Message1");
C#

C#

Cloud Firestore 클라이언트 설치 및 생성에 관한 자세한 내용은 Cloud Firestore 클라이언트 라이브러리를 참조하세요.

DocumentReference documentRef = db
    .Collection("Rooms").Document("RoomA")
    .Collection("Messages").Document("Message1");
Ruby
message_ref = firestore.col("rooms").doc("roomA").col("messages").doc("message1")

컬렉션과 문서가 교대로 나타나는 패턴에 주목하세요. 컬렉션과 문서는 항상 이 패턴을 따라야 합니다. 컬렉션에 속한 컬렉션이나 문서에 속한 문서는 참조할 수 없습니다.

하위 컬렉션을 사용하여 데이터를 계층적으로 구조화하면 데이터에 쉽게 액세스할 수 있습니다. roomA의 모든 메시지를 가져오려면 하위 컬렉션 messages에 대한 컬렉션 참조를 만들고 다른 컬렉션 참조와 같은 방식으로 상호작용하면 됩니다.

하위 컬렉션의 문서도 하위 컬렉션을 포함할 수 있으므로 데이터를 더 중첩할 수 있습니다. 데이터는 최대 100레벨 깊이까지 중첩할 수 있습니다.