Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
381 views
in Technique[技术] by (71.8m points)

java - Firebase Database - the "Fan Out" technique

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

enter image description here

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
Waitting for answers

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...