我有属于群组的帖子。我在可扩展性方面考虑了两种不同的方法:
方法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等的帖子。
答案 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
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获得。