Join us for Firebase Summit on November 10, 2021. Tune in to learn how Firebase can help you accelerate app development, release with confidence, and scale with ease. Register

Mô hình dữ liệu Cloud Firestore

Cloud Firestore là một NoSQL, cơ sở dữ liệu hướng tài liệu. Không giống như cơ sở dữ liệu SQL, không có bảng hoặc hàng. Thay vào đó, bạn lưu trữ dữ liệu trong các văn bản, được tổ chức thành các bộ sưu tập.

Mỗi tài liệu có chứa một tập hợp các cặp khóa-giá trị. Cloud Firestore được tối ưu hóa để lưu trữ các bộ sưu tập lớn các tài liệu nhỏ.

Tất cả các tài liệu phải được lưu trữ trong bộ sưu tập. Tài liệu có thể chứa bộ sưu tập con và các đối tượng lồng nhau, cả hai đều có thể bao gồm các lĩnh vực nguyên thủy như dây hoặc đối tượng phức tạp như danh sách.

Các bộ sưu tập và tài liệu được tạo ngầm trong Cloud Firestore. Chỉ cần gán dữ liệu cho một tài liệu trong một bộ sưu tập. Nếu bộ sưu tập hoặc tài liệu không tồn tại, Cloud Firestore sẽ tạo nó.

Các tài liệu

Trong Cloud Firestore, đơn vị lưu trữ là tài liệu. Tài liệu là một bản ghi gọn nhẹ chứa các trường ánh xạ tới các giá trị. Mỗi tài liệu được xác định bằng một tên.

Một tài liệu đại diện cho một người sử dụng alovelace có thể trông như thế này:

  • alovelace

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

Các đối tượng phức tạp, lồng nhau trong một tài liệu được gọi là bản đồ. Ví dụ: bạn có thể cấu trúc tên của người dùng từ ví dụ trên với một bản đồ, như sau:

  • alovelace

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

Bạn có thể nhận thấy rằng các tài liệu trông rất giống JSON. Trên thực tế, về cơ bản chúng là như vậy. Có một số khác biệt (ví dụ: tài liệu hỗ trợ các loại dữ liệu bổ sung và có kích thước giới hạn ở 1 MB), nhưng nói chung, bạn có thể coi tài liệu là bản ghi JSON nhẹ.

Bộ sưu tập

Tài liệu nằm trong các bộ sưu tập, đơn giản là các thùng chứa tài liệu. Ví dụ, bạn có thể có một users bộ sưu tập để chứa người dùng khác nhau của bạn, mỗi đại diện bởi một tài liệu:

  • người dùng

    • alovelace

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

    • aturing

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

Cloud Firestore không có tính toán, vì vậy bạn hoàn toàn có quyền tự do đối với những trường bạn đặt trong mỗi tài liệu và những kiểu dữ liệu bạn lưu trữ trong những trường đó. Tất cả các tài liệu trong cùng một bộ sưu tập có thể chứa các trường khác nhau hoặc lưu trữ các loại dữ liệu khác nhau trong các trường đó. Tuy nhiên, bạn nên sử dụng các trường và kiểu dữ liệu giống nhau trên nhiều tài liệu để bạn có thể truy vấn tài liệu dễ dàng hơn.

Một bộ sưu tập chứa các tài liệu và không có gì khác. Nó không thể chứa trực tiếp các trường thô có giá trị và không thể chứa các bộ sưu tập khác. (Xem dữ liệu phân cấp cho một lời giải thích làm thế nào để cấu trúc dữ liệu phức tạp hơn trong Cloud FireStore.)

Tên của các tài liệu trong một bộ sưu tập là duy nhất. Bạn có thể cung cấp khóa của riêng mình, chẳng hạn như ID người dùng hoặc bạn có thể để Cloud Firestore tự động tạo ID ngẫu nhiên cho bạn.

Bạn không cần phải "tạo" hoặc "xóa" các bộ sưu tập. Sau khi bạn tạo tài liệu đầu tiên trong một bộ sưu tập, bộ sưu tập sẽ tồn tại. Nếu bạn xóa tất cả các tài liệu trong một bộ sưu tập, nó sẽ không còn tồn tại.

