Firebase / AngularFire中的数据建模最佳实践

时间:2021-04-08 16:54:55

I'm developing an application in Firebase for the first time and was curious how I should model the data between two objects, a user and a post. I come from more of a relational db background and was curious not only how this would be done in nonrelational DBs but specifically how to set up a relationship between two objects in Firebase.

我是第一次在Firebase中开发应用程序,并且很好奇我应该如何在两个对象(用户和帖子)之间建模数据。我来自更多的关系数据库背景,不仅好奇这是如何在非关系数据库中完成的,而且特别是如何在Firebase中设置两个对象之间的关系。

For example, my application has many Users, and each user creates many Posts.

例如,我的应用程序有很多用户,每个用户创建许多帖子。

User {
    firstName: String,
    lastname: String,
    userName: String
}

Post {
    title: String,
    content: String,
    date: Date,
    writtenBy: [User object?]
}

How should I structure these two objects in Firebase so that a Post belongs to a User, but all Posts can be queried for regardless of User, and both User and Post objects can be edited without disrupting the other object's data and/or relationship?

我应该如何在Firebase中构建这两个对象,以便帖子属于用户,但是无论用户如何都可以查询所有帖子,并且可以在不中断其他对象的数据和/或关系的情况下编辑用户和帖子对象?

And how should I create new "relational" objects via firebase:

我应该如何通过firebase创建新的“关系”对象:

sync.$set({userA: {
   firstname: "Billy",
   lastName: "Bob",
   userName: "BillyBob",
   Posts: {
       // .....
   }
}
});

Thanks!

2 个解决方案

#1


9  

Firebase is built with performance in mind. This is the reason you have to design data structures differently, normalization is your enemy in most cases. Every object in Firebase can be accessed by URL, and you should always keep this in mind. There are still many ways of designing the data structures, it depends on what queries do you want to execute. If one of the queries is to be able to display all messages (I believe a number of latest messages would be the most common use case), but at the same time you want to be able to show messages per user than one of the possible data structures could look like this:

Firebase的构建充分考虑了性能。这就是你必须以不同方式设计数据结构的原因,在大多数情况下,规范化是你的敌人。 Firebase中的每个对象都可以通过URL访问,您应该始终牢记这一点。设计数据结构的方法仍然很多,这取决于您要执行哪些查询。如果其中一个查询能够显示所有消息(我相信一些最新消息将是最常见的用例),但同时您希望能够显示每个用户的消息而不是其中一个消息数据结构可能如下所示:

User {
    userId(assigned by Firebase automatically) {
        firstName: String,
        lastname: String,
        userName: String
    }
}

Post {
    User {
        userId(matching userId in the User object) {
            postId(assigned by Firebase for every new post automatically) {
                title: String,
                content: String,
                date: Date,
                writtenBy: String, userName or userId (this is not really needed, but may keep it for easier data access)
            }
        }
    }
}

Then you can change any user data without triggering data change events in Posts, like in your example, (which would be extremely heavy if you have large number of messages). You can get all messages independently of user:

然后,您可以更改任何用户数据,而不会触发帖子中的数据更改事件,如您的示例所示(如果您有大量邮件,这将非常繁重)。您可以独立于用户获取所有消息:

var postListRef = new Firebase(URL);
var lastPostQuery = postListRef.child("Post").limit(500);

You can also use startAt() and endAt() quesries https://www.firebase.com/docs/web/api/query/limit.html As a drawback - you have to unpack every message in the for loop if you need to show only messages, but I would expect you would show user info as well, so it should be ok.

您还可以使用startAt()和endAt()问题https://www.firebase.com/docs/web/api/query/limit.html作为一个缺点 - 如果需要,您必须解压缩for循环中的每条消息仅显示消息,但我希望您也会显示用户信息,所以它应该没问题。

If you want to listen for just one user messages, it's very simple and fast:

如果您只想收听一条用户消息,那么它非常简单快捷:

