适用于大型数据集的 Firebase 最佳数据结构实践



假设我有 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等事件?

(

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

谢谢!

当我们谈论速度时,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 数据库的更多信息,请阅读这篇文章。

希望对您有所帮助。

最新更新