将某些数据库参考数据存储在节点键中还是作为值存储更好?

时间:2019-06-28 01:04:46

标签: ios firebase firebase-realtime-database

我有一个时间轴节点,如下所示。我首先存储用户的uid,该用户跟随一些发表过帖子的用户。然后,我在其旁边存储有posterUID和postID,并用':'分隔信息,以便以后可以轻松获得每一部分。然后,我存储帖子的时间戳。

"Post_Timeline" : {
    "uid" : {
      "posterUID:postID" : {//example postID value: "post:583190375"
        "timeStamp" : 583190375
      },

我想知道这样做是否会更有效(所谓“高效”是指更快地获取或获取正确的信息。或者可能是基于火力成本等):

"Post_Timeline" : {
    "uid" : {
      "randomID" : {
        "timeStamp" : 583190375,
        "posterUID" : "JNFSD78436VSFFDSF"
      },

我用来提取的代码:

ref.child("Timeline").child((Auth.auth().currentUser?.uid)!)
            .queryOrdered(byChild: "timeStamp")
            .queryLimited(toLast: 10)
            .observeSingleEvent(of: .value, with: { (snapshot) in

                var i = 0
                for case let rest as DataSnapshot in snapshot.children.reversed() {//.reversed()
                    let keyValue = rest.key
                    let uid = keyValue.split(separator: ":")[0]
                    let postIDDoubleVal = keyValue.split(separator: ":")[2]

                    self.fetchUsersPost(uid: "\(uid)", postID: "post:\(postIDDoubleVal)")

我使用此时间轴来获取当前用户关注的用户创建的10条最新帖子。

1 个答案:

答案 0 :(得分:0)

通常,Firebase结构取决于您将要使用的查询类型。 IMO,通常最好的做法是将节点密钥与它们包含的数据解除关联-尤其是如果节点密钥可能是动态数据(例如电子邮件或用户名,将来可能会更改)的话。

我将通过举例说明原因,以给出答案

"posterUID:postID"

可能不好。

不用说,您显然必须具有用于编码/解码节点密钥的代码,所以这只是附加代码。

问题#1:如果同一用户两次在帖子中发帖怎么办?

uid
   posterUID:postID
      timeStamp: 583190375
   posterUID:postID
      timeStamp: 123456789

啊-无法这样做,因为在同一节点内不能有重复的密钥

问题2:如果不读取所有节点并过滤代码,就无法对特定帖子进行任何类型的查询。那可能是大量数据或大量冗余

问题3:从所有关注的用户那里获取有关特定帖子的所有发布时间。 Firebase不支持部分 end 字符串查询。

问题4: Post_1234已删除,现在我需要从“ uid”节点中删除对该节点的引用。好吧,不读取所有子节点就不会发生这种情况。

可能还会遇到许多其他问题,但是如果不了解可能会运行哪些查询的全部范围,就无法解决这些问题。

这似乎是一种更灵活的解决方案

Post_Timeline
   uid
      randomID
        timeStamp: 583190375,
        posterUID: "JNFSD78436VSFFDSF"