假设我有 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 数据库的更多信息,请阅读这篇文章。
希望对您有所帮助。