Người giới thiệu

Mọi tài liệu trong Cloud Firestore đều được xác định duy nhất theo vị trí của nó trong cơ sở dữ liệu. Ví dụ trước đây cho thấy một tài liệu alovelace trong bộ sưu tập users . Để chỉ vị trí này trong mã của bạn, bạn có thể tạo một tham chiếu đến nó.

Phiên bản web 9

import { doc } from "firebase/firestore";

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

Phiên bản web 8

var alovelaceDocumentRef = db.collection('users').doc('alovelace');
Nhanh
let alovelaceDocumentRef = db.collection("users").document("alovelace")
Objective-C
FIRDocumentReference *alovelaceDocumentRef =
    [[self.db collectionWithPath:@"users"] documentWithPath:@"alovelace"];

Java

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

Kotlin + KTX

val alovelaceDocumentRef = db.collection("users").document("alovelace")
Java
// Reference to a document with id "alovelace" in the collection "users"
DocumentReference document = db.collection("users").document("alovelace");
Python
a_lovelace_ref = db.collection(u'users').document(u'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');
Đi
alovelaceRef := client.Collection("users").Doc("alovelace")
PHP
$document = $db->collection('samples/php/users')->document('lovelace');
Đoàn kết
DocumentReference documentRef = db.Collection("users").Document("alovelace");
NS#
DocumentReference documentRef = db.Collection("users").Document("alovelace");
Ruby
document_ref = firestore.col("users").doc("alovelace")

Tham chiếu là một đối tượng nhẹ chỉ đến một vị trí trong cơ sở dữ liệu của bạn. Bạn có thể tạo tham chiếu cho dù dữ liệu có tồn tại ở đó hay không và việc tạo tham chiếu không thực hiện bất kỳ hoạt động mạng nào.

Bạn cũng có thể tạo ra tài liệu tham khảo bộ sưu tập:

Phiên bản web 9

import { collection } from "firebase/firestore";

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

Phiên bản web 8

var usersCollectionRef = db.collection('users');
Nhanh
let usersCollectionRef = db.collection("users")
Objective-C
FIRCollectionReference *usersCollectionRef = [self.db collectionWithPath:@"users"];

Java

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

Kotlin + KTX

val usersCollectionRef = db.collection("users")
Java
// Reference to the collection "users"
CollectionReference collection = db.collection("users");
Python
users_ref = db.collection(u'users')

Python

users_ref = db.collection("users")
C ++
CollectionReference users_collection_reference = db->Collection("users");
Node.js
const usersCollectionRef = db.collection('users');
Đi
usersRef := client.Collection("users")
PHP
$collection = $db->collection('samples/php/users');
Đoàn kết
CollectionReference collectionRef = db.Collection("users");
NS#
CollectionReference collectionRef = db.Collection("users");
Ruby
collection_ref = firestore.col "users"

Để thuận tiện, bạn cũng có thể tạo ra tài liệu tham khảo bằng cách xác định đường dẫn đến một tài liệu hoặc bộ sưu tập như là một chuỗi, với các thành phần con đường cách nhau bởi một dấu gạch chéo ( / ). Ví dụ, để tạo một tham chiếu đến alovelace tài liệu:

Phiên bản web 9

import { doc } from "firebase/firestore"; 

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

Phiên bản web 8

var alovelaceDocumentRef = db.doc('users/alovelace');
Nhanh
let aLovelaceDocumentReference = db.document("users/alovelace")
Objective-C
FIRDocumentReference *aLovelaceDocumentReference =
    [self.db documentWithPath:@"users/alovelace"];

Java

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

Kotlin + KTX

val alovelaceDocumentRef = db.document("users/alovelace")
Java
// Reference to a document with id "alovelace" in the collection "users"
DocumentReference document = db.document("users/alovelace");
Python
a_lovelace_ref = db.document(u'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');
Đi
alovelaceRef := client.Doc("users/alovelace")
PHP
$document = $db->document('users/lovelace');
Đoàn kết
DocumentReference documentRef = db.Document("users/alovelace");
NS#
DocumentReference documentRef = db.Document("users/alovelace");
Ruby
document_path_ref = firestore.doc "users/alovelace"

