数据库结构首选项



我有一个基于文档的数据结构,里面充满了用户。关于用户的信息将包括每周议程(一周内要做的活动,例如:周一运行10分钟,周二购物),以及其他基本信息,如他们的名字、性别、年龄等。用户可以有多个每周议程(例如,一个是本周的,另一个是下周的,等等)

然而,我不知道如何构建这些数据。

如果用户目录中有两个子目录,一个子目录名为"weekly_agendas"(包含用户所有每周议程的文档),另一个子目录名称为"user_data",包含姓名、性别、年龄等个人信息。本质上,嵌套数据正在创建中。

或:

是否应将"weekly_agendas"目录移到用户目录之外?

我在谷歌上搜索过所有地方,所有文档通常都建议防止嵌套数据结构,但这种嵌套数据结构怎么会不好呢?

这有助于说明我想要达到的目标:

Structure #1
users
|
+--user_id
|
+--user_data
|
+--username
+--age
+--gender
+--weekly_agenda
|
+--weekly_agenda_number
|
+--1: walk the dog on Monday
+--2: Go shopping on Tuesday

Structure #2:               
users
|
+--user_id
|
+--username
+--age
+--gender

+--weekly_agenda
|
+--user_id
|
+--weekly_agenda_number
|
+--1: walk the dog on Monday
+--2: Go shopping on Tuesday

(为了将来参考,这种类型的"最佳实践"问题比Stack Overflow更适合Firebase Google Group)

首先,我不确定这是故意的还是图表中的错误,但我只想指出,在Structure#1中,应该将usernameagegender作为用户文档中的字段,而不是像图表所示的那样作为子集合。(考虑到你的描述,我猜这就是你的意思,但只是为了确定,因为用户数据对子集合的使用会很差)。

现在谈谈你的主要问题:

Firestore在平面数据结构上操作时受益匪浅,即具有大量小文档而不是少量大文档的数据结构。这是人们在谈论反嵌套实践时提到的要点之一。

如何构建数据完全取决于计划如何与之交互,而不仅仅是查看数据的意义。

如果您计划让用户能够看到其他用户的议程,那么Structure #1将无法像Structure #2那样工作。它仍然可以工作,但查询将更加丑陋。

也就是说,如果议程只对其所有者可见,那么Structure #1可能更有意义,因为组织对该目标更直观。使用Structure #1,您可能会体验到稍微更快的查询响应时间。

Structure #2没有任何问题。如果现在或将来,用户可以查看其他用户的议程,那么Structure #2是你的最佳选择。如果你计划根据其中一个字段在多个用户中搜索议程,Structure #2也会更好。例如,如果您想按timestamp字段查找20个最新的应用程序范围议程文档。

我的项目有一个非常相似的情况,有不同的背景。我们的应用程序有PostsContent。每个CCD_ 14包含一个或多个CCD_。我们本可以将Content作为每个Post的子集合(如您的Structure #1),但我们将Content作为根级别集合(如Structure #2),因为我们需要根据用户的某个字段跨用户查询Content文档。

总之,Structure #2更灵活,但如果您确定不想跨多个用户查询议程(集合组查询),那么Structure #1可能更有利。

我通常默认为Structure #2,除非在那些罕见但合法的情况下,将数据隔离到特定文档确实更有意义。

构建Cloud Firestore数据库没有"完美"、"最好"或"正确"的解决方案。

我在谷歌上搜索过所有地方,所有文档通常都建议防止嵌套数据结构,但这种嵌套数据结构怎么会不好呢?

与Firebase实时数据库中显示每周议程列表不同,您可能已经下载了整个用户对象,在Cloud Firestore中,这不再是问题。因此,在每个用户文档下嵌套一个名为weekly_agenda的子集合不会成为问题。第一种方法的缺点是,您不能查询数据库来显示所有用户的所有议程。因此,一个可能的方案,即您的解决方案的混合方案可能是:

Firestore-root
|
--- users (collection)
|    |
|    --- uid (document)
|         |
|         --- username: "John"
|         |
|         --- age: 22
|         |
|         --- gender: "male"
|
--- weeklyAgenda (collection)
|
--- weeklyAgendaId (document)
|
--- uid: "UidOfTheUser"
|
--- //Weekly Agenda Properties

使用此模式,您可以简单地:

  • 通过在users集合上附加侦听器来查询整个数据库中的所有用户
  • 通过在weeklyAgenda集合上附加一个监听器来查询所有用户的议程
  • 通过使用在Android中可能看起来像这样的查询来查询属于单个用户的所有议程:

    FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
    Query query = productsRef.whereEqualTo("uid", uid);
    

    此查询也可以用其他编程语言编写。

最新更新