【问题标题】:Document vs Collection文档与集合
【发布时间】:2019-06-19 17:03:51
【问题描述】:

我在 Firestore 上苦苦挣扎。问题是如何构建数据,而不会陷入计费陷阱/噩梦。

我有以下数据结构:

school
  course1
    section1
      page1
      page2
    section2
      page1
      page2
    ...

我假设一门课程通常不会超过 50 个部分。

使用集合

所以我可以使用一个集合并为每个部分创建一个包含每个部分的名称和描述的文档。

db.collection("schools")
.document("school1")
.collection("courses")
.document("course1")
.collection("sections").snapshots()

文档结构:

name: "Section 1"
description: "Description 1"

但是,如果我需要显示部分列表,那么根据 Firestore 计费,我会为每次阅读文档付费。这意味着如果有 20 个部分,我将收取 20 次阅读的费用。

使用带有嵌套集合的文档

我也可以只创建一个文档“课程 1”并嵌套所有部分。

db.collection("schools")
.document("school1")
.collection("courses")
.document("course1")
.get()

文档结构:

name: "Course 1"
description: "The description",
sections: [
  {
    name: "Section 1", 
    description: "Description 1"
    pages: [
      {name: "Page 1", description: "Page Description 1"},
      {name: "Page 2", description: "Page Description 2"}
    ]
  },
  {
    name: "Section 2", 
    description: "Description 2"},
    pages: [
      {name: "Page 1", description: "Page Description 1"},
      {name: "Page 2", description: "Page Description 2"}
    ]
  ...
]

那么我只会被收取 1 次阅读的费用。很可能我不会遇到 40'000 个属性的限制,也不会遇到 1 MB 的限制。

但使用 FutureBuilder 从文档中加载数据似乎需要一些时间,如果我使用 StreamBuilder 获取集合中的文档,这似乎更快。

所以我不知何故无法决定采用哪种方法。不知何故,使用集合会更合乎逻辑,因为我永远不会在任何限制下运行,而且加载似乎更快,但从计费的角度来看,嵌套部分会更有意义。

哪个选项更好?

【问题讨论】:

  • 使用 NoSQL 数据建模,更好的选择是适合您的应用程序需求(您尚未完全指定)的选择。您可能会过度考虑成本和性能。大多数情况下,您应该考虑如何组织数据,以便您的应用可以有效地查询数据,并由应用的 UI 驱动。如果您不知道您的 UI 和查询将是什么,那么您将难以构建数据。不要本末倒置。
  • 从 UI 的角度来看,课程、部分和页面需要一起加载。所以一份文件会更有意义。我肯定是想多了,但我想从成本的角度来解决这个问题,因为如果我不能为客户提供有竞争力的价格,这可能会毁了整个案子。如果我比竞争对手贵,那案子就死定了。如果我以灵活性为代价并需要移动数据,则可能会在将数据从文档迁移到集合期间导致中断,并且还会花费大量时间和成本。估计我需要详细计算,如果没有技术反之亦然。

标签: flutter google-cloud-firestore


【解决方案1】:

我同意您的观点,即何时选择子集合方法而不是传统的多集合方法是很困难的。因此,当您决定选择子集合方法时,请记住以下情况。

何时使用子集合:

1) 当您不想在文档中存储大量字段时。 Cloud Firestore 有 20,000 个字段限制。 (如果学校和课程信息可以超过 20,000 个字段)

2) 更新父集合时是常见的操作。 Firestore 仅允许您以每秒 1 次写入的速率更新文档。 (如果学校、课程和页面信息经常修改)

3) 当您想限制对文档特定字段的访问时。 (如果您想限制对课程页面的访问。在这种情况下,将受限字段移动到另一个集合中的另一个文档也是一个好主意!)

何时不使用子集合:

1) 当你想同时查询集合和子集合时。 Firestore 查询很浅。所以查询父集合时不会查询子集合,所以必须单独查询。 (如果您有案例要在一个窗口中显示所有学校及其课程)

2) 当您想在查看集合时显示子集合时。(当显示一所学校时,您可能希望显示它的课程。这里阅读的数量会增加,因为不是阅读一个文档,而是阅读一个文档文档及其子集合)

3)当你想同时查询集合和子集合时。(你必须使用集合组查询,因为子集合本质上是集合。)

4) 如果您正在考虑查询单个数据,您应该将它们放在一个集合中。 (如果学校的特定属性通常被用户查询或课程的详细信息被多个用户查看)

我的建议:

Schools
  - Array<CourseIds>
  - Other info

Schools集合存储学校信息,可以根据学校的质量搜索哪些学校。学校信息还可以包含一个字段 courses_available ,它可以是一个数组或映射来单独存储课程名称及其unique id

Courses
  -Course info

Courses 集合使用相同的方法,因为我假设课程信息将根据其属性进行大量查询。

CourseSections
  -Course1Section1
    -Pages
  -Course1Section2
    -Pages

CourseSections 收集有关具有子收集的课程部分的信息 Pages

优点:

  1. 这将帮助您为每个部分添加大量页面。
  2. CourseSection 可以按需阅读,因此您在阅读Course 时无需阅读其所有部分。

最终选择取决于您拥有的用例。

希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 2018-12-22
    • 1970-01-01
    • 1970-01-01
    • 2020-12-05
    • 1970-01-01
    • 1970-01-01
    • 2018-06-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多