Firebase针对大型数据集的最佳数据结构实践

时间:2017-05-09 19:49:55

标签: firebase firebase-realtime-database

假设我拥有20K用户,每个用户拥有约100个产品(约为2M产品)。我有两个解决方案:

解决方案1 ​​

{
"products": {
   "product1": {
     "uid": "uid1",
     "cat": "category1",
     "title": "Produc1",
     "url": "url1"
   },
   "product2": {
     "uid": "uid2",
     "cat": "category2",
     "title": "Product2",
     "url": "url2"
   },
   "product3": {
     "uid": "uid2",
     "cat": "category1",
     "title": "Product3",
     "url": "url3"
   },
    ...
}

解决方案2:

{
"stuff": {
   "uid1": {
        "products": {
           "product1": {
             "cat": "category1",
             "title": "Produc1",
             "url": "url1"
           },
           "product2": {
             "cat": "category2",
             "title": "Product2",
             "url": "url2"
           },
           "product3": {
             "cat": "category1",
             "title": "Product3",
             "url": "url3"
           },
   },
   "uid2": {
    ...
}

我想获得特定用户的所有产品(我已经知道了uid)。

问题1:就速度而言,哪种解决方案更好?

问题2:在解决方案2中,如何使用child_added,child_changed等事件?

(我的第一个想法:使用uid选项过滤器的解决方案1似乎比解决方案2更慢,只是获取特定的子节点(对于2M记录),我是对的吗?但是,在解决方案2的情况下:可以我检索第二级/ stuff / $ uid / products中的列表,然后使用push,child_added事件等?)

谢谢!

1 个答案:

答案 0 :(得分:2)

当我们谈论速度时,Firebase中最重要的规则是让数据尽可能扁平化。根据这条规则,我建议你改造你的数据库:

firebase-url
    |
    --- users
    |     |
    |     ---- userId_1
    |     |       |
    |     |       ---- userName: "John"
    |     |       |
    |     |       ---- userAge: 30
    |     |       |
    |     |       ---- products
    |     |              |
    |     |              ---- productId_1 : true
    |     |              |
    |     |              ---- productId_2 : true
    |     |
    |     ---- userId_2
    |             |
    |             ---- userName: "Anna"
    |             |
    |             ---- userAge: 25
    |             |
    |             ---- products
    |                    |
    |                    ---- productId_3 : true
    |                    |
    |                    ---- productId_4 : true
    |
    ---- products
       |
       ---- productId_1
           |
           ---- productName: "product_1"
           |
           ---- users
              |
              ---- userId_1: true
              |
              ---- userId_2: true

通过这种方式,您可以非常简单地查询数据库,以显示有权访问单个产品的所有用户:firebase-url/products/productId/users/以及特定用户的所有产品:firebase-url/users/userId/products/

这是如何在代码中完成的:

DatabaseReference usersRef = FirebaseDatabase.getInstance().getReference().child("users").child(userId).child("products");
ValueEventListener eventListener = new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        for(DataSnapshot ds : dataSnapshot.getChildren()) {
            String productId = (String) ds.getKey();

            DatabaseReference productsRef = FirebaseDatabase.getInstance().getReference().child("products").child(productId);
            ValueEventListener valueEventListener = new ValueEventListener() {
                @Override
                public void onDataChange(DataSnapshot dataSnapshot) {
                     String productName = (String) dataSnapshot.child("productName").getValue();
                }

                @Override
                public void onCancelled(DatabaseError databaseError) {}
            };
            productsRef.addListenerForSingleValueEvent(valueEventListener);
        }
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {}
};
usersRef.addListenerForSingleValueEvent(eventListener);

要详细了解如何正确构建Firebase数据库,请阅读此post

希望它有所帮助。