在Cloud Firestore中管理非规范化/重复数据

Soc*_*oos 6 firebase google-cloud-firestore

如果您决定在Firestore中对数据进行非规范化/复制以优化读取,那么通常使用哪种模式(如果有)来跟踪重复的数据,以便可以正确地更新它们以避免数据不一致?

例如,如果我具有Pinterest板之类的功能user,平台上的任何功能都可以将我的功能固定post到自己的功能上board,那么您将如何跟踪许多位置的重复数据?

对于为数据可以存在的每个唯一位置创建一个类似关系的表,该表用于重建需要更新的路径。

例如,创建一个users_posts_boards集合,首先是集合userIDs与子集postIDs终于有另一个子集boardIDsboardOwnerID。然后,您可以使用它们来为post(例如/users/[boardOwnerID]/boards/[boardID]/posts/[postID])重建重复数据的路径吗?

另外,如果posts可以额外共享,以groupslists你会继续做users_posts_groups,并users_posts_lists集合和子集,以同样的方式跟踪复制的数据?

另外,您会否拥有posts_denormalization_tracker唯一的集合,postIDs其中包含post已复制到的位置的子集合?

{
  postID: 'someID',
  locations: ( <---- collection
    "path/to/post/location1",
    "path/to/post/location2",
    ...
  )
}
Run Code Online (Sandbox Code Playgroud)

这意味着你将基本上需要有所有写入公司的FireStore通过云的功能实现,可以保持这个数据的轨道出于安全原因....除非公司的FireStore安全规则是足够强大,以允许添加操作的/posts_denormalization_tracker/[postID]/locations子集,而不允许读取或更新子集合或父postIDs集合。

我基本上是在寻找一种跟踪严重的非规范化数据的合理方法。

编辑:哦,是的,另一个很好的例子是将post作者的profile信息嵌入每个文档中post。想象一下,在整个平台上共享时,地狱试图保持所有最新状态,然后对其进行user更新profile

Ale*_*amo 4

我问这个问题是因为你在这里提出要求。

当您复制数据时,需要记住一件事。就像添加数据一样,您也需要维护它。换句话说,如果你想更新/删除一个对象,你需要在它存在的每个地方都进行操作。

通常使用哪些模式(如果有)来跟踪重复的数据,以便可以正确更新它们以避免数据不一致?

为了跟踪我们需要执行的所有操作以获得一致的数据,我们将所有操作添加到一个批次中。您可以对不同的引用添加一项或多项更新操作,以及删除添加操作。为此,请参阅:

如何为数据可能存在的每个唯一位置创建一个类似关系的表,用于重建需要更新的路径。

在我看来,没有必要添加额外的“类似关系的表”,但如果您觉得舒服,请继续使用它。

然后您使用它们来重建帖子的重复数据的路径(例如/users/[boardOwnerID]/boards/[boardID]/posts/[postID])?

是的,您需要向每个document()方法传递相应的文档 ID 才能使更新操作起作用。遗憾的是, Cloud Firestore 文档路径中没有通配符。您必须通过 ID 来识别文档。

或者,您是否会拥有一个 posts_denormalization_tracker,它只是唯一 postID 的集合,其中包含帖子已复制到的位置的子集合?

我认为这也没有必要,因为它需要额外的读取操作。由于 Firestore 中的所有内容都与读取和写入的数量有关,因此我认为您应该再次考虑这种方法。请参阅Firestore 的使用和限制

除非 Firestore 安全规则足够强大,允许向 /posts_denormalization_tracker/[postID]/locations 子集合添加操作,而不允许读取或更新子集合或父 postIDs 集合。

Firestore 安全规则非常强大,可以做到这一点。您还可以允许读取或写入,甚至应用有关您需要的每个 CRUD 操作的安全规则。

我基本上正在寻找一种合理的方法来跟踪严重非规范化的数据。

我能想到的最简单的方法是将操作添加到键和值类型的数据结构中。假设我们有一张如下所示的地图:

Map<Object, DocumentRefence> map = new HashMap<>();
map.put(customObject1, reference1);
map.put(customObject2, reference2);
map.put(customObject3, reference3);
//And so on
Run Code Online (Sandbox Code Playgroud)

遍历映射,并将所有这些键和值添加到批处理中,提交批处理,仅此而已。

  • 是的,所以我知道您可以对非规范化数据执行批量更新。但是如何跟踪该数据所在位置的所有引用呢?举个例子,如果 100 个用户在他们自己的论坛(私人和公共)上“固定”了一个“帖子”,那么在我更新该“帖子”之前,我首先需要搜索*每个*用户的论坛,看看他们是否他们的板上有“帖子”。人们如何解决这个问题? (2认同)