【问题标题】:Data Modeling Best Practices in Firebase/AngularFireFirebase/AngularFire 中的数据建模最佳实践
【发布时间】:2014-10-03 03:00:27
【问题描述】:

我是第一次在 Firebase 中开发应用程序,我很好奇我应该如何对两个对象之间的数据建模,userpost。我来自更多的关系数据库背景,不仅好奇如何在非关系数据库中完成此操作,还特别好奇如何在 Firebase 中的两个对象之间建立关系。

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

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

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

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

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

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

谢谢!

【问题讨论】:

    标签: angularjs json firebase angularfire nosql


    【解决方案1】:

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

    Users: {
      userID: {
        firstName: String,
        lastname: String,
        userName: String,
        posts: {
          postID1:true,
          postID2:true
       }
    
    Posts: {
      postID1:{
        title: String,
        content: String,
        date: Date,
        writtenBy: userID
      }
    }
    

    它使您无需通过任何用户即可获取最新帖子。另外,您可以获取任何用户发布的所有帖子。

    【讨论】:

    • 这有一个问题,您如何构建 Firebase 规则以仅允许用户获取他们的帖子列表而不允许其他人获取?
    • 这不就是查询的来源吗?
    • 如果您使用查询,它不安全,因为任何人都可以使用 firebase 对象查询列表
    【解决方案2】:

    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)
                }
            }
        }
    }
    

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

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

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

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

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

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

    【讨论】:

    • 这里有一篇来自 Anant(来自 Firebase 团队)关于数据结构的好文章:firebase.com/blog/2013-04-12-denormalizing-is-normal.html
    • 非常感谢您的解释。确实很有帮助。当你说你必须以不同的方式设计数据结构时,mongodb数据结构和firebase之间是否有任何重叠,或者我不应该使用mongo作为蓝图?再次感谢!
    • 据我所知,Firebase 是建立在 Mongo 之上的。但与此同时,您应该考虑要收听多少数据块以进行更新,因为这会直接影响性能。
    猜你喜欢
    • 2016-09-17
    • 2016-09-21
    • 2019-10-22
    • 1970-01-01
    • 1970-01-01
    • 2018-07-18
    • 2019-04-17
    • 2011-04-02
    • 2011-10-29
    相关资源
    最近更新 更多