Dữ liệu phân cấp

Để hiểu cách cấu trúc dữ liệu phân cấp hoạt động trong Cloud Firestore, hãy xem xét một ứng dụng trò chuyện mẫu với tin nhắn và phòng trò chuyện.

Bạn có thể tạo một bộ sưu tập được gọi là rooms để lưu trữ các phòng chat khác nhau:

  • phòng

    • RoomA

      name : "my chat room"

    • roomB

      ...

Bây giờ bạn đã có phòng trò chuyện, hãy quyết định cách lưu trữ tin nhắn của bạn. Bạn có thể không muốn lưu trữ chúng trong tài liệu của phòng trò chuyện. Tài liệu trong Cloud Firestore phải nhẹ và phòng trò chuyện có thể chứa một lượng lớn tin nhắn. Tuy nhiên, bạn có thể tạo các bộ sưu tập bổ sung trong tài liệu của phòng trò chuyện của mình, dưới dạng các bộ sưu tập con.

Bộ sưu tập con

Cách tốt nhất để lưu trữ tin nhắn trong trường hợp này là sử dụng các bộ sưu tập con. Bộ sưu tập con là một bộ sưu tập được liên kết với một tài liệu cụ thể.

Bạn có thể tạo một subcollection gọi là messages cho tất cả các tài liệu trong phòng của bạn rooms bộ sưu tập:

  • phòng

    • RoomA

      name : "my chat room"

      • thông điệp

        • message1

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

        • message2

          ...

    • roomB

      ...

Trong ví dụ này, bạn sẽ tạo một tham chiếu đến một thư trong bộ sưu tập con bằng mã sau:

Phiên bản web 9

import { doc } from "firebase/firestore"; 

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

Phiên bản web 8

var messageRef = db.collection('rooms').doc('roomA')
                .collection('messages').doc('message1');
Nhanh
let messageRef = db
    .collection("rooms").document("roomA")
    .collection("messages").document("message1")
Objective-C
FIRDocumentReference *messageRef =
    [[[[self.db collectionWithPath:@"rooms"] documentWithPath:@"roomA"]
    collectionWithPath:@"messages"] documentWithPath:@"message1"];

Java

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

Kotlin + KTX

val messageRef = db
        .collection("rooms").document("roomA")
        .collection("messages").document("message1")
Java
// Reference to a document in subcollection "messages"
DocumentReference document =
    db.collection("rooms").document("roomA").collection("messages").document("message1");
Python
room_a_ref = db.collection(u'rooms').document(u'roomA')
message_ref = room_a_ref.collection(u'messages').document(u'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');
Đi
messageRef := client.Collection("rooms").Doc("roomA").
	Collection("messages").Doc("message1")
PHP
$document = $db
    ->collection('rooms')
    ->document('roomA')
    ->collection('messages')
    ->document('message1');
Đoàn kết
DocumentReference documentRef = db
	.Collection("Rooms").Document("RoomA")
	.Collection("Messages").Document("Message1");
NS#
DocumentReference documentRef = db
    .Collection("Rooms").Document("RoomA")
    .Collection("Messages").Document("Message1");
Ruby
message_ref = firestore.col("rooms").doc("roomA").col("messages").doc("message1")

Lưu ý mô hình xen kẽ của các bộ sưu tập và tài liệu. Bộ sưu tập và tài liệu của bạn phải luôn tuân theo mẫu này. Bạn không thể tham chiếu một bộ sưu tập trong một bộ sưu tập hoặc một tài liệu trong một tài liệu.

Các bộ sưu tập con cho phép bạn cấu trúc dữ liệu theo thứ bậc, giúp cho việc truy cập dữ liệu dễ dàng hơn. Để có được tất cả thư trong roomA , bạn có thể tạo ra một tài liệu tham khảo bộ sưu tập đến subcollection messages và tương tác với nó như bạn sẽ bất kỳ tài liệu tham khảo bộ sưu tập khác.

Các tài liệu trong bộ sưu tập con cũng có thể chứa các bộ sưu tập con, cho phép bạn lồng ghép thêm dữ liệu. Bạn có thể lồng dữ liệu sâu tới 100 cấp độ.