Firebase数据库 - “Fan Out”技术 [英] Firebase Database - the "Fan Out" technique

查看:159
本文介绍了Firebase数据库 - “Fan Out”技术的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在调查Android
的Firebase数据库



我对NoSQL技术并不熟悉并试图理解为什么我们必须坚持每个 post 实体两次 - posts user_posts 相应地。文档说,这种方法被称为扇出,我完全同意通过简单的结构像 databaseReference.child(user-posts)来访问用户的帖子可能是有用的。child(< ; user_uid>中)。但为什么我们需要 posts 节点呢?

  // [START write_fan_out] $ b $如果我们需要更新一些帖子,我们必须做两次吗? b private void writeNewPost(String userId,String username,String title,String body){
//在/ user-posts / $ userid / $ postid和
// / posts / $创建新帖子postid同时
String key = mDatabase.child(posts)。push()。getKey();
Post post = new Post(userId,username,title,body);
地图< 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是否提供了一些工具来保持所有副本的同步?
$ b b
$ b

更新: / strong>以下是



这样,您正在跟踪用户写在 users-posts 节点下的哪些帖子;还有在 posts 节点下写入每篇文章的用户。现在,您可能需要获取所有用户帖子的列表。您需要做的是在用户拥有的所有帖子上,将 users-posts / USER_KEY / 节点同步到获取键编写,然后使用刚刚获得的帖子键获取更多发布信息

为什么推荐这个数据库设计?因为您对每次同步获取的信息少得多(使用Firebase,我们不会发出请求本身,所以我把这个读取称为同步)。在您的示例中,如果您将侦听器附加到 user-posts / USER_KEY / 以获取所有文章的列表,则还会要求 ALL 他们写的 EACH AND EVERY 帖子的信息。使用数据扇出方法,您可以请求您需要的发布信息,因为您已经有了帖子的关键字。


I was investigating the Firebase Database sample for Android and realized that it stores its data in the following way:

I am not quite familiar with NoSQL techniques and trying to understand why we have to persist each post entity twice - at posts and user_posts correspondingly. The documentation says that this approach is called "Fan Out" and I fully agree that it might be useful to access user's posts via simple construction like databaseReference.child("user-posts").child("<user_uid>"). But why do we need the posts node then? What if we need to update some post - do we have to do it twice?

// [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]

So I wonder... when this approach might be useful and when not? Does Firebase SDK provide any tools to keep all duplicates in sync when updating or removing data?


UPDATE: Here is the explanation received from Firebase team:

the reason the posts are duplicated is because we want to be able to quickly get all the posts belonging to a user (as you suggested) and filtering from the list of all posts ever to get the posts by one user can get pretty expensive as the number of posts expands.

This does mean that we have to update the post in two locations whenever we update it. It makes the code a little uglier but since queries are more common than writes it's better to optimize for reading the data.

I suspect that this approach might look not quite elegant but it is probably the fastest option for large data sets as long as you perform SELECT more often than UPDATE. However, for some cases I'd rather stick to other solutions recommended here.

解决方案

Data Fan Out is a great technique to manage massive amounts of data. If you do not use this pattern, you could have serious scaling problems in the future.

What I see from your database structure, is that you are storing the whole post information twice, and that is not a good practice. You want to store just a reference to the post under another node instead. So, you will have a node named users-postswhich will consist of user keys, and each of those keys will have a set of posts keys with value of true. To make it more clear:

This way, you are tracking which posts the user has written under the users-posts node; and also the user that has written each post under the posts node. Now, you may need to get a list of all users' posts. What you would have to do is to synchronize on the users-posts/USER_KEY/ node to get the keys for all the posts that the user has written, and then get more post information using the post key you just got.

Why is this database design recommended? Because you are getting much less information for each synchronization (with Firebase we are not issuing requests per-se, so I call the reading a synchronization). In your example, if you attach a listener to the user-posts/USER_KEY/ to get a list of all posts, you will also ask for ALL the information of EACH AND EVERY post they have written. With the data fan out approach you can just ask for the post information you need because you already have the key of the posts.

这篇关于Firebase数据库 - “Fan Out”技术的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