如何在NoSQL环境中创建以下数据结构

时间:2018-09-21 14:03:12

标签: database firebase data-structures nosql google-cloud-firestore

简介
我有一个类似于社交媒体数据库的FireStore数据库,具有3个集合Users,Events和EventUpdates。我的目标是使用我和我的朋友创建的eventUpdates创建供稿。因此,我必须通过友谊连接来扩展我的数据库。但是我遇到了3个问题,希望这里的人可以将我推向正确的方向来解决这些问题。

问题/问题1:
我将用户名和用户图像添加到EventUpdate模型中,以便于查询。我听说非规范化是NoSQL数据库中要采用的方法。但是,如果用户更新了他的用户图像,则必须更新该用户创建的所有eventUpdates。听起来就像您不想做的事情。但是有更好的方法吗?

问题/问题2:
我如何创建为执行以下查询而优化的数据结构:按日期从我和我的朋友那里获取eventUpdates。

问题/问题3:
如何存储喜欢?我可以在eventUpdate中保留一个计数器。但这在我对eventUpdates非规范化时成为问题(请参见“编辑”下的当前解决方案)。

数据结构示例

{
  "users": {
    "1": { "name": "Jack", "imageUrl": "http://lorempixel.nl" }
  },
  "events": {
    "A": { 
      "name": "BeerFestival", 
      "date": "2018/09/05",
      "creatorId": "1"
    }
  },
  "eventUpdates": {
    "1": {
      "timestamp": "13243543",
      "creatorId: "1",
      "creatorName": "Jack",
      "creatorImageUrl": "http://lorempixel.nl",
      "eventId": "A",
      "message": "Lorem ipsum"
    }
  }
}

编辑

好的,经过一番尝试和错误后,我最终得到以下结构。这种结构似乎可以工作,但是此解决方案的问题是我需要进行大量写调用来更新单个eventUpdate,因为每个提要中都有所有副本(1000个关注者意味着1000个副本)。看来我需要做很多事情。

例如,我想向每个事件更新添加一个赞按钮。这将触发所有EventUpdate副本的更新。对我来说,firebase似乎不适合我的项目,我正在考虑将其替换为SQL DB,或者任何人都可以通过更好的解决方案改变主意吗?

{
  "users": {
    "user1": { "name": "Jack", 
      "imageUrl": "http://lorempixel.nl",
      "followers": ["user1"]
    }
  },
  "feeds": {
    "user1": {
      "eventUpdates": {
        "1": {
          "timestamp": "13243543",
          "creatorId: "1",
          "eventId": "A",
          "message": "Lorem ipsum"
        }
      },
      "following": {
        "user1": { 
          "name": "Jack", 
          "imageUrl": "http://lorempixel.nl",
          "followers": ["user1"]
        }
      }
  },
  "events": {
    "A": { 
      "name": "BeerFestival", 
      "date": "2018/09/05",
      "creatorId": "1"
    }
  }
}

3 个答案:

答案 0 :(得分:4)

  

我在EventUpdate模型中添加了用户名和用户图像,以便查询。我听说非规范化是进入NoSQL数据库的方法。

是的,denormalization是Firebase的一种常见做法。如果您不熟悉NoQSL数据库,建议您观看此视频Denormalization is normal with the Firebase Database,以更好地理解。它用于Firebase实时数据库,但相同的规则适用于Cloud Firestore。

  

但是,如果用户更新了他的用户图像,我必须更新该用户创建的所有eventUpdates。听起来就像您不想做的事情。但是有更好的方法吗?

是的,这也是正确的。您需要更新该图像所在的所有位置。因为您选择了google-cloud-firestore作为标签,所以我建议您从此 post 中查看答案,因为在进行许多写入操作的情况下,Firestore可能会花费一些成本。另请参见Firestore pricing plans

关于Firestore,只能保存对图片的引用,而不是保存整个对象。在这种情况下,您无需更新任何内容。这始终是这两种技术之间的一种交易,不幸的是两者之间没有办法。您要么持有对象,要么仅持有对象的引用。为此,请从此 post 中查看我的答案。

  

如何创建针对执行以下查询而优化的数据结构:按日期从我和我的朋友那里获取eventUpdates。

如我所见,您的架构更多是Firebase实时数据库架构,而不是Cloud Firestore。要回答您的问题,可以的。因此,在谈论Firestore时,您可以创建一个名为eventUpdates的集合,该集合可以容纳eventUpdate个对象,并根据时间戳进行查询,需要这样的查询:

FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
CollectionReference eventUpdatesRef = rootRef.collection("eventUpdates");
Query query = eventUpdatesRef.orderBy("timestamp", Query.Direction.ASCENDING);

但是请注意,timestamp字段的类型应为Date,而不是long。另请参阅此 post 中的答案,以了解如何在Cloud Firestore数据库中添加日期属性。

  

如何存储点赞?我可以在eventUpdate中保留一个计数器。但这在我对eventUpdates非规范化时成为问题(请参见“编辑”下的当前解决方案)

您可以简单地添加喜欢,但我建议您从此 post 中查看答案的最后一部分。因此,您可以考虑在Firebase实时数据库中而非Cloud Firestore中添加该计数。两个数据库都可以很好地协同工作。

  

此结构似乎可行,但是此解决方案的我的问题是,由于每个提要中的所有副本(1000个关注者意味着1000个副本),我需要进行大量写调用来更新单个eventUpdate。看来我需要做很多。

您也可以从此 post 看我的回答。

  

对我来说,firebase似乎不适合我的项目,我正在考虑将其替换为SQL DB,或者任何人都可以通过更好的解决方案改变主意吗?

我不这样认为。有很多应用程序具有与您的应用程序完全相同的机制,并且运行良好。

答案 1 :(得分:0)

如果您希望Feed项与真实用户数据(例如,当用户更改时,新的个人资料图像)保持同步,则只需将用户ID存储在eventUpdate文档中。这样,您就不必手动使其保持同步,并且每次必须在Feed中显示项目时,您都可以简单地获取用户数据,并轻松查询eventUpdate上的许多userIdcreated_at个字段(假设您有这些字段)。

要在您的供稿中实现喜欢,解决方案取决于诸如流量之类的一堆东西。 最简单的方法是使用事务更新likes字段,但是Firestore在单个文档上的最大更新频率为1秒。另外,如果有5个以上的事务试图更新同一文档,则事务很容易失败。

要实施更可靠的likes系统,请查看Firebase官方文档中的this page

答案 2 :(得分:0)

Firestore对NoSQL世界有不同的方法。一旦知道了将要使用的数据(就像您已经做过的一样),就会有一些关于数据将具有什么体系结构的非常重要的观点。而且,这很大程度上取决于数据的增长方式,所需的查询类型以及使用频率。在某些情况下,您可以创建一个根集合来聚合数据,并且查询可能会更容易。

Firebase频道有一段很棒的视频可能会有所帮助。一探究竟! 如何构造数据认识Cloud Firestore#5 https://www.youtube.com/watch?v=haMOUb3KVSo

[UPDATED] 12月26日

其他可能有助于建模和查询数据的视频是这些视频

如何将Firebase用户连接到他们的数据-3种方法 https://www.youtube.com/watch?v=jm66TSlVtcc

如何不获取30K Firebase Bill https://www.youtube.com/watch?v=Lb-Pnytoi-8

Firestore NoSQL中的模型关系数据 https://www.youtube.com/watch?v=jm66TSlVtcc