var postListRef = new Firebase(URL);
var lastPostQuery = postListRef.child("Post/User").child(userId);

And Angular/AngularFire has great support for this kind of data structures.

Angular / AngularFire对这种数据结构有很大的支持。

#2


0  

I am also new to Firebase, I would recommend the following structure.

我也是Firebase的新手,我会推荐以下结构。

Users: {
  userID: {
    firstName: String,
    lastname: String,
    userName: String,
    posts: {
      postID1:true,
      postID2:true
   }

Posts: {
  postID1:{
    title: String,
    content: String,
    date: Date,
    writtenBy: userID
  }
}

It allows you to get the latest posts without having to through any users. Plus you can get all the post made by any user.

它允许您获得最新的帖子,而无需通过任何用户。另外,您可以获得任何用户发布的所有帖子。

#1


9  

Firebase is built with performance in mind. This is the reason you have to design data structures differently, normalization is your enemy in most cases. Every object in Firebase can be accessed by URL, and you should always keep this in mind. There are still many ways of designing the data structures, it depends on what queries do you want to execute. If one of the queries is to be able to display all messages (I believe a number of latest messages would be the most common use case), but at the same time you want to be able to show messages per user than one of the possible data structures could look like this:

Firebase的构建充分考虑了性能。这就是你必须以不同方式设计数据结构的原因,在大多数情况下,规范化是你的敌人。 Firebase中的每个对象都可以通过URL访问,您应该始终牢记这一点。设计数据结构的方法仍然很多,这取决于您要执行哪些查询。如果其中一个查询能够显示所有消息(我相信一些最新消息将是最常见的用例),但同时您希望能够显示每个用户的消息而不是其中一个消息数据结构可能如下所示:

User {
    userId(assigned by Firebase automatically) {
        firstName: String,
        lastname: String,
        userName: String
    }
}

Post {
    User {
        userId(matching userId in the User object) {
            postId(assigned by Firebase for every new post automatically) {
                title: String,
                content: String,
                date: Date,
                writtenBy: String, userName or userId (this is not really needed, but may keep it for easier data access)
            }
        }
    }
}

Then you can change any user data without triggering data change events in Posts, like in your example, (which would be extremely heavy if you have large number of messages). You can get all messages independently of user:

然后,您可以更改任何用户数据,而不会触发帖子中的数据更改事件,如您的示例所示(如果您有大量邮件,这将非常繁重)。您可以独立于用户获取所有消息:

var postListRef = new Firebase(URL);
var lastPostQuery = postListRef.child("Post").limit(500);

You can also use startAt() and endAt() quesries https://www.firebase.com/docs/web/api/query/limit.html As a drawback - you have to unpack every message in the for loop if you need to show only messages, but I would expect you would show user info as well, so it should be ok.

您还可以使用startAt()和endAt()问题https://www.firebase.com/docs/web/api/query/limit.html作为一个缺点 - 如果需要,您必须解压缩for循环中的每条消息仅显示消息,但我希望您也会显示用户信息,所以它应该没问题。

If you want to listen for just one user messages, it's very simple and fast:

如果您只想收听一条用户消息,那么它非常简单快捷:

var postListRef = new Firebase(URL);
var lastPostQuery = postListRef.child("Post/User").child(userId);

And Angular/AngularFire has great support for this kind of data structures.

Angular / AngularFire对这种数据结构有很大的支持。

#2


0  

I am also new to Firebase, I would recommend the following structure.

我也是Firebase的新手,我会推荐以下结构。

Users: {
  userID: {
    firstName: String,
    lastname: String,
    userName: String,
    posts: {
      postID1:true,
      postID2:true
   }

Posts: {
  postID1:{
    title: String,
    content: String,
    date: Date,
    writtenBy: userID
  }
}

It allows you to get the latest posts without having to through any users. Plus you can get all the post made by any user.

它允许您获得最新的帖子,而无需通过任何用户。另外,您可以获得任何用户发布的所有帖子。