Firebase数据库 - "扇出"技术

fra*_*kee 11 java android nosql firebase firebase-realtime-database

我正在调查针对Android 的Firebase数据库示例,并意识到它以下列方式存储其数据:

在此输入图像描述

我不太熟悉NoSQL技术,并试图理解为什么我们必须坚持每个post实体两次 - 在postsuser_posts相应地.文档说这种方法被称为"扇出",我完全同意通过简单的构造来访问用户的帖子可能是有用的databaseReference.child("user-posts").child("<user_uid>").但为什么我们需要posts节点呢?如果我们需要更新一些帖子怎么办?我们必须做两次吗?

// [START write_fan_out]
private void writeNewPost(String userId, String username, String title, String body) {
    // Create new post at /user-posts/$userid/$postid and at
    // /posts/$postid simultaneously
    String key = mDatabase.child("posts").push().getKey();
    Post post = new Post(userId, username, title, body);
    Map<String, Object> postValues = post.toMap();

    Map<String, Object> childUpdates = new HashMap<>();
    childUpdates.put("/posts/" + key, postValues);
    childUpdates.put("/user-posts/" + userId + "/" + key, postValues);

    mDatabase.updateChildren(childUpdates);
}
// [END write_fan_out]
Run Code Online (Sandbox Code Playgroud)

所以我想...当这种方法可能有用时,何时不是?Firebase SDK是否提供了在更新或删除数据时保持所有重复项同步的任何工具?


更新:这里是解释接收从火力地堡团队:

帖子重复的原因是因为我们希望能够快速获取属于用户的所有帖子(如您所建议的),并且从所有帖子的列表中过滤以获得一个用户的帖子可能会变得相当昂贵,因为帖子数量扩大.

这意味着每当我们更新帖子时,我们都必须在两个位置更新帖子.它使代码变得更加丑陋,但由于查询比写入更常见,因此最好优化读取数据.

我怀疑这种方法可能看起来不太优雅,但它可能是大型数据集的最快选择,只要您执行SELECT比UPDATE更频繁.但是,在某些情况下,我宁愿坚持使用此处推荐的其他解决方案.

dav*_*eda 7

Data Fan Out是管理大量数据的绝佳技术.如果不使用此模式,将来可能会出现严重的扩展问题.

我从您的数据库结构中看到的是,您将整个帖子信息存储两次,这不是一个好习惯.您希望存储另一个节点下的帖子的引用.因此,您将拥有一个名为的节点users-posts,该节点将包含用户密钥,并且每个密钥都将具有一组值为的帖子密钥true.为了更清楚:

在此输入图像描述

这样,您就可以跟踪用户在users-posts节点下编写的帖子; 以及在posts节点下编写每个帖子的用户.现在,您可能需要获取所有用户帖子的列表.您需要做的是在users-posts/USER_KEY/节点上进行同步以获取用户编写的所有帖子的密钥,然后使用您刚刚获得的帖子密钥获取更多帖子信息.

为什么建议使用此数据库设计?因为每次同步获得的信息要少得多(使用Firebase,我们不会发出请求,因此我将读取称为同步).在您的示例中,如果您附加一个监听器以user-posts/USER_KEY/获取所有帖子的列表,您还将询问他们所写的每个和每个帖子的所有信息.使用数据扇出方法,您可以只询问所需的帖子信息,因为您已经拥有帖子的密钥.

  • 你的建议与扇出相反.您建议使用此方法可以使数据保存更简单,但会在数百万个帖子中减慢查询速度,您需要逐个查询ID.因此扇出(复制)是Firebase建议处理这种规模的,请参阅此帖子:https://firebase.googleblog.com/search?update-max = 2015-10-13T20:08:00:07: 00最大结果= 1&开始= 24&按日期=假 (2认同)