在Firestore中构造此类数据的正确方法是什么?

时间:2018-10-29 21:03:15

标签: java firebase firebase-realtime-database google-cloud-firestore

我已经从Google Firebase服务中观看了视频并阅读了Cloud Firestore的文档,但是我无法确定这是来自实时数据库。

我想到了这个Web应用程序,我想在其中存储来自不同类别产品的提供商。我想对我所有的产品执行搜索查询,以找到该产品的供应商,并最终访问该供应商信息。

我正打算将这种结构用于此目的

Providers ( Collection )
   Provider 1 ( Document )
      Name
      City
      Categories
   Provider 2
      Name
      City

Products ( Collection )
   Product 1 ( Document )
      Name
      Description
      Category
      Provider ID
   Product 2
      Name
      Description
      Category
      Provider ID

所以我的问题是,一旦我得到想要的产品,这种方法是访问提供商信息的正确方法吗?

我知道这在实时数据库中是可能的,使用提供者ID可以在“提供者”部分中搜索该提供者,但是对于Firestore,我不确定这是否可行或正确的方法。

1 个答案:

答案 0 :(得分:8)

  

在Firestore中构造此类数据的正确方法是什么?

您需要知道,没有用于构建Cloud Firestore数据库的“完美”,“最佳”或“正确”解决方案。最佳和正确的解决方案是适合您的需求并使您的工作更轻松的解决方案。还请记住,在NoSQL数据库的世界中也没有没有一个“正确的数据结构”。所有数据均经过建模,以允许您的应用程序需要用例。这意味着对一个应用程序有效的功能可能对另一应用程序而言是不够的。因此,没有一种适合所有人的正确解决方案。 NoSQL类型数据库的有效结构完全取决于您打算如何查询它。

您构建数据的方式对我来说很好。通常,可以通过两种方法实现同一件事。第一个是在产品对象中保留提供者的引用(就像您已经做过的那样),或者在产品文档中复制整个提供者对象。最后一种技术称为denormalization,在涉及Firebase时,这是一种非常普遍的做法。因此,我们经常在nosql数据库中复制数据,以适应否则可能无法进行的查询。为了更好地理解,我建议您观看此视频Denormalization is normal with the Firebase Database。它用于Firebase实时数据库,但相同的原理也适用于Cloud Firestore。

此外,在复制数据时,需要记住一件事。用与添加数据相同的方式,您需要对其进行维护。换句话说,如果要更新/删除提供程序对象,则需要在它存在的每个位置进行操作。

您可能现在想知道哪种技术最好。从广义上讲,在NoSQL数据库中存储引用或重复数据的最佳方式完全取决于项目的需求。

因此,您应该问自己一些有关要复制的数据的问题,或者只是将其保留为参考:

  1. 是静态的还是随时间变化的?
  2. 如果这样做,是否需要更新每个重复的数据实例,以便它们都保持同步?这是我之前也提到的。
  3. 在谈到Firestore时,您是否正在针对performancecost进行优化?

如果重复的数据需要同时更改并保持同步,那么将来可能很难将所有重复的数据保持最新状态。这也可能意味着您要花很多钱来使所有这些文档保持最新状态,因为每次更改都需要对每个文档进行读写操作。在这种情况下,仅保留引用将是赢家。

通过这种方法,您将写入很少的重复数据(几乎只有Provider ID)。因此,这意味着您编写此数据的代码将非常简单且非常快速。但是在读取数据时,您将需要从两个集合中加载数据,这意味着需要进行额外的数据库调用。对于合理数量的文档而言,这通常不是一个大的性能问题,但确实确实需要更多的代码和更多的API调用。

如果您需要非常快速的查询,则可能希望复制更多的数据,以便客户端只需要为每个查询项目读取一个文档,而不是多个文档。但是您也许还可以依靠本地客户端缓存使此便宜,这取决于客户端必须读取的数据。

通过这种方法,您将为每个provider文档复制product的所有数据。这意味着编写此数据的代码更加复杂,并且您肯定要存储更多的数据,每个产品文档还有一个提供者对象。而且,您需要确定是否以及如何使其保持最新状态。但是另一方面,现在阅读product文档会以一个阅读方式为您提供有关provider文档的所有信息。

这是NoSQL数据库中的常见注意事项:您通常必须考虑写入性能和磁盘存储与读取性能和可伸缩性。

在选择是否复制某些数据时,它很大程度上取决于您的数据及其特征。您将不得不逐案考虑。

因此,最后请记住,这两种方法都是有效的方法,并且两者都不比其他方法更好。这完全取决于您的用例以及您对这种新的复制数据技术的适应程度。数据复制是快速读取的关键,不仅在Cloud Firestore或Fireabase实时数据库中,而且在一般情况下。每当您将相同数据添加到其他位置时,您都在复制数据以提高读取速度。不幸的是,作为回报,您拥有更复杂的更新和更高的存储/内存使用率。但您需要注意,在Firebase实时数据库中,额外的调用并不昂贵,在Firestore中则是昂贵的。对于您来说,最佳的复制数据量是额外的数据库调用量,具体取决于您的需求以及您是否愿意放弃“单点定义思维方式”,这可以说是非常主观的。

在完成了一些Firebase项目之后,我发现如果我复制数据,我的阅读代码将大大简化。但是,当然,编写代码会同时变得更加复杂。两者之间的权衡决定了您的应用程序的最佳解决方案。此外,更精确地说,您还可以使用现有工具衡量应用程序中发生的事情并做出相应的决定。我知道这不是具体的建议,而是软性发展。一切都与衡量事物有关。

还请记住,某些数据库结构更易于通过某些安全规则进行保护。因此,尝试找到可以使用Cloud Firestore Security Rules轻松保护的架构。

也请查看我从此 post 中获得的答案,其中我详细介绍了Firestore中的collectionsmapsarrays