假设我拥有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事件等?)
谢谢!
答案 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。
希望它有所帮助。