数据模型
Firestore 是一种基于文档的 NoSQL 数据库。与 SQL 数据库不同的是,它没有表格或行的概念,而是将数据存储在文档中,并将文档组织为集合。
每个文档包含一组键值对。Firestore 经过优化,可用于存储小型文档的大型集合。
所有文档必须存储在集合中。文档可以包含子集合和嵌套对象,两者都可以包括原始字段(如字符串)或复杂对象(如列表)。
集合和文档是在 Firestore 中隐式创建的。 只需将数据分配给集合中的文档即可。如果集合或文档不存在,Firestore 会创建一个。
文档
在 Firestore 中,存储单元是文档。文档是一个轻量级记录,包含映射到值的字段。每个文档都用一个名称进行标识。
代表用户 alovelace
的文档可能如下所示:
alovelace
first : "Ada"
last : "Lovelace"
born : 1815
文档中的复杂嵌套对象称为映射 (map)。例如,您可以使用映射来设计上例中用户姓名的结构,如下所示:
alovelace
name :
first : "Ada"
last : "Lovelace"
born : 1815
您可能会注意到,文档看起来很像 JSON。它们其实基本上就是 JSON,但有稍许差异(例如,文档支持额外的数据类型,大小限制为 1 MB),但总体而言,您可以将文档视为轻量级 JSON 记录。
集合
文档存在于集合中,简单来说,集合就是文档的容器。例如,您可以使用 users
集合来容纳您的各个用户,每个用户用一个文档来表示:
users
alovelace
first : "Ada"
last : "Lovelace"
born : 1815
aturing
first : "Alan"
last : "Turing"
born : 1912
Firestore 是无架构的,所以您可以自由选择在每个文档中设置什么字段以及在这些字段中存储什么数据类型。同一集合中的文档可以全部包含不同的字段或在这些字段中存储不同类型的数据。但比较好的做法是在多个文档中使用相同的字段和数据类型,以便您可以更轻松地查询文档。
集合只包含文档,不包含任何其他内容。它不能直接包含带有值的原始字段,也不能包含其他集合。(如需了解如何在 Firestore 中设计更复杂数据的结构,请参阅分层数据。)
集合中的文档名称是唯一的。您可以提供自己的密钥(例如用户 ID),或者可以让 Firestore 自动为您创建随机 ID。
您无需“创建”或“删除”集合。在集合中创建第一个文档之后,集合才会存在。如果删除集合中的所有文档,集合将不再存在。
引用
Firestore 中的每个文档都通过其在数据库中的位置唯一进行标识。之前的示例展示了集合 users
中的一个文档 alovelace
。如需在代码中引用此位置,您可以创建一个指向此位置的引用。
Web 版本 9
import { doc } from "firebase/firestore"; const alovelaceDocumentRef = doc(db, 'users', 'alovelace');
Web 版本 8
var alovelaceDocumentRef = db.collection('users').doc('alovelace');
Swift
let alovelaceDocumentRef = db.collection("users").document("alovelace")
Objective-C
FIRDocumentReference *alovelaceDocumentRef = [[self.db collectionWithPath:@"users"] documentWithPath:@"alovelace"];
Kotlin
Android
val alovelaceDocumentRef = db.collection("users").document("alovelace")
Java
Android
DocumentReference alovelaceDocumentRef = db.collection("users").document("alovelace");
Dart
final alovelaceDocumentRef = db.collection("users").doc("alovelace");
Java
Python
Python
(异步)
C++
DocumentReference alovelace_document_reference = db->Collection("users").Document("alovelace");
Node.js
Go
PHP
PHP
如需向 Firestore 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为本地开发环境设置身份验证。
Unity
DocumentReference documentRef = db.Collection("users").Document("alovelace");
C#
C#
如需向 Firestore 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为本地开发环境设置身份验证。
Ruby
引用是一个轻量级对象,它仅指向数据库中的某个位置。无论此位置中是否存在数据,您都可以创建引用,并且创建引用不会执行任何网络操作。
您还可以创建对集合的引用:
Web 版本 9
import { collection } from "firebase/firestore"; const usersCollectionRef = collection(db, 'users');
Web 版本 8
var usersCollectionRef = db.collection('users');
Swift
let usersCollectionRef = db.collection("users")
Objective-C
FIRCollectionReference *usersCollectionRef = [self.db collectionWithPath:@"users"];
Kotlin
Android
val usersCollectionRef = db.collection("users")
Java
Android
CollectionReference usersCollectionRef = db.collection("users");
Dart
final usersCollectionRef = db.collection("users");
Java
Python
Python
(异步)
C++
CollectionReference users_collection_reference = db->Collection("users");
Node.js
Go
PHP
PHP
如需向 Firestore 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为本地开发环境设置身份验证。
Unity
CollectionReference collectionRef = db.Collection("users");
C#
C#
如需向 Firestore 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为本地开发环境设置身份验证。
Ruby
为方便起见,您还可以通过将文档或集合的路径指定为字符串来创建引用,路径组成部分之间用正斜杠 (/
) 分隔。例如,如需创建对 alovelace
文档的引用,请执行以下操作:
Web 版本 9
import { doc } from "firebase/firestore"; const alovelaceDocumentRef = doc(db, 'users/alovelace');
Web 版本 8
var alovelaceDocumentRef = db.doc('users/alovelace');
Swift
let aLovelaceDocumentReference = db.document("users/alovelace")
Objective-C
FIRDocumentReference *aLovelaceDocumentReference = [self.db documentWithPath:@"users/alovelace"];
Kotlin
Android
val alovelaceDocumentRef = db.document("users/alovelace")
Java
Android
DocumentReference alovelaceDocumentRef = db.document("users/alovelace");
Dart
final aLovelaceDocRef = db.doc("users/alovelace");
Java
Python
Python
(异步)
C++
DocumentReference alovelace_document = db->Document("users/alovelace");
Node.js
Go
PHP
PHP
如需向 Firestore 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为本地开发环境设置身份验证。
Unity
DocumentReference documentRef = db.Document("users/alovelace");
C#
C#
如需向 Firestore 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为本地开发环境设置身份验证。
Ruby
分层数据
要了解分层数据结构在 Firestore 中的工作原理,让我们以一个提供消息和聊天室功能的聊天应用来看一看。
您可以创建名为 rooms
的集合来存储不同的聊天室:
rooms
roomA
name : "my chat room"
roomB
...
现在您已经有聊天室了,需要决定如何存储消息。您可能不想将它们存储在聊天室的文档中。这是因为 Firestore 中的文档应该是轻量级的,而聊天室可能包含大量消息。 但是,您可以在聊天室的文档中创建额外的集合作为子集合。
子集合
在此例中,存储消息的最佳方式是使用子集合。子集合是指与某个文档相关联的集合。
您可以为 rooms
集合中的每个聊天室文档创建名为 messages
的子集合:
rooms
roomA
name : "my chat room"
messages
message1
from : "alex"
msg : "Hello World!"
message2
...
roomB
...
在此例中,您将使用以下代码创建对子集合中的消息的引用:
Web 版本 9
import { doc } from "firebase/firestore"; const messageRef = doc(db, "rooms", "roomA", "messages", "message1");
Web 版本 8
var messageRef = db.collection('rooms').doc('roomA') .collection('messages').doc('message1');
Swift
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"];
Kotlin
Android
val messageRef = db .collection("rooms").document("roomA") .collection("messages").document("message1")
Java
Android
DocumentReference messageRef = db .collection("rooms").document("roomA") .collection("messages").document("message1");
Dart
final messageRef = db .collection("rooms") .doc("roomA") .collection("messages") .doc("message1");
Java
Python
Python
(异步)
C++
DocumentReference message_reference = db->Collection("rooms") .Document("roomA") .Collection("messages") .Document("message1");
Node.js
Go
PHP
PHP
如需向 Firestore 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为本地开发环境设置身份验证。
Unity
DocumentReference documentRef = db .Collection("Rooms").Document("RoomA") .Collection("Messages").Document("Message1");
C#
C#
如需向 Firestore 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为本地开发环境设置身份验证。
Ruby
请注意集合和文档的交替模式。您的集合和文档必须始终遵循此模式。您不能在集合中引用集合或在文档中引用文档。
子集合可让您以分层方式设计数据结构,使数据更易于访问。如需获取 roomA
中的所有消息,您可以创建对子集合 messages
的集合引用,并像与任何其他集合引用交互一样与其进行交互。
子集合中的文档也可以包含子集合,以便进一步嵌套数据。嵌套数据的深度最多可达 100 层。