我是firebase的新手,我想知道在其上构建数据的最佳方法是什么.
我有一个简单的例子:
我的项目有申请人和申请.1申请人可以有几个申请.如何在firebase上关联这两个对象?它是否像关系数据库一样工作?或者在数据设计方面需要完全不同的方法?
我正在使用Firebase作为后端存储机制(JSON)的简单JavaScript Twitter克隆.我熟悉关系数据库(SQL),但不熟悉非关系数据库.我目前正在尝试研究如何在Firebase中设计数据集的结构,因为没有外键关系或表连接.
该应用程序有三个表,users,tweets,和followers.用户可以发布推文,也可以关注其他用户并查看推文的摘要.尝试创建数据结构时会出现问题,因为我不知道如何加入必要的表.例如,我将如何实现用户关注功能?
这是我用来给自己起点的ERD:
正如我一直在试图环绕这整个事情的JSON我的头,这是最接近的,我可以将它与关系数据库,同时仍使用火力地堡的.push()功能添加到列表数据库(从火力地堡看到仪表板):
我看到有些人试图通过"取消规范化"数据来解决这个问题,理由是Firebase没有任何查询机制.然而,这些文章都主要是在2014年之前,也就是当火力地堡并添加查询.话虽如此,我不明白使用查询如何帮助我,我想我已经陷入了生成的密钥.
我应该如何最好地构建我的数据以使用Firebase JSON列表?我已经阅读了他们的一些文档,但无法找到任何使用我正在寻找的东西和生成的密钥.
我应该尝试以.set()某种方式使用该方法,并使用电子邮件地址作为用户的"主键"而不是生成的密钥?[如下所述,这是我计划避免的事情.谢谢@metame]
这更像是我应该关注的数据结构吗?然后按键查询?
users: {
Hj83Kd83: {
username: "test",
password: "2K44Djl3",
email: "a@b.c"
},
J3kk0dK4: {
username: "another",
password: "33kj4l5K",
email: "d@e.f"
}
}
tweets: {
Jkk3ld92: {
userkey: "Hj83Kd83",
message: "Test message here!"
},
K3Ljdi94: {
userkey: "J3kk0dK4",
message: "Another message here!"
}
}
followers: {
Lk3jdke9: {
userkey: "Hj83Kd83",
followerkey: "J3kk0dK4"
}
}
Run Code Online (Sandbox Code Playgroud)
如果我还要包含其他内容,请告诉我!
对于 Facebook 类型的社交网络应用程序,需要一个高性能的数据库结构,用于在 Firebase(Cloud Firestore) (NoSQL) 中存储数据。
要存储的数据:
- Userinfo (name, email etc)
- Friends
- Posts
- Comments on posts.
Run Code Online (Sandbox Code Playgroud)
我对以下两个关于查询性能的数据库结构感到困惑(如果数据库变得巨大)。
(参考:C_xxx 是收藏,D_xxx 是文档)
结构 1
C_AllData
- D_UserID-1
name: xxxx,
email: yyy,
friends: [UserID-3, UserID-4]
- C_Posts
- D_PostId-1
Text: hhh
Date: zzz
- C_Comments
- D_CommentId-1
UserID: 3
Text: kkk
- D_CommentId-2
UserID: 4
Text: kkk
- D_PostId-2
Text: hhh
Date: zzz
- C_Comments
- D_CommentId-3
UserID: 3
Text: kkk
- D_CommentId-4
UserID: 4
Text: kkk
- …Run Code Online (Sandbox Code Playgroud) 我正在制作聊天应用,我有一个具有以下结构的Firebase.Chat1,Chat2,Chat3 ...用于保存不同聊天组的数据.Message1,Message2,Message3是第1组内的消息.它可以来自任何作者.
聊天
我想从"作者1"中检索所有消息的列表.含义Message1,Message3应该从Chat1中检索,而Message3也应该从Chat2中检索.我想显示来自1位作者的所有消息.
ref = new Firebase(FIREBASE_URL); //Root URL
ref.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot child : dataSnapshot.getChildren()) {
for (DataSnapshot childd : child.getChildren()) {
//This might work but it retrieves all the data
}
}
}
@Override
public void onCancelled() {
}
});
Run Code Online (Sandbox Code Playgroud)
这给了我全部数据!如何将其限制为"Author1"?
假设我有一个典型的用户和组数据模型,其中用户可以在多个组中,一个组可以有许多用户.在我看来,firebase文档建议我通过在组内部复制用户ID并在用户内部组ID来建模我的数据,如下所示:
{
"usergroups": {
"bob": {
"groups": {
"one": true,
"two": true
}
},
"fred": {
"groups": {
"one": true
}
}
},
"groupusers": {
"one": {
"users": {
"bob": true,
"fred": true
}
},
"two": {
"users": {
"bob": true
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
为了维护该结构,每当我的应用更新关系的一侧(例如,将用户添加到组)时,它还需要更新关系的另一侧(例如,将组添加到用户).
我担心最终某人的计算机会在更新过程中崩溃,否则会出现其他问题,并且这种关系的双方将会失去同步.理想情况下,我想将更新放在一个事务中,以便双方都得到更新或双方都没有,但据我所知,我不能用firebase中的当前事务支持来做到这一点.
另一种方法是使用即将到来的firebase触发器来更新关系的另一面,但触发器尚未可用,并且它似乎是一个非常重量级的解决方案,只是为了让该服务器保持冗余数据而将消息发布到外部服务器至今.
所以我正在考虑另一种方法,其中许多用户组成员身份存储为单独的端点:
{
"memberships": {
"id1": {
"user": "bob",
"group": "one"
},
"id2": {
"user": "bob",
"group": "two"
},
"id3": {
"user": "fred",
"group": "one"
}
}
}
Run Code Online (Sandbox Code Playgroud)
我可以在"user"和"group"上添加索引,并发出firebase查询".orderByChild("user").equalTo(...)"和".orderByChild("group").equalTo(...)"分别确定特定用户的组和特定组的用户.
这种方法的缺点是什么?我们不再需要维护冗余数据,为什么这不是推荐的方法?它是否明显慢于推荐的复制数据方法?
当子属性具有名称时,Firebase orderByChild()运行良好,因此使用如下数据:
groups
<groupID>
groupStatus: "Active"
Run Code Online (Sandbox Code Playgroud)
很容易得到具有"活动"状态的组的groupID:
var ref = "http://myFirebase.firebaseio.com/groups";
ref.orderByChild("groupStatus").equalTo("Active").on("child_added", function(snapshot) {
console.log(snapshot.key());
});
Run Code Online (Sandbox Code Playgroud)
但是我有以下形式的群组和这些群组的成员的firebase数据:
groups
group123
member404: true
member503: true
...
group124
member503: true
member221: true
...
Run Code Online (Sandbox Code Playgroud)
我需要生成一个所有成员ID的列表,这些成员ID是特定成员的"朋友",被定义为至少与他们共同的一个组.对于成员503,您会认为这将是orderByChild()机会.但由于memberID是嵌套在组下的键,语法是什么?
就像是:
ref.orderByChild(???).equalTo("member503")
Run Code Online (Sandbox Code Playgroud)
当然,我可以让所有组的所有成员在本地获得一个数组,但是肯定有办法让firebase为我做这个吗?
我想创建可扩展的数据(跟踪用户的私人数据).
Firebase文档建议将子对象嵌套在父对象下,如下所示:
{
"users": {
"google:1234567890": {
"displayName" : "Username A",
"provider" : "google",
"provider_id" : "1234567890",
"todos": {
"rec_id1": "Walk the dog",
"rec_id2": "Buy milk",
"rec_id3": "Win a gold medal in the Olympics",
...
}
}, ...
}
}
Run Code Online (Sandbox Code Playgroud)
(其中rec_id是Firebase.push()生成的唯一键.)
但正如Denormalizing Your Data is Normal中提到的那样,我认为以这种方式构造它会更好:
{
"users" : {
"google:1234567890" : {
"displayName" : "Username A",
"provider" : "google",
"provider_id" : "1234567890"
}, ...
},
"todos" : {
"google:1234567890" : {
"rec_id1" : {
"todo" …Run Code Online (Sandbox Code Playgroud) firebase ×7
database ×2
json ×2
nosql ×2
android ×1
eclipse ×1
java ×1
javascript ×1
jsonschema ×1
mongodb ×1