Firebase Swift的可伸缩性:查询与重复数据

时间:2016-05-25 17:08:25

标签: ios swift firebase scalability firebase-realtime-database

我有属于群组的帖子。我在可扩展性方面考虑了两种不同的方法:

方法1:发布带有通过查询访问的组的值

结构:

{
 "posts": {
   "1": {
     "message": "hello world",
     "timeAdded": 1718281919,
     "posterId": 123,
     "group": 15
   },
  "2": {
    "message": "this is second"
    "timeAdded": 12717212182,
    "posterId": 124,
    "group": 3
   },
   ...
  }
}

获取一个群组,即群组15,通过以下查询发布:

ref.child("posts/group").queryEqualToValue("15").observeEventType(.Value, withBlock: { snapshot in ... })

方法2:组中的重复数据

结构:

{
 "posts": {
   "1": {
     "message": "hello world",
     "timeAdded": 1718281919,
     "posterId": 123,
     "group": 15
   },
  "2": {
    "message": "this is second"
    "timeAdded": 12717212182,
    "posterId": 124,
    "group": 3
   },
   ...
  },
  "groups": {
    "15": {
      "posts": {
        "1": {
          "message": "hello world",
          "timeAdded": 1718281919,
          "posterId": 123,
        },
       ...
      }
    },
    ...
  },
  ...
}

获得一个小组,即小组15,简单地发布:

ref.child("groups/15").observeEventType(.Value, withBlock: { snapshot in ... })

哪种更好的可扩展性设计?

编辑:

作为一个附带问题,是否有Firebase查询可以查询多个值,而不仅仅是一个,即不仅返回第15组,还包括21,28等的帖子。

3 个答案:

答案 0 :(得分:2)

你走在正确的轨道上,但最终会有所不同。我非常确定组织数据的正确方法是将组和帖子都作为不同的集合。但是,为了说某个帖子属于某个给定的群组,只需在该群组的帖子中添加帖子标识符'帖子'属性。

{
 "posts": {
   "1": {
     "message": "hello world",
     "timeAdded": 1718281919,
     "posterId": 123,
     "group": 15
   },
   "2": {
    "message": "this is second"
    "timeAdded": 12717212182,
    "posterId": 124,
    "group": 3
   },
   ...
  },


  "groups": {
    "15": {
      "posts": {
        "1": true,
       }
       ...
      }
    } "3": {
      "posts" : {
         "2":true
       },
    ...
  },
  ...
}

这样,您就可以获取帖子标识符,然后使用此标识来查询Firebase以检索有关该特定帖子的信息。

这个例子有点令人困惑,因为组和帖子的标识符都是低整数值:)

有关详细信息,请参阅Firebase中的文档:https://firebase.google.com/docs/database/ios/structure-data#flatten_data_structures

希望这有帮助!

答案 1 :(得分:1)

由于您经常查询群组密钥,因此您应该将其设为顶级密钥:

{
  "posts": {
    "15": {
      "1": {
        "message": "hello world",
        "timeAdded": 1718281919,
        "posterId": 123
      },
      "6": {
        "message": "another post",
        "timeAdded": 1718281919,
        "posterId": 122
      },
    },
    "3": {
      "2": {
        "message": "this is second"
        "timeAdded": 12717212182,
        "posterId": 124
      }
    }
  }
}

这样的结构允许您通过/posts/15

获取第15组中的所有帖子

firebase docs中的示例与您的数据具有相似的结构,术语略有不同,“聊天”而不是“群组”和“消息”而不是“帖子”。

答案 2 :(得分:0)

似乎不需要方法2中的重复数据,因此我建议使用两种解决方案:

使用方法1结构

postsRef.queryOrderedByChild("group").queryEqualToValue("15").observeEventType(.ChildAdded
postsRef.queryOrderedByChild("group").queryEqualToValue("15").observeEventType(.ChildChanged
postsRef.queryOrderedByChild("group").queryEqualToValue("15").observeEventType(.ChildRemoved    

postsRef.queryOrderedByChild("group").queryEqualToValue("21").observeEventType(.ChildAdded
postsRef.queryOrderedByChild("group").queryEqualToValue("21").observeEventType(.ChildChanged
postsRef.queryOrderedByChild("group").queryEqualToValue("21").observeEventType(.ChildRemoved

postsRef.queryOrderedByChild("group").queryEqualToValue("28").observeEventType(.ChildAdded
postsRef.queryOrderedByChild("group").queryEqualToValue("28").observeEventType(.ChildChanged
postsRef.queryOrderedByChild("group").queryEqualToValue("28").observeEventType(.ChildRemoved

这会在postsRef上设置观察员,观看第15组,第21组和第28组的帖子,查看任何新帖子,对现有帖子的更改或删除的帖子。

请注意,我建议使用.ChildAdded,.ChildChanged和.ChildRemoved而不是.Value作为.Value将返回节点中的所有内容,包含任何更改,这可能是大量数据。

方法2有重复数据但在这种情况下似乎不需要它,所以只需保留组节点

"groups": {
    "15": {
      "posts": {
        "1": {
          "message": "hello world",
          "timeAdded": 1718281919,
          "posterId": 123,

并将观察者添加到每个

中的posts节点
postsRef = groups/15/posts
   ...add observers like above
postsRef = groups/21/posts
   ...add observers like above
postsRef = groups/28/posts
   ...add observers like above

我的建议#2的缺点是查询,因为结构太深而无法做太多 - 但问题中没有指定查询的需要。

第一个建议提供简单,非规范化数据和查询任何内容的能力。它也快速而有弹性。

作为旁注,这可能不言而喻,但请不要使用整数 - 顺序或其他 - 作为父节点名称。那些应该通过childByAutoId获得。