Firebase数据库 - “扇出”技术

时间:2016-07-04 10:05:39

标签: java android firebase firebase-realtime-database nosql

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

enter image description here

我对NoSQL技术并不熟悉,并试图理解为什么我们必须在postposts相应地保留每个user_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]

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

更新:以下是Firebase小组的解释received

  

帖子重复的原因是因为我们希望能够   快速获取属于用户的所有帖子(如您所建议的)和   从所有帖子的列表中过滤以获得一个用户的帖子   随着帖子数量的增加,可能会变得非常昂贵。

     

这确实意味着我们必须在两个位置更新帖子   每当我们更新它。它使代码有点丑陋但是从那以后   查询比写入更常见,优化更好   阅读数据。

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

2 个答案:

答案 0 :(得分:7)

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

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

enter image description here

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

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

答案 1 :(得分:2)

在我看来,这不是一个好方法,因为您需要保持这些数据的同步,而Firebase不提供任何工具来保持重复同步。一种好方法是仅在user-posts中存储密钥。

我建议阅读本文,了解如何构建数据非常有趣:https://www.firebase.com/docs/web/guide/structuring-data.html