简介
我有一个类似于社交媒体数据库的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"
}
}
}
答案 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
上的许多userId
和created_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