如果您决定在Firestore中对数据进行非规范化/复制以优化读取,那么通常使用什么模式(如果有)来跟踪重复的数据,以便可以正确地对其进行更新以避免数据不一致?
例如,如果我拥有Pinterest板之类的功能,平台上的任何user
都可以将我的post
固定到自己的board
上,那么您将如何跟踪许多位置中的重复数据?
关于为数据可以存在的每个唯一位置创建一个类似关系的表,该表用于重建需要更新的路径。
例如,创建一个users_posts_boards
集合,该集合首先是一个userIDs
子集合的postIDs
集合,最后又具有一个boardIDs
的子集合boardOwnerID
。然后,您可以使用它们来重构post
(例如/users/[boardOwnerID]/boards/[boardID]/posts/[postID]
)的重复数据的路径吗?
如果另外可以将posts
与groups
和lists
共享,您是否会继续创建users_posts_groups
和users_posts_lists
集合和子集合来跟踪重复项数据以同样的方式?
或者,您是否有一个posts_denormalization_tracker
只是唯一的postIDs
的集合,其中包括post
被复制到的位置的子集合?
{
postID: 'someID',
locations: ( <---- collection
"path/to/post/location1",
"path/to/post/location2",
...
)
}
这意味着您基本上需要通过Cloud Functions完成所有对Firestore的写入操作,出于安全原因,这些功能可以跟踪此数据。...除非Firestore安全规则足够强大,以允许对{ {1}}子集合,不允许对该子集合或父/posts_denormalization_tracker/[postID]/locations
集合进行读取或更新。
我基本上是在寻找一种跟踪严重的非规范化数据的理智方法。
编辑:是的,另一个很好的例子是将postIDs
作者的post
信息嵌入到每个profile
中。想象一下,在整个平台上共享时,地狱试图保持所有最新状态,然后post
更新其user
。
答案 0 :(得分:0)
由于您来自here的请求,我在问这个问题。
复制数据时,请记住一件事。用与添加数据相同的方式,您需要对其进行维护。换句话说,如果要更新/删除对象,则需要在对象存在的每个位置进行处理。
通常使用什么模式(如果有的话)来跟踪重复的数据,以便可以正确地更新它们以避免数据不一致?
要跟踪拥有一致数据所需执行的所有操作,我们将所有操作添加到批处理中。您可以在不同的引用上添加一个或多个 update 操作,以及 delete 或 add 操作。为此,请参见:
关于为数据可以存在的每个唯一位置创建一个类似关系的表,该表用于重建需要更新的路径。
我认为不需要添加额外的“类似关系的表”,但是如果您对此感到不舒服,请继续使用它。
然后,您可以使用它们来重构帖子的重复数据的路径(例如
/users/[boardOwnerID]/boards/[boardID]/posts/[postID]
)吗?
是的,您需要将每个文档的ID传递给每个document()
方法,以使更新操作起作用。不幸的是,Cloud Firestore的文档路径中没有通配符。您必须通过文档ID来识别它们。
或者,您是否会拥有一个posts_denormalization_tracker,它只是唯一的postID的集合,其中包括该帖子被复制到的位置的子集合?
我认为这也是不必要的,因为它需要额外的读取操作。由于Firestore中的所有内容都是关于读写次数的,所以我认为您应该再次考虑这种方法。请参阅Firestore usage and limits。
除非Firestore安全规则足够强大,以允许对/ posts_denormalization_tracker / [postID] / locations子集合进行添加操作,但不允许读取或更新子集合或父postIDs集合。
Firestore security rules如此强大。您还可以允许阅读或编写甚至应用有关所需的每个CRUD操作的安全规则。
我基本上是在寻找一种跟踪严重的非规范化数据的理智方法。
我能想到的最简单的方法是将操作添加到键和值类型的数据结构中。假设我们有一张看起来像这样的地图:
Map<Object, DocumentRefence> map = new HashMap<>();
map.put(customObject1, reference1);
map.put(customObject2, reference2);
map.put(customObject3, reference3);
//And so on
遍历整个地图,并将所有这些键和值添加到批处理中,然后提交批处理。