数据库结构首选项

时间:2019-01-16 01:03:48

标签: mongodb nosql google-cloud-firestore

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

但是我不知道如何构造这些数据。

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

OR:

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

我到处都有Google搜索,所有文档通常都建议防止嵌套数据结构,但是这种嵌套数据结构怎么可能不好呢?

这可以帮助说明我要达到的目标:

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

2 个答案:

答案 0 :(得分:0)

(供以后参考,这种“最佳实践”问题比堆栈溢出更适合Firebase Google Group

首先,我不确定这是故意的还是您的图中的错误,但我只想指出,在结构1中,您应该有usernameagegender作为用户文档中的字段,而不是如图所示的子集合。 (根据您的描述,我想这就是您的意思,但是请确定,因为用户数据对子集合的使用不佳。)

现在是您的主要问题:

当在 flat 数据结构上运行时,

Firestore会大大受益,即,该结构具有大量的小文档,而不是少量的大文档。这是人们在谈论反嵌套做法时所指的要点之一。

数据的结构方式完全取决于计划与之交互的方式,而不仅取决于如何看待。

如果您计划用户能够看到其他用户的议程,那么

Structure #1的效果将不如Structure #2。仍然可以,但是查询会更麻烦。

话虽如此,如果议程仅对其所有者可见,则考虑到组织对于该目标更为直观的​​事实,Structure #1可能更有意义。使用Structure #1也可能会稍微加快查询响应速度。

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

我的项目有非常相似的情况,但上下文不同。我们的应用程序包含PostsContent。每个Post包含一个或多个Content。我们可以将Content设为每个Post的子集合(例如您的Structure #1),但是我们改为使Content成为根级别的集合(例如您的Structure #2 ),因为我们需要根据用户的其中一个字段来查询Content个文档。

最后,Structure #2更加灵活,但是如果您确定不想在多个用户之间查询议程(collection group query),那么Structure #1可能更有利

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

答案 1 :(得分:0)

没有用于构建Cloud Firestore数据库的“完美”,“最佳”或"the correct"解决方案。

  

我到处都有Google搜索,所有文档通常都建议防止嵌套数据结构,但是这种嵌套数据结构怎么可能不好呢?

与在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);
    